]> git.ipfire.org Git - people/ms/dnsmasq.git/blame - src/rfc1035.c
protocol handling for DNSSEC
[people/ms/dnsmasq.git] / src / rfc1035.c
CommitLineData
c47e3ba4 1/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
9e4abcb5
SK
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
824af85b
SK
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
7
9e4abcb5
SK
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
824af85b 12
73a08a24
SK
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
9e4abcb5
SK
15*/
16
17#include "dnsmasq.h"
18
4f7b304f
SK
19int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
20 char *name, int isExtract, int extrabytes)
9e4abcb5 21{
3d8df260 22 unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL;
9e4abcb5
SK
23 unsigned int j, l, hops = 0;
24 int retvalue = 1;
25
f6b7dc47
SK
26 if (isExtract)
27 *cp = 0;
28
9009d746
SK
29 while (1)
30 {
31 unsigned int label_type;
32
33 if (!CHECK_LEN(header, p, plen, 1))
34 return 0;
35
36 if ((l = *p++) == 0)
37 /* end marker */
38 {
39 /* check that there are the correct no of bytes after the name */
40 if (!CHECK_LEN(header, p, plen, extrabytes))
41 return 0;
42
43 if (isExtract)
44 {
45 if (cp != (unsigned char *)name)
46 cp--;
47 *cp = 0; /* terminate: lose final period */
48 }
49 else if (*cp != 0)
50 retvalue = 2;
51
52 if (p1) /* we jumped via compression */
53 *pp = p1;
54 else
55 *pp = p;
56
57 return retvalue;
58 }
59
60 label_type = l & 0xc0;
61
9e4abcb5
SK
62 if (label_type == 0xc0) /* pointer */
63 {
9009d746 64 if (!CHECK_LEN(header, p, plen, 1))
9e4abcb5
SK
65 return 0;
66
67 /* get offset */
68 l = (l&0x3f) << 8;
69 l |= *p++;
9e4abcb5
SK
70
71 if (!p1) /* first jump, save location to go back to */
72 p1 = p;
73
74 hops++; /* break malicious infinite loops */
75 if (hops > 255)
76 return 0;
77
78 p = l + (unsigned char *)header;
79 }
80 else if (label_type == 0x80)
81 return 0; /* reserved */
82 else if (label_type == 0x40)
83 { /* ELT */
84 unsigned int count, digs;
85
86 if ((l & 0x3f) != 1)
87 return 0; /* we only understand bitstrings */
88
89 if (!isExtract)
90 return 0; /* Cannot compare bitsrings */
91
92 count = *p++;
93 if (count == 0)
94 count = 256;
95 digs = ((count-1)>>2)+1;
96
97 /* output is \[x<hex>/siz]. which is digs+9 chars */
3d8df260 98 if (cp - (unsigned char *)name + digs + 9 >= MAXDNAME)
9e4abcb5 99 return 0;
9009d746 100 if (!CHECK_LEN(header, p, plen, (count-1)>>3))
9e4abcb5
SK
101 return 0;
102
103 *cp++ = '\\';
104 *cp++ = '[';
105 *cp++ = 'x';
106 for (j=0; j<digs; j++)
107 {
108 unsigned int dig;
109 if (j%2 == 0)
110 dig = *p >> 4;
111 else
112 dig = *p++ & 0x0f;
113
114 *cp++ = dig < 10 ? dig + '0' : dig + 'A' - 10;
115 }
3d8df260 116 cp += sprintf((char *)cp, "/%d]", count);
9e4abcb5
SK
117 /* do this here to overwrite the zero char from sprintf */
118 *cp++ = '.';
119 }
120 else
121 { /* label_type = 0 -> label. */
3d8df260 122 if (cp - (unsigned char *)name + l + 1 >= MAXDNAME)
9e4abcb5 123 return 0;
9009d746 124 if (!CHECK_LEN(header, p, plen, l))
9e4abcb5 125 return 0;
9009d746 126
9e4abcb5
SK
127 for(j=0; j<l; j++, p++)
128 if (isExtract)
129 {
1f15b81d
SK
130 unsigned char c = *p;
131 if (isascii(c) && !iscntrl(c) && c != '.')
9e4abcb5
SK
132 *cp++ = *p;
133 else
134 return 0;
135 }
136 else
137 {
138 unsigned char c1 = *cp, c2 = *p;
139
140 if (c1 == 0)
141 retvalue = 2;
142 else
143 {
144 cp++;
145 if (c1 >= 'A' && c1 <= 'Z')
146 c1 += 'a' - 'A';
147 if (c2 >= 'A' && c2 <= 'Z')
148 c2 += 'a' - 'A';
149
150 if (c1 != c2)
151 retvalue = 2;
152 }
153 }
154
155 if (isExtract)
156 *cp++ = '.';
f6b7dc47
SK
157 else if (*cp != 0 && *cp++ != '.')
158 retvalue = 2;
9e4abcb5 159 }
309331f5 160 }
9e4abcb5
SK
161}
162
163/* Max size of input string (for IPv6) is 75 chars.) */
164#define MAXARPANAME 75
4f7b304f 165int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
9e4abcb5
SK
166{
167 int j;
168 char name[MAXARPANAME+1], *cp1;
169 unsigned char *addr = (unsigned char *)addrp;
170 char *lastchunk = NULL, *penchunk = NULL;
171
172 if (strlen(namein) > MAXARPANAME)
173 return 0;
174
175 memset(addrp, 0, sizeof(struct all_addr));
176
177 /* turn name into a series of asciiz strings */
178 /* j counts no of labels */
179 for(j = 1,cp1 = name; *namein; cp1++, namein++)
180 if (*namein == '.')
181 {
182 penchunk = lastchunk;
183 lastchunk = cp1 + 1;
184 *cp1 = 0;
185 j++;
186 }
187 else
188 *cp1 = *namein;
189
190 *cp1 = 0;
191
192 if (j<3)
193 return 0;
194
195 if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr"))
196 {
197 /* IP v4 */
198 /* address arives as a name of the form
199 www.xxx.yyy.zzz.in-addr.arpa
200 some of the low order address octets might be missing
201 and should be set to zero. */
202 for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
203 {
204 /* check for digits only (weeds out things like
205 50.0/24.67.28.64.in-addr.arpa which are used
206 as CNAME targets according to RFC 2317 */
207 char *cp;
208 for (cp = cp1; *cp; cp++)
572b41eb 209 if (!isdigit((unsigned char)*cp))
9e4abcb5
SK
210 return 0;
211
212 addr[3] = addr[2];
213 addr[2] = addr[1];
214 addr[1] = addr[0];
215 addr[0] = atoi(cp1);
216 }
217
218 return F_IPV4;
219 }
220#ifdef HAVE_IPV6
221 else if (hostname_isequal(penchunk, "ip6") &&
222 (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa")))
223 {
224 /* IP v6:
225 Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
226 or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]
227
228 Note that most of these the various reprentations are obsolete and
229 left-over from the many DNS-for-IPv6 wars. We support all the formats
230 that we can since there is no reason not to.
231 */
232
233 if (*name == '\\' && *(name+1) == '[' &&
234 (*(name+2) == 'x' || *(name+2) == 'X'))
235 {
572b41eb 236 for (j = 0, cp1 = name+3; *cp1 && isxdigit((unsigned char) *cp1) && j < 32; cp1++, j++)
9e4abcb5
SK
237 {
238 char xdig[2];
239 xdig[0] = *cp1;
240 xdig[1] = 0;
241 if (j%2)
242 addr[j/2] |= strtol(xdig, NULL, 16);
243 else
244 addr[j/2] = strtol(xdig, NULL, 16) << 4;
245 }
246
247 if (*cp1 == '/' && j == 32)
248 return F_IPV6;
249 }
250 else
251 {
252 for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
253 {
572b41eb 254 if (*(cp1+1) || !isxdigit((unsigned char)*cp1))
9e4abcb5
SK
255 return 0;
256
257 for (j = sizeof(struct all_addr)-1; j>0; j--)
258 addr[j] = (addr[j] >> 4) | (addr[j-1] << 4);
259 addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
260 }
261
262 return F_IPV6;
263 }
264 }
265#endif
266
267 return 0;
268}
269
32f82c62 270unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes)
9e4abcb5 271{
feba5c1d 272 while(1)
9e4abcb5 273 {
9009d746 274 unsigned int label_type;
feba5c1d 275
9009d746 276 if (!CHECK_LEN(header, ansp, plen, 1))
feba5c1d
SK
277 return NULL;
278
9009d746
SK
279 label_type = (*ansp) & 0xc0;
280
feba5c1d 281 if (label_type == 0xc0)
9e4abcb5 282 {
feba5c1d
SK
283 /* pointer for compression. */
284 ansp += 2;
285 break;
286 }
287 else if (label_type == 0x80)
288 return NULL; /* reserved */
289 else if (label_type == 0x40)
290 {
291 /* Extended label type */
292 unsigned int count;
9e4abcb5 293
9009d746
SK
294 if (!CHECK_LEN(header, ansp, plen, 2))
295 return NULL;
296
feba5c1d
SK
297 if (((*ansp++) & 0x3f) != 1)
298 return NULL; /* we only understand bitstrings */
9e4abcb5 299
feba5c1d
SK
300 count = *(ansp++); /* Bits in bitstring */
301
302 if (count == 0) /* count == 0 means 256 bits */
303 ansp += 32;
9e4abcb5 304 else
feba5c1d
SK
305 ansp += ((count-1)>>3)+1;
306 }
307 else
308 { /* label type == 0 Bottom six bits is length */
309 unsigned int len = (*ansp++) & 0x3f;
9009d746
SK
310
311 if (!ADD_RDLEN(header, ansp, plen, len))
312 return NULL;
313
feba5c1d
SK
314 if (len == 0)
315 break; /* zero length label marks the end. */
9e4abcb5 316 }
feba5c1d 317 }
9009d746
SK
318
319 if (!CHECK_LEN(header, ansp, plen, extrabytes))
320 return NULL;
feba5c1d
SK
321
322 return ansp;
323}
324
4f7b304f 325unsigned char *skip_questions(struct dns_header *header, size_t plen)
feba5c1d 326{
5aabfc78 327 int q;
feba5c1d
SK
328 unsigned char *ansp = (unsigned char *)(header+1);
329
5aabfc78 330 for (q = ntohs(header->qdcount); q != 0; q--)
feba5c1d 331 {
9009d746 332 if (!(ansp = skip_name(ansp, header, plen, 4)))
feba5c1d 333 return NULL;
9e4abcb5
SK
334 ansp += 4; /* class and type */
335 }
9e4abcb5
SK
336
337 return ansp;
338}
339
572b41eb 340static unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen)
feba5c1d 341{
fd9fa481 342 int i, rdlen;
36717eee 343
fd9fa481 344 for (i = 0; i < count; i++)
36717eee 345 {
9009d746 346 if (!(ansp = skip_name(ansp, header, plen, 10)))
fd9fa481 347 return NULL;
36717eee
SK
348 ansp += 8; /* type, class, TTL */
349 GETSHORT(rdlen, ansp);
9009d746 350 if (!ADD_RDLEN(header, ansp, plen, rdlen))
fd9fa481 351 return NULL;
36717eee
SK
352 }
353
fd9fa481
SK
354 return ansp;
355}
356
0a852541
SK
357/* CRC the question section. This is used to safely detect query
358 retransmision and to detect answers to questions we didn't ask, which
359 might be poisoning attacks. Note that we decode the name rather
360 than CRC the raw bytes, since replies might be compressed differently.
832af0ba
SK
361 We ignore case in the names for the same reason. Return all-ones
362 if there is not question section. */
572b41eb 363unsigned int questions_crc(struct dns_header *header, size_t plen, char *name)
fd9fa481 364{
91dccd09
SK
365 int q;
366 unsigned int crc = 0xffffffff;
0a852541
SK
367 unsigned char *p1, *p = (unsigned char *)(header+1);
368
5aabfc78 369 for (q = ntohs(header->qdcount); q != 0; q--)
0a852541 370 {
9009d746 371 if (!extract_name(header, plen, &p, name, 1, 4))
0a852541
SK
372 return crc; /* bad packet */
373
3d8df260 374 for (p1 = (unsigned char *)name; *p1; p1++)
0a852541
SK
375 {
376 int i = 8;
377 char c = *p1;
378
379 if (c >= 'A' && c <= 'Z')
380 c += 'a' - 'A';
381
382 crc ^= c << 24;
383 while (i--)
384 crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
385 }
386
387 /* CRC the class and type as well */
388 for (p1 = p; p1 < p+4; p1++)
389 {
390 int i = 8;
391 crc ^= *p1 << 24;
392 while (i--)
393 crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
394 }
395
396 p += 4;
9009d746 397 if (!CHECK_LEN(header, p, plen, 0))
0a852541
SK
398 return crc; /* bad packet */
399 }
fd9fa481 400
fd9fa481
SK
401 return crc;
402}
403
404
572b41eb 405size_t resize_packet(struct dns_header *header, size_t plen, unsigned char *pheader, size_t hlen)
fd9fa481
SK
406{
407 unsigned char *ansp = skip_questions(header, plen);
408
9009d746 409 /* if packet is malformed, just return as-is. */
fd9fa481 410 if (!ansp)
9009d746 411 return plen;
fd9fa481
SK
412
413 if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
414 header, plen)))
9009d746 415 return plen;
fd9fa481 416
36717eee
SK
417 /* restore pseudoheader */
418 if (pheader && ntohs(header->arcount) == 0)
419 {
420 /* must use memmove, may overlap */
421 memmove(ansp, pheader, hlen);
422 header->arcount = htons(1);
423 ansp += hlen;
424 }
425
426 return ansp - (unsigned char *)header;
427}
428
572b41eb 429unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, size_t *len, unsigned char **p, int *is_sign)
36717eee
SK
430{
431 /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
832af0ba
SK
432 also return length of pseudoheader in *len and pointer to the UDP size in *p
433 Finally, check to see if a packet is signed. If it is we cannot change a single bit before
434 forwarding. We look for SIG and TSIG in the addition section, and TKEY queries (for GSS-TSIG) */
feba5c1d
SK
435
436 int i, arcount = ntohs(header->arcount);
832af0ba
SK
437 unsigned char *ansp = (unsigned char *)(header+1);
438 unsigned short rdlen, type, class;
439 unsigned char *ret = NULL;
1b7ecd11
SK
440
441 if (is_sign)
832af0ba 442 {
1b7ecd11
SK
443 *is_sign = 0;
444
572b41eb 445 if (OPCODE(header) == QUERY)
832af0ba 446 {
5aabfc78 447 for (i = ntohs(header->qdcount); i != 0; i--)
1b7ecd11 448 {
9009d746 449 if (!(ansp = skip_name(ansp, header, plen, 4)))
1b7ecd11
SK
450 return NULL;
451
452 GETSHORT(type, ansp);
453 GETSHORT(class, ansp);
454
455 if (class == C_IN && type == T_TKEY)
456 *is_sign = 1;
457 }
832af0ba
SK
458 }
459 }
460 else
461 {
462 if (!(ansp = skip_questions(header, plen)))
463 return NULL;
464 }
465
466 if (arcount == 0)
feba5c1d
SK
467 return NULL;
468
fd9fa481
SK
469 if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount), header, plen)))
470 return NULL;
832af0ba 471
feba5c1d
SK
472 for (i = 0; i < arcount; i++)
473 {
36717eee 474 unsigned char *save, *start = ansp;
9009d746 475 if (!(ansp = skip_name(ansp, header, plen, 10)))
feba5c1d
SK
476 return NULL;
477
478 GETSHORT(type, ansp);
479 save = ansp;
832af0ba
SK
480 GETSHORT(class, ansp);
481 ansp += 4; /* TTL */
feba5c1d 482 GETSHORT(rdlen, ansp);
9009d746 483 if (!ADD_RDLEN(header, ansp, plen, rdlen))
feba5c1d 484 return NULL;
832af0ba 485 if (type == T_OPT)
36717eee
SK
486 {
487 if (len)
488 *len = ansp - start;
489 if (p)
490 *p = save;
832af0ba 491 ret = start;
36717eee 492 }
832af0ba
SK
493 else if (is_sign &&
494 i == arcount - 1 &&
495 class == C_ANY &&
5f8e58f4 496 type == T_TSIG)
832af0ba 497 *is_sign = 1;
feba5c1d
SK
498 }
499
832af0ba 500 return ret;
feba5c1d 501}
28866e95
SK
502
503struct macparm {
504 unsigned char *limit;
572b41eb 505 struct dns_header *header;
28866e95
SK
506 size_t plen;
507 union mysockaddr *l3;
508};
28866e95 509
ed4c0767 510static size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
3a237152 511 int optno, unsigned char *opt, size_t optlen, int set_do)
ed4c0767
SK
512{
513 unsigned char *lenp, *datap, *p;
a25720a3 514 int rdlen, is_sign;
28866e95 515
a25720a3 516 if (!(p = find_pseudoheader(header, plen, NULL, NULL, &is_sign)))
28866e95 517 {
a25720a3
SK
518 if (is_sign)
519 return plen;
520
28866e95 521 /* We are adding the pseudoheader */
ed4c0767 522 if (!(p = skip_questions(header, plen)) ||
28866e95 523 !(p = skip_section(p,
a25720a3 524 ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
ed4c0767
SK
525 header, plen)))
526 return plen;
28866e95
SK
527 *p++ = 0; /* empty name */
528 PUTSHORT(T_OPT, p);
ed4c0767 529 PUTSHORT(daemon->edns_pktsz, p); /* max packet length */
3a237152
SK
530 PUTSHORT(0, p); /* extended RCODE and version */
531 PUTSHORT(set_do ? 0x8000 : 0, p); /* DO flag */
28866e95
SK
532 lenp = p;
533 PUTSHORT(0, p); /* RDLEN */
534 rdlen = 0;
ed4c0767
SK
535 if (((ssize_t)optlen) > (limit - (p + 4)))
536 return plen; /* Too big */
a25720a3 537 header->arcount = htons(ntohs(header->arcount) + 1);
28866e95
SK
538 datap = p;
539 }
540 else
541 {
a25720a3 542 int i;
3a237152 543 unsigned short code, len, flags;
28866e95 544
a25720a3 545 /* Must be at the end, if exists */
28866e95 546 if (ntohs(header->arcount) != 1 ||
28866e95 547 is_sign ||
ed4c0767
SK
548 (!(p = skip_name(p, header, plen, 10))))
549 return plen;
28866e95 550
3a237152
SK
551 p += 6; /* skip UDP length and RCODE */
552 GETSHORT(flags, p);
553 if (set_do)
554 {
555 p -=2;
556 PUTSHORT(flags | 0x8000, p);
557 }
558
28866e95
SK
559 lenp = p;
560 GETSHORT(rdlen, p);
ed4c0767
SK
561 if (!CHECK_LEN(header, p, plen, rdlen))
562 return plen; /* bad packet */
28866e95
SK
563 datap = p;
564
3a237152
SK
565 /* no option to add */
566 if (optno == 0)
567 return plen;
568
28866e95
SK
569 /* check if option already there */
570 for (i = 0; i + 4 < rdlen; i += len + 4)
571 {
572 GETSHORT(code, p);
573 GETSHORT(len, p);
ed4c0767
SK
574 if (code == optno)
575 return plen;
28866e95
SK
576 p += len;
577 }
feba5c1d 578
ed4c0767
SK
579 if (((ssize_t)optlen) > (limit - (p + 4)))
580 return plen; /* Too big */
28866e95
SK
581 }
582
0fc2f313
SK
583 if (optno != 0)
584 {
585 PUTSHORT(optno, p);
586 PUTSHORT(optlen, p);
587 memcpy(p, opt, optlen);
588 p += optlen;
589 }
28866e95
SK
590
591 PUTSHORT(p - datap, lenp);
ed4c0767
SK
592 return p - (unsigned char *)header;
593
594}
595
596static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *parmv)
597{
598 struct macparm *parm = parmv;
599 int match = 0;
600
601 if (family == parm->l3->sa.sa_family)
602 {
603 if (family == AF_INET && memcmp (&parm->l3->in.sin_addr, addrp, INADDRSZ) == 0)
604 match = 1;
605#ifdef HAVE_IPV6
606 else
607 if (family == AF_INET6 && memcmp (&parm->l3->in6.sin6_addr, addrp, IN6ADDRSZ) == 0)
608 match = 1;
609#endif
610 }
611
612 if (!match)
613 return 1; /* continue */
614
3a237152 615 parm->plen = add_pseudoheader(parm->header, parm->plen, parm->limit, EDNS0_OPTION_MAC, (unsigned char *)mac, maclen, 0);
28866e95
SK
616
617 return 0; /* done */
618}
619
572b41eb 620size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysockaddr *l3)
28866e95
SK
621{
622 struct macparm parm;
623
624/* Must have an existing pseudoheader as the only ar-record,
625 or have no ar-records. Must also not be signed */
626
627 if (ntohs(header->arcount) > 1)
628 return plen;
629
630 parm.header = header;
631 parm.limit = (unsigned char *)limit;
632 parm.plen = plen;
633 parm.l3 = l3;
634
635 iface_enumerate(AF_UNSPEC, &parm, filter_mac);
feba5c1d 636
28866e95
SK
637 return parm.plen;
638}
639
ed4c0767
SK
640struct subnet_opt {
641 u16 family;
642 u8 source_netmask, scope_netmask;
643#ifdef HAVE_IPV6
644 u8 addr[IN6ADDRSZ];
645#else
646 u8 addr[INADDRSZ];
647#endif
648};
649
44de649e 650static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
ed4c0767
SK
651{
652 /* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
653
654 int len;
655 void *addrp;
656
ed4c0767 657#ifdef HAVE_IPV6
24b5a5d5 658 if (source->sa.sa_family == AF_INET6)
ed4c0767
SK
659 {
660 opt->family = htons(2);
661 opt->source_netmask = daemon->addr6_netmask;
662 addrp = &source->in6.sin6_addr;
663 }
24b5a5d5 664 else
ed4c0767 665#endif
24b5a5d5
SK
666 {
667 opt->family = htons(1);
668 opt->source_netmask = daemon->addr4_netmask;
669 addrp = &source->in.sin_addr;
670 }
ed4c0767
SK
671
672 opt->scope_netmask = 0;
673 len = 0;
674
675 if (opt->source_netmask != 0)
676 {
677 len = ((opt->source_netmask - 1) >> 3) + 1;
678 memcpy(opt->addr, addrp, len);
679 if (opt->source_netmask & 7)
680 opt->addr[len-1] &= 0xff << (8 - (opt->source_netmask & 7));
681 }
682
683 return len + 4;
684}
685
686size_t add_source_addr(struct dns_header *header, size_t plen, char *limit, union mysockaddr *source)
687{
688 /* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
689
690 int len;
691 struct subnet_opt opt;
692
693 len = calc_subnet_opt(&opt, source);
3a237152 694 return add_pseudoheader(header, plen, (unsigned char *)limit, EDNS0_OPTION_CLIENT_SUBNET, (unsigned char *)&opt, len, 0);
ed4c0767 695}
3a237152
SK
696
697#ifdef HAVE_DNSSEC
698size_t add_do_bit(struct dns_header *header, size_t plen, char *limit)
699{
700 return add_pseudoheader(header, plen, (unsigned char *)limit, 0, NULL, 0, 1);
701}
702#endif
703
ed4c0767
SK
704int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer)
705{
706 /* Section 9.2, Check that subnet option in reply matches. */
707
708
709 int len, calc_len;
710 struct subnet_opt opt;
711 unsigned char *p;
712 int code, i, rdlen;
713
714 calc_len = calc_subnet_opt(&opt, peer);
715
716 if (!(p = skip_name(pseudoheader, header, plen, 10)))
717 return 1;
718
719 p += 8; /* skip UDP length and RCODE */
720
721 GETSHORT(rdlen, p);
722 if (!CHECK_LEN(header, p, plen, rdlen))
723 return 1; /* bad packet */
724
725 /* check if option there */
726 for (i = 0; i + 4 < rdlen; i += len + 4)
727 {
728 GETSHORT(code, p);
729 GETSHORT(len, p);
730 if (code == EDNS0_OPTION_CLIENT_SUBNET)
731 {
732 /* make sure this doesn't mismatch. */
733 opt.scope_netmask = p[3];
734 if (len != calc_len || memcmp(p, &opt, len) != 0)
735 return 0;
736 }
737 p += len;
738 }
739
740 return 1;
741}
742
9e4abcb5 743/* is addr in the non-globally-routed IP space? */
dc27e148 744int private_net(struct in_addr addr, int ban_localhost)
9e4abcb5 745{
f2621c7f
SK
746 in_addr_t ip_addr = ntohl(addr.s_addr);
747
748 return
8ef5ada2 749 (((ip_addr & 0xFF000000) == 0x7F000000) && ban_localhost) /* 127.0.0.0/8 (loopback) */ ||
f2621c7f
SK
750 ((ip_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168.0.0/16 (private) */ ||
751 ((ip_addr & 0xFF000000) == 0x0A000000) /* 10.0.0.0/8 (private) */ ||
752 ((ip_addr & 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12 (private) */ ||
753 ((ip_addr & 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */ ;
9e4abcb5 754}
fd9fa481 755
572b41eb 756static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *header, size_t qlen, char *name)
824af85b
SK
757{
758 int i, qtype, qclass, rdlen;
824af85b
SK
759
760 for (i = count; i != 0; i--)
761 {
28866e95 762 if (name && option_bool(OPT_LOG))
8ef5ada2
SK
763 {
764 if (!extract_name(header, qlen, &p, name, 1, 10))
765 return 0;
766 }
767 else if (!(p = skip_name(p, header, qlen, 10)))
824af85b
SK
768 return 0; /* bad packet */
769
770 GETSHORT(qtype, p);
771 GETSHORT(qclass, p);
7de060b0 772 p += 4; /* ttl */
824af85b
SK
773 GETSHORT(rdlen, p);
774
8ef5ada2 775 if (qclass == C_IN && qtype == T_A)
824af85b
SK
776 {
777 struct doctor *doctor;
778 struct in_addr addr;
779
9009d746
SK
780 if (!CHECK_LEN(header, p, qlen, INADDRSZ))
781 return 0;
8ef5ada2
SK
782
783 /* alignment */
824af85b
SK
784 memcpy(&addr, p, INADDRSZ);
785
786 for (doctor = daemon->doctors; doctor; doctor = doctor->next)
73a08a24
SK
787 {
788 if (doctor->end.s_addr == 0)
789 {
790 if (!is_same_net(doctor->in, addr, doctor->mask))
791 continue;
792 }
793 else if (ntohl(doctor->in.s_addr) > ntohl(addr.s_addr) ||
794 ntohl(doctor->end.s_addr) < ntohl(addr.s_addr))
795 continue;
8ef5ada2 796
73a08a24
SK
797 addr.s_addr &= ~doctor->mask.s_addr;
798 addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
799 /* Since we munged the data, the server it came from is no longer authoritative */
572b41eb 800 header->hb3 &= ~HB3_AA;
73a08a24
SK
801 memcpy(p, &addr, INADDRSZ);
802 break;
803 }
824af85b 804 }
28866e95 805 else if (qtype == T_TXT && name && option_bool(OPT_LOG))
8ef5ada2
SK
806 {
807 unsigned char *p1 = p;
808 if (!CHECK_LEN(header, p1, qlen, rdlen))
809 return 0;
810 while ((p1 - p) < rdlen)
811 {
812 unsigned int i, len = *p1;
813 unsigned char *p2 = p1;
814 /* make counted string zero-term and sanitise */
815 for (i = 0; i < len; i++)
231d061b
SK
816 {
817 if (!isprint((int)*(p2+1)))
818 break;
819
820 *p2 = *(p2+1);
821 p2++;
822 }
8ef5ada2 823 *p2 = 0;
28866e95 824 my_syslog(LOG_INFO, "reply %s is %s", name, p1);
8ef5ada2 825 /* restore */
231d061b 826 memmove(p1 + 1, p1, i);
8ef5ada2
SK
827 *p1 = len;
828 p1 += len+1;
829 }
830 }
824af85b 831
9009d746
SK
832 if (!ADD_RDLEN(header, p, qlen, rdlen))
833 return 0; /* bad packet */
824af85b
SK
834 }
835
836 return p;
837}
838
572b41eb 839static int find_soa(struct dns_header *header, size_t qlen, char *name)
9e4abcb5
SK
840{
841 unsigned char *p;
9e4abcb5 842 int qtype, qclass, rdlen;
fd9fa481
SK
843 unsigned long ttl, minttl = ULONG_MAX;
844 int i, found_soa = 0;
9e4abcb5 845
fd9fa481
SK
846 /* first move to NS section and find TTL from any SOA section */
847 if (!(p = skip_questions(header, qlen)) ||
8ef5ada2 848 !(p = do_doctor(p, ntohs(header->ancount), header, qlen, name)))
824af85b 849 return 0; /* bad packet */
9e4abcb5 850
5aabfc78 851 for (i = ntohs(header->nscount); i != 0; i--)
9e4abcb5 852 {
9009d746 853 if (!(p = skip_name(p, header, qlen, 10)))
fd9fa481
SK
854 return 0; /* bad packet */
855
9e4abcb5
SK
856 GETSHORT(qtype, p);
857 GETSHORT(qclass, p);
858 GETLONG(ttl, p);
859 GETSHORT(rdlen, p);
fd9fa481 860
9e4abcb5
SK
861 if ((qclass == C_IN) && (qtype == T_SOA))
862 {
fd9fa481
SK
863 found_soa = 1;
864 if (ttl < minttl)
865 minttl = ttl;
866
9e4abcb5 867 /* MNAME */
9009d746 868 if (!(p = skip_name(p, header, qlen, 0)))
fd9fa481 869 return 0;
9e4abcb5 870 /* RNAME */
9009d746 871 if (!(p = skip_name(p, header, qlen, 20)))
fd9fa481
SK
872 return 0;
873 p += 16; /* SERIAL REFRESH RETRY EXPIRE */
874
9e4abcb5
SK
875 GETLONG(ttl, p); /* minTTL */
876 if (ttl < minttl)
877 minttl = ttl;
878 }
9009d746 879 else if (!ADD_RDLEN(header, p, qlen, rdlen))
fd9fa481 880 return 0; /* bad packet */
9e4abcb5 881 }
9009d746 882
824af85b 883 /* rewrite addresses in additioal section too */
8ef5ada2 884 if (!do_doctor(p, ntohs(header->arcount), header, qlen, NULL))
824af85b
SK
885 return 0;
886
887 if (!found_soa)
888 minttl = daemon->neg_ttl;
889
890 return minttl;
1cff166d
SK
891}
892
fd9fa481
SK
893/* Note that the following code can create CNAME chains that don't point to a real record,
894 either because of lack of memory, or lack of SOA records. These are treated by the cache code as
824af85b 895 expired and cleaned out that way.
8ef5ada2 896 Return 1 if we reject an address because it look like part of dns-rebinding attack. */
572b41eb 897int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t now,
0fc2f313 898 char **ipsets, int is_sign, int check_rebind, int no_cache_dnssec, int secure)
9e4abcb5 899{
824af85b 900 unsigned char *p, *p1, *endrr, *namep;
fd9fa481 901 int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
0a852541 902 unsigned long ttl = 0;
5aabfc78 903 struct all_addr addr;
13d86c73
JD
904#ifdef HAVE_IPSET
905 char **ipsets_cur;
906#else
907 (void)ipsets; /* unused */
908#endif
909
9e4abcb5 910 cache_start_insert();
0a852541 911
8ef5ada2 912 /* find_soa is needed for dns_doctor and logging side-effects, so don't call it lazily if there are any. */
28866e95 913 if (daemon->doctors || option_bool(OPT_LOG))
0a852541
SK
914 {
915 searched_soa = 1;
8ef5ada2 916 ttl = find_soa(header, qlen, name);
0a852541 917 }
9e4abcb5 918
fd9fa481
SK
919 /* go through the questions. */
920 p = (unsigned char *)(header+1);
9e4abcb5 921
5aabfc78 922 for (i = ntohs(header->qdcount); i != 0; i--)
9e4abcb5 923 {
fd9fa481
SK
924 int found = 0, cname_count = 5;
925 struct crec *cpp = NULL;
572b41eb 926 int flags = RCODE(header) == NXDOMAIN ? F_NXDOMAIN : 0;
0435d041 927 int secflag = secure ? F_DNSSECOK : 0;
0a852541 928 unsigned long cttl = ULONG_MAX, attl;
0fc2f313 929
824af85b 930 namep = p;
9009d746 931 if (!extract_name(header, qlen, &p, name, 1, 4))
824af85b 932 return 0; /* bad packet */
fd9fa481 933
9e4abcb5
SK
934 GETSHORT(qtype, p);
935 GETSHORT(qclass, p);
9e4abcb5
SK
936
937 if (qclass != C_IN)
fd9fa481 938 continue;
9e4abcb5 939
fd9fa481
SK
940 /* PTRs: we chase CNAMEs here, since we have no way to
941 represent them in the cache. */
942 if (qtype == T_PTR)
943 {
9e4abcb5 944 int name_encoding = in_arpa_name_2_addr(name, &addr);
fd9fa481
SK
945
946 if (!name_encoding)
947 continue;
948
949 if (!(flags & F_NXDOMAIN))
9e4abcb5 950 {
fd9fa481
SK
951 cname_loop:
952 if (!(p1 = skip_questions(header, qlen)))
824af85b 953 return 0;
fd9fa481 954
5aabfc78 955 for (j = ntohs(header->ancount); j != 0; j--)
fd9fa481 956 {
824af85b
SK
957 unsigned char *tmp = namep;
958 /* the loop body overwrites the original name, so get it back here. */
9009d746
SK
959 if (!extract_name(header, qlen, &tmp, name, 1, 0) ||
960 !(res = extract_name(header, qlen, &p1, name, 0, 10)))
824af85b 961 return 0; /* bad packet */
fd9fa481
SK
962
963 GETSHORT(aqtype, p1);
964 GETSHORT(aqclass, p1);
965 GETLONG(attl, p1);
8ef5ada2
SK
966 if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
967 {
572b41eb 968 (p1) -= 4;
8ef5ada2
SK
969 PUTLONG(daemon->max_ttl, p1);
970 }
fd9fa481
SK
971 GETSHORT(ardlen, p1);
972 endrr = p1+ardlen;
973
974 /* TTL of record is minimum of CNAMES and PTR */
975 if (attl < cttl)
976 cttl = attl;
977
978 if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
979 {
9009d746 980 if (!extract_name(header, qlen, &p1, name, 1, 0))
824af85b 981 return 0;
fd9fa481
SK
982
983 if (aqtype == T_CNAME)
984 {
985 if (!cname_count--)
824af85b 986 return 0; /* looped CNAMES */
fd9fa481
SK
987 goto cname_loop;
988 }
989
0435d041 990 cache_insert(name, &addr, now, cttl, name_encoding | secflag | F_REVERSE);
fd9fa481
SK
991 found = 1;
992 }
993
994 p1 = endrr;
9009d746 995 if (!CHECK_LEN(header, p1, qlen, 0))
824af85b 996 return 0; /* bad packet */
fd9fa481
SK
997 }
998 }
999
28866e95 1000 if (!found && !option_bool(OPT_NO_NEG))
fd9fa481
SK
1001 {
1002 if (!searched_soa)
1003 {
1004 searched_soa = 1;
8ef5ada2 1005 ttl = find_soa(header, qlen, NULL);
fd9fa481
SK
1006 }
1007 if (ttl)
0435d041 1008 cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags | secflag);
9e4abcb5
SK
1009 }
1010 }
fd9fa481 1011 else
9e4abcb5 1012 {
fd9fa481
SK
1013 /* everything other than PTR */
1014 struct crec *newc;
5aabfc78
SK
1015 int addrlen;
1016
fd9fa481 1017 if (qtype == T_A)
5aabfc78
SK
1018 {
1019 addrlen = INADDRSZ;
1020 flags |= F_IPV4;
1021 }
fd9fa481
SK
1022#ifdef HAVE_IPV6
1023 else if (qtype == T_AAAA)
5aabfc78
SK
1024 {
1025 addrlen = IN6ADDRSZ;
1026 flags |= F_IPV6;
1027 }
fd9fa481
SK
1028#endif
1029 else
1030 continue;
1031
45cca585
SK
1032 cname_loop1:
1033 if (!(p1 = skip_questions(header, qlen)))
1034 return 0;
1035
1036 for (j = ntohs(header->ancount); j != 0; j--)
9e4abcb5 1037 {
45cca585
SK
1038 if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
1039 return 0; /* bad packet */
9e4abcb5 1040
45cca585
SK
1041 GETSHORT(aqtype, p1);
1042 GETSHORT(aqclass, p1);
1043 GETLONG(attl, p1);
1044 if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
9e4abcb5 1045 {
45cca585
SK
1046 (p1) -= 4;
1047 PUTLONG(daemon->max_ttl, p1);
1048 }
1049 GETSHORT(ardlen, p1);
1050 endrr = p1+ardlen;
1051
1052 if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
1053 {
1054 if (aqtype == T_CNAME)
fd9fa481 1055 {
45cca585
SK
1056 if (!cname_count--)
1057 return 0; /* looped CNAMES */
0435d041 1058 newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD | secflag);
45cca585 1059 if (newc)
fd9fa481 1060 {
45cca585
SK
1061 newc->addr.cname.target.cache = NULL;
1062 if (cpp)
fd9fa481 1063 {
45cca585
SK
1064 cpp->addr.cname.target.cache = newc;
1065 cpp->addr.cname.uid = newc->uid;
fd9fa481 1066 }
fd9fa481 1067 }
45cca585
SK
1068
1069 cpp = newc;
1070 if (attl < cttl)
1071 cttl = attl;
1072
1073 if (!extract_name(header, qlen, &p1, name, 1, 0))
1074 return 0;
1075 goto cname_loop1;
1076 }
1077 else if (!(flags & F_NXDOMAIN))
1078 {
1079 found = 1;
1080
1081 /* copy address into aligned storage */
1082 if (!CHECK_LEN(header, p1, qlen, addrlen))
1083 return 0; /* bad packet */
1084 memcpy(&addr, p1, addrlen);
1085
1086 /* check for returned address in private space */
1087 if (check_rebind &&
1088 (flags & F_IPV4) &&
1089 private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
1090 return 1;
1091
13d86c73 1092#ifdef HAVE_IPSET
45cca585
SK
1093 if (ipsets && (flags & (F_IPV4 | F_IPV6)))
1094 {
1095 ipsets_cur = ipsets;
1096 while (*ipsets_cur)
1097 add_to_ipset(*ipsets_cur++, &addr, flags, 0);
1098 }
13d86c73 1099#endif
45cca585 1100
0435d041 1101 newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD | secflag);
45cca585
SK
1102 if (newc && cpp)
1103 {
1104 cpp->addr.cname.target.cache = newc;
1105 cpp->addr.cname.uid = newc->uid;
fd9fa481 1106 }
45cca585 1107 cpp = NULL;
fd9fa481 1108 }
fd9fa481 1109 }
45cca585
SK
1110
1111 p1 = endrr;
1112 if (!CHECK_LEN(header, p1, qlen, 0))
1113 return 0; /* bad packet */
fd9fa481
SK
1114 }
1115
28866e95 1116 if (!found && !option_bool(OPT_NO_NEG))
fd9fa481
SK
1117 {
1118 if (!searched_soa)
1cff166d 1119 {
fd9fa481 1120 searched_soa = 1;
8ef5ada2 1121 ttl = find_soa(header, qlen, NULL);
1cff166d 1122 }
fd9fa481 1123 /* If there's no SOA to get the TTL from, but there is a CNAME
824af85b 1124 pointing at this, inherit its TTL */
fd9fa481 1125 if (ttl || cpp)
9e4abcb5 1126 {
0435d041 1127 newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | secflag);
26128d27 1128 if (newc && cpp)
9e4abcb5 1129 {
d56a604a 1130 cpp->addr.cname.target.cache = newc;
fd9fa481
SK
1131 cpp->addr.cname.uid = newc->uid;
1132 }
9e4abcb5 1133 }
9e4abcb5 1134 }
fd9fa481 1135 }
9e4abcb5 1136 }
fd9fa481 1137
1023dcbc 1138 /* Don't put stuff from a truncated packet into the cache.
1023dcbc
SK
1139 Don't cache replies from non-recursive nameservers, since we may get a
1140 reply containing a CNAME but not its target, even though the target
1141 does exist. */
1142 if (!(header->hb3 & HB3_TC) &&
1143 !(header->hb4 & HB4_CD) &&
1144 (header->hb4 & HB4_RA) &&
3a237152 1145 !no_cache_dnssec)
824af85b
SK
1146 cache_end_insert();
1147
1148 return 0;
9e4abcb5
SK
1149}
1150
1151/* If the packet holds exactly one query
28866e95 1152 return F_IPV4 or F_IPV6 and leave the name from the query in name */
572b41eb 1153unsigned int extract_request(struct dns_header *header, size_t qlen, char *name, unsigned short *typep)
9e4abcb5
SK
1154{
1155 unsigned char *p = (unsigned char *)(header+1);
1156 int qtype, qclass;
1157
c1bb8504
SK
1158 if (typep)
1159 *typep = 0;
1160
572b41eb 1161 if (ntohs(header->qdcount) != 1 || OPCODE(header) != QUERY)
9e4abcb5
SK
1162 return 0; /* must be exactly one query. */
1163
9009d746 1164 if (!extract_name(header, qlen, &p, name, 1, 4))
9e4abcb5
SK
1165 return 0; /* bad packet */
1166
1167 GETSHORT(qtype, p);
1168 GETSHORT(qclass, p);
1169
0a852541
SK
1170 if (typep)
1171 *typep = qtype;
1172
9e4abcb5
SK
1173 if (qclass == C_IN)
1174 {
1175 if (qtype == T_A)
1176 return F_IPV4;
1177 if (qtype == T_AAAA)
1178 return F_IPV6;
1179 if (qtype == T_ANY)
1180 return F_IPV4 | F_IPV6;
1181 }
1182
1183 return F_QUERY;
1184}
1185
1186
572b41eb 1187size_t setup_reply(struct dns_header *header, size_t qlen,
28866e95 1188 struct all_addr *addrp, unsigned int flags, unsigned long ttl)
9e4abcb5
SK
1189{
1190 unsigned char *p = skip_questions(header, qlen);
1191
572b41eb
SK
1192 /* clear authoritative and truncated flags, set QR flag */
1193 header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
1194 /* set RA flag */
1195 header->hb4 |= HB4_RA;
1196
9e4abcb5
SK
1197 header->nscount = htons(0);
1198 header->arcount = htons(0);
feba5c1d 1199 header->ancount = htons(0); /* no answers unless changed below */
9e4abcb5 1200 if (flags == F_NEG)
572b41eb 1201 SET_RCODE(header, SERVFAIL); /* couldn't get memory */
824af85b 1202 else if (flags == F_NOERR)
572b41eb 1203 SET_RCODE(header, NOERROR); /* empty domain */
9e4abcb5 1204 else if (flags == F_NXDOMAIN)
572b41eb 1205 SET_RCODE(header, NXDOMAIN);
9e4abcb5
SK
1206 else if (p && flags == F_IPV4)
1207 { /* we know the address */
572b41eb 1208 SET_RCODE(header, NOERROR);
9e4abcb5 1209 header->ancount = htons(1);
572b41eb
SK
1210 header->hb3 |= HB3_AA;
1211 add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_A, C_IN, "4", addrp);
9e4abcb5
SK
1212 }
1213#ifdef HAVE_IPV6
1214 else if (p && flags == F_IPV6)
1215 {
572b41eb 1216 SET_RCODE(header, NOERROR);
9e4abcb5 1217 header->ancount = htons(1);
572b41eb
SK
1218 header->hb3 |= HB3_AA;
1219 add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
9e4abcb5
SK
1220 }
1221#endif
1222 else /* nowhere to forward to */
572b41eb 1223 SET_RCODE(header, REFUSED);
9e4abcb5
SK
1224
1225 return p - (unsigned char *)header;
1226}
36717eee
SK
1227
1228/* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
5aabfc78 1229int check_for_local_domain(char *name, time_t now)
36717eee
SK
1230{
1231 struct crec *crecp;
0a852541
SK
1232 struct mx_srv_record *mx;
1233 struct txt_record *txt;
f2621c7f
SK
1234 struct interface_name *intr;
1235 struct ptr_record *ptr;
7de060b0
SK
1236 struct naptr *naptr;
1237
1238 if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME)) &&
7b174c25 1239 (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
36717eee
SK
1240 return 1;
1241
7de060b0
SK
1242 for (naptr = daemon->naptr; naptr; naptr = naptr->next)
1243 if (hostname_isequal(name, naptr->name))
1244 return 1;
1245
1246 for (mx = daemon->mxnames; mx; mx = mx->next)
0a852541 1247 if (hostname_isequal(name, mx->name))
36717eee 1248 return 1;
f6b7dc47 1249
0a852541
SK
1250 for (txt = daemon->txt; txt; txt = txt->next)
1251 if (hostname_isequal(name, txt->name))
f6b7dc47 1252 return 1;
f2621c7f
SK
1253
1254 for (intr = daemon->int_names; intr; intr = intr->next)
1255 if (hostname_isequal(name, intr->name))
1256 return 1;
1257
1258 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1259 if (hostname_isequal(name, ptr->name))
1260 return 1;
1261
36717eee
SK
1262 return 0;
1263}
9e4abcb5
SK
1264
1265/* Is the packet a reply with the answer address equal to addr?
1266 If so mung is into an NXDOMAIN reply and also put that information
1267 in the cache. */
572b41eb 1268int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
9e4abcb5
SK
1269 struct bogus_addr *baddr, time_t now)
1270{
1271 unsigned char *p;
1272 int i, qtype, qclass, rdlen;
1273 unsigned long ttl;
1274 struct bogus_addr *baddrp;
1275
1276 /* skip over questions */
1277 if (!(p = skip_questions(header, qlen)))
1278 return 0; /* bad packet */
1279
5aabfc78 1280 for (i = ntohs(header->ancount); i != 0; i--)
9e4abcb5 1281 {
9009d746 1282 if (!extract_name(header, qlen, &p, name, 1, 10))
9e4abcb5
SK
1283 return 0; /* bad packet */
1284
1285 GETSHORT(qtype, p);
1286 GETSHORT(qclass, p);
1287 GETLONG(ttl, p);
1288 GETSHORT(rdlen, p);
1289
1290 if (qclass == C_IN && qtype == T_A)
9009d746
SK
1291 {
1292 if (!CHECK_LEN(header, p, qlen, INADDRSZ))
1293 return 0;
1294
1295 for (baddrp = baddr; baddrp; baddrp = baddrp->next)
1296 if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
1297 {
1298 /* Found a bogus address. Insert that info here, since there no SOA record
1299 to get the ttl from in the normal processing */
1300 cache_start_insert();
8db957df 1301 cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
9009d746
SK
1302 cache_end_insert();
1303
1304 return 1;
1305 }
1306 }
9e4abcb5 1307
9009d746
SK
1308 if (!ADD_RDLEN(header, p, qlen, rdlen))
1309 return 0;
9e4abcb5
SK
1310 }
1311
1312 return 0;
1313}
1314
b75e9363 1315int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp,
e1ff419c 1316 unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
f6b7dc47
SK
1317{
1318 va_list ap;
1319 unsigned char *sav, *p = *pp;
1320 int j;
1321 unsigned short usval;
1322 long lval;
1323 char *sval;
1324
1325 if (truncp && *truncp)
1326 return 0;
4f7b304f
SK
1327
1328 va_start(ap, format); /* make ap point to 1st unamed argument */
1329
b75e9363 1330 if (nameoffset > 0)
4f7b304f
SK
1331 {
1332 PUTSHORT(nameoffset | 0xc000, p);
1333 }
1334 else
1335 {
e1ff419c
SK
1336 char *name = va_arg(ap, char *);
1337 if (name)
1338 p = do_rfc1035_name(p, name);
b75e9363
SK
1339 if (nameoffset < 0)
1340 {
1341 PUTSHORT(-nameoffset | 0xc000, p);
1342 }
1343 else
1344 *p++ = 0;
4f7b304f 1345 }
f6b7dc47 1346
f6b7dc47
SK
1347 PUTSHORT(type, p);
1348 PUTSHORT(class, p);
1349 PUTLONG(ttl, p); /* TTL */
1350
1351 sav = p; /* Save pointer to RDLength field */
1352 PUTSHORT(0, p); /* Placeholder RDLength */
1353
f6b7dc47
SK
1354 for (; *format; format++)
1355 switch (*format)
1356 {
1357#ifdef HAVE_IPV6
1358 case '6':
1359 sval = va_arg(ap, char *);
1360 memcpy(p, sval, IN6ADDRSZ);
1361 p += IN6ADDRSZ;
1362 break;
1363#endif
1364
1365 case '4':
1366 sval = va_arg(ap, char *);
1367 memcpy(p, sval, INADDRSZ);
1368 p += INADDRSZ;
1369 break;
1370
1371 case 's':
1372 usval = va_arg(ap, int);
1373 PUTSHORT(usval, p);
1374 break;
1375
1376 case 'l':
1377 lval = va_arg(ap, long);
1378 PUTLONG(lval, p);
1379 break;
1380
1381 case 'd':
1382 /* get domain-name answer arg and store it in RDATA field */
0a852541
SK
1383 if (offset)
1384 *offset = p - (unsigned char *)header;
3d8df260 1385 p = do_rfc1035_name(p, va_arg(ap, char *));
f6b7dc47
SK
1386 *p++ = 0;
1387 break;
3d8df260 1388
f6b7dc47 1389 case 't':
0a852541 1390 usval = va_arg(ap, int);
f6b7dc47 1391 sval = va_arg(ap, char *);
9f7f3b12
SK
1392 if (usval != 0)
1393 memcpy(p, sval, usval);
0a852541 1394 p += usval;
f6b7dc47 1395 break;
1a6bca81
SK
1396
1397 case 'z':
1398 sval = va_arg(ap, char *);
1399 usval = sval ? strlen(sval) : 0;
1400 if (usval > 255)
1401 usval = 255;
1402 *p++ = (unsigned char)usval;
1403 memcpy(p, sval, usval);
1404 p += usval;
1405 break;
f6b7dc47
SK
1406 }
1407
1408 va_end(ap); /* clean up variable argument pointer */
1409
1410 j = p - sav - 2;
1411 PUTSHORT(j, sav); /* Now, store real RDLength */
1412
f6b7dc47
SK
1413 /* check for overflow of buffer */
1414 if (limit && ((unsigned char *)limit - p) < 0)
1415 {
1416 if (truncp)
1417 *truncp = 1;
1418 return 0;
1419 }
1420
1421 *pp = p;
1422 return 1;
1423}
1424
9009d746
SK
1425static unsigned long crec_ttl(struct crec *crecp, time_t now)
1426{
1427 /* Return 0 ttl for DHCP entries, which might change
1428 before the lease expires. */
1429
1430 if (crecp->flags & (F_IMMORTAL | F_DHCP))
1431 return daemon->local_ttl;
1432
8ef5ada2
SK
1433 /* Return the Max TTL value if it is lower then the actual TTL */
1434 if (daemon->max_ttl == 0 || ((unsigned)(crecp->ttd - now) < daemon->max_ttl))
1435 return crecp->ttd - now;
1436 else
1437 return daemon->max_ttl;
9009d746
SK
1438}
1439
1440
9e4abcb5 1441/* return zero if we can't answer from cache, or packet size if we can */
572b41eb 1442size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
cdeda28f 1443 struct in_addr local_addr, struct in_addr local_netmask, time_t now)
9e4abcb5 1444{
3be34541 1445 char *name = daemon->namebuff;
feba5c1d 1446 unsigned char *p, *ansp, *pheader;
832af0ba 1447 int qtype, qclass;
9e4abcb5 1448 struct all_addr addr;
b75e9363 1449 int nameoffset;
feba5c1d 1450 unsigned short flag;
0a852541 1451 int q, ans, anscount = 0, addncount = 0;
a25720a3 1452 int dryrun = 0, sec_reqd = 0, have_pseudoheader = 0;
832af0ba 1453 int is_sign;
9e4abcb5 1454 struct crec *crecp;
0fc2f313 1455 int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1;
0a852541 1456 struct mx_srv_record *rec;
a25720a3 1457 size_t len;
0a852541 1458
a25720a3
SK
1459 /* Don't return AD set even for local data if checking disabled. */
1460 if (header->hb4 & HB4_CD)
1461 sec_data = 0;
1462
feba5c1d
SK
1463 /* If there is an RFC2671 pseudoheader then it will be overwritten by
1464 partial replies, so we have to do a dry run to see if we can answer
1465 the query. We check to see if the do bit is set, if so we always
1466 forward rather than answering from the cache, which doesn't include
a25720a3 1467 security information, unless we're in DNSSEC validation mode. */
feba5c1d 1468
832af0ba 1469 if (find_pseudoheader(header, qlen, NULL, &pheader, &is_sign))
feba5c1d 1470 {
7de060b0 1471 unsigned short udpsz, flags;
feba5c1d
SK
1472 unsigned char *psave = pheader;
1473
a25720a3
SK
1474 have_pseudoheader = 1;
1475
feba5c1d 1476 GETSHORT(udpsz, pheader);
7de060b0 1477 pheader += 2; /* ext_rcode */
feba5c1d
SK
1478 GETSHORT(flags, pheader);
1479
1480 sec_reqd = flags & 0x8000; /* do bit */
1481
1482 /* If our client is advertising a larger UDP packet size
1483 than we allow, trim it so that we don't get an overlarge
1484 response from upstream */
1485
832af0ba 1486 if (!is_sign && (udpsz > daemon->edns_pktsz))
3be34541 1487 PUTSHORT(daemon->edns_pktsz, psave);
feba5c1d
SK
1488
1489 dryrun = 1;
1490 }
1491
572b41eb 1492 if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
832af0ba
SK
1493 return 0;
1494
0a852541
SK
1495 for (rec = daemon->mxnames; rec; rec = rec->next)
1496 rec->offset = 0;
1497
feba5c1d 1498 rerun:
9e4abcb5
SK
1499 /* determine end of question section (we put answers there) */
1500 if (!(ansp = skip_questions(header, qlen)))
1501 return 0; /* bad packet */
1502
1503 /* now process each question, answers go in RRs after the question */
1504 p = (unsigned char *)(header+1);
feba5c1d 1505
5aabfc78 1506 for (q = ntohs(header->qdcount); q != 0; q--)
9e4abcb5
SK
1507 {
1508 /* save pointer to name for copying into answers */
1509 nameoffset = p - (unsigned char *)header;
1510
1511 /* now extract name as .-concatenated string into name */
9009d746 1512 if (!extract_name(header, qlen, &p, name, 1, 4))
9e4abcb5 1513 return 0; /* bad packet */
832af0ba 1514
9e4abcb5
SK
1515 GETSHORT(qtype, p);
1516 GETSHORT(qclass, p);
1517
1518 ans = 0; /* have we answered this question */
1519
0a852541 1520 if (qtype == T_TXT || qtype == T_ANY)
9e4abcb5 1521 {
0a852541
SK
1522 struct txt_record *t;
1523 for(t = daemon->txt; t ; t = t->next)
9e4abcb5 1524 {
0a852541
SK
1525 if (t->class == qclass && hostname_isequal(name, t->name))
1526 {
1527 ans = 1;
e17fb629
SK
1528 if (!dryrun)
1529 {
28866e95 1530 log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
e17fb629
SK
1531 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1532 daemon->local_ttl, NULL,
1533 T_TXT, t->class, "t", t->len, t->txt))
1534 anscount++;
1535
1536 }
0a852541 1537 }
9e4abcb5 1538 }
0a852541 1539 }
f6b7dc47 1540
0a852541 1541 if (qclass == C_IN)
9e4abcb5 1542 {
9f7f3b12
SK
1543 struct txt_record *t;
1544
1545 for (t = daemon->rr; t; t = t->next)
1546 if ((t->class == qtype || qtype == T_ANY) && hostname_isequal(name, t->name))
1547 {
1548 ans = 1;
1549 if (!dryrun)
1550 {
1551 log_query(F_CONFIG | F_RRNAME, name, NULL, "<RR>");
1552 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1553 daemon->local_ttl, NULL,
1554 t->class, C_IN, "t", t->len, t->txt))
1555 anscount ++;
1556 }
1557 }
1558
f6b7dc47 1559 if (qtype == T_PTR || qtype == T_ANY)
c1bb8504 1560 {
832af0ba
SK
1561 /* see if it's w.z.y.z.in-addr.arpa format */
1562 int is_arpa = in_arpa_name_2_addr(name, &addr);
1563 struct ptr_record *ptr;
f2621c7f 1564 struct interface_name* intr = NULL;
832af0ba
SK
1565
1566 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1567 if (hostname_isequal(name, ptr->name))
1568 break;
1569
f2621c7f
SK
1570 if (is_arpa == F_IPV4)
1571 for (intr = daemon->int_names; intr; intr = intr->next)
5aabfc78 1572 {
115ac3e4
SK
1573 struct addrlist *addrlist;
1574
376d48c7
SK
1575 for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1576 if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
115ac3e4
SK
1577 break;
1578
1579 if (addrlist)
1580 break;
1581 else
1582 while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1583 intr = intr->next;
1584 }
1585#ifdef HAVE_IPV6
1586 else if (is_arpa == F_IPV6)
1587 for (intr = daemon->int_names; intr; intr = intr->next)
1588 {
1589 struct addrlist *addrlist;
1590
376d48c7
SK
1591 for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1592 if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
115ac3e4
SK
1593 break;
1594
1595 if (addrlist)
5aabfc78
SK
1596 break;
1597 else
1598 while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1599 intr = intr->next;
1600 }
115ac3e4 1601#endif
f2621c7f
SK
1602
1603 if (intr)
1604 {
1605 ans = 1;
1606 if (!dryrun)
f6b7dc47 1607 {
115ac3e4 1608 log_query(is_arpa | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
f2621c7f
SK
1609 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1610 daemon->local_ttl, NULL,
1611 T_PTR, C_IN, "d", intr->name))
1612 anscount++;
9e4abcb5 1613 }
9e4abcb5 1614 }
832af0ba
SK
1615 else if (ptr)
1616 {
1617 ans = 1;
1618 if (!dryrun)
1619 {
28866e95 1620 log_query(F_CONFIG | F_RRNAME, name, NULL, "<PTR>");
832af0ba 1621 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
f2621c7f
SK
1622 if (hostname_isequal(name, ptr->name) &&
1623 add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1624 daemon->local_ttl, NULL,
1625 T_PTR, C_IN, "d", ptr->ptr))
1626 anscount++;
1627
1628 }
1629 }
1630 else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
1631 do
1632 {
1633 /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
1634 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1635 continue;
1636
0fc2f313
SK
1637 if (!(crecp->flags & F_DNSSECOK))
1638 sec_data = 0;
1639
f2621c7f
SK
1640 if (crecp->flags & F_NEG)
1641 {
1642 ans = 1;
1643 auth = 0;
1644 if (crecp->flags & F_NXDOMAIN)
1645 nxdomain = 1;
1646 if (!dryrun)
1a6bca81 1647 log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
f2621c7f 1648 }
a25720a3 1649 else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd || option_bool(OPT_DNSSEC_VALID))
f2621c7f
SK
1650 {
1651 ans = 1;
1652 if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1653 auth = 0;
1654 if (!dryrun)
832af0ba 1655 {
1a6bca81 1656 log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
7622fc06 1657 record_source(crecp->uid));
f2621c7f 1658
9009d746
SK
1659 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1660 crec_ttl(crecp, now), NULL,
f2621c7f 1661 T_PTR, C_IN, "d", cache_get_name(crecp)))
832af0ba
SK
1662 anscount++;
1663 }
f2621c7f
SK
1664 }
1665 } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
2bb73af7
SK
1666 else if (is_rev_synth(is_arpa, &addr, name))
1667 {
1668 ans = 1;
1669 if (!dryrun)
1670 {
1671 log_query(F_CONFIG | F_REVERSE | is_arpa, name, &addr, NULL);
1672
1673 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1674 daemon->local_ttl, NULL,
1675 T_PTR, C_IN, "d", name))
1676 anscount++;
1677 }
1678 }
f2621c7f 1679 else if (is_arpa == F_IPV4 &&
28866e95 1680 option_bool(OPT_BOGUSPRIV) &&
8ef5ada2 1681 private_net(addr.addr.addr4, 1))
f2621c7f
SK
1682 {
1683 /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
1684 ans = 1;
1685 nxdomain = 1;
1686 if (!dryrun)
1687 log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN,
1a6bca81 1688 name, &addr, NULL);
832af0ba 1689 }
f6b7dc47 1690 }
f2621c7f 1691
f6b7dc47
SK
1692 for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
1693 {
1694 unsigned short type = T_A;
115ac3e4
SK
1695 struct interface_name *intr;
1696
f6b7dc47 1697 if (flag == F_IPV6)
feba5c1d 1698#ifdef HAVE_IPV6
3d8df260 1699 type = T_AAAA;
feba5c1d 1700#else
3d8df260 1701 break;
feba5c1d 1702#endif
f6b7dc47
SK
1703
1704 if (qtype != type && qtype != T_ANY)
1705 continue;
1706
316e2730
SK
1707 /* Check for "A for A" queries; be rather conservative
1708 about what looks like dotted-quad. */
1709 if (qtype == T_A)
3d8df260 1710 {
316e2730
SK
1711 char *cp;
1712 unsigned int i, a;
1713 int x;
1714
1715 for (cp = name, i = 0, a = 0; *cp; i++)
3d8df260 1716 {
572b41eb 1717 if (!isdigit((unsigned char)*cp) || (x = strtol(cp, &cp, 10)) > 255)
316e2730
SK
1718 {
1719 i = 5;
1720 break;
1721 }
1722
1723 a = (a << 8) + x;
1724
1725 if (*cp == '.')
1726 cp++;
1727 }
1728
1729 if (i == 4)
1730 {
1731 ans = 1;
1732 if (!dryrun)
1733 {
1734 addr.addr.addr4.s_addr = htonl(a);
1735 log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
1736 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1737 daemon->local_ttl, NULL, type, C_IN, "4", &addr))
1738 anscount++;
1739 }
1740 continue;
3d8df260 1741 }
3d8df260
SK
1742 }
1743
f2621c7f 1744 /* interface name stuff */
d56a604a 1745 intname_restart:
115ac3e4
SK
1746 for (intr = daemon->int_names; intr; intr = intr->next)
1747 if (hostname_isequal(name, intr->name))
1748 break;
1749
1750 if (intr)
f2621c7f 1751 {
115ac3e4 1752 struct addrlist *addrlist;
fb63dd13 1753 int gotit = 0;
f2621c7f 1754
115ac3e4 1755 enumerate_interfaces(0);
f2621c7f 1756
fb63dd13
SK
1757 for (intr = daemon->int_names; intr; intr = intr->next)
1758 if (hostname_isequal(name, intr->name))
1759 {
fb63dd13
SK
1760 ans = 1;
1761 if (!dryrun)
115ac3e4 1762 {
376d48c7
SK
1763
1764 for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1765#ifdef HAVE_IPV6
1766 if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
1767#endif
1768 {
1769 gotit = 1;
1770 log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
1771 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1772 daemon->local_ttl, NULL, type, C_IN,
1773 type == T_A ? "4" : "6", &addrlist->addr))
1774 anscount++;
1775 }
115ac3e4 1776 }
fb63dd13
SK
1777 }
1778
1779 if (!dryrun && !gotit)
1780 log_query(F_FORWARD | F_CONFIG | flag | F_NEG, name, NULL, NULL);
1781
115ac3e4 1782 continue;
f2621c7f
SK
1783 }
1784
f6b7dc47
SK
1785 cname_restart:
1786 if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME)))
1787 {
1788 int localise = 0;
feba5c1d 1789
f6b7dc47
SK
1790 /* See if a putative address is on the network from which we recieved
1791 the query, is so we'll filter other answers. */
28866e95 1792 if (local_addr.s_addr != 0 && option_bool(OPT_LOCALISE) && flag == F_IPV4)
f6b7dc47
SK
1793 {
1794 struct crec *save = crecp;
1795 do {
1796 if ((crecp->flags & F_HOSTS) &&
1797 is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1798 {
1799 localise = 1;
1800 break;
1801 }
1802 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
1803 crecp = save;
1804 }
1805
1806 do
9e4abcb5 1807 {
26128d27
SK
1808 /* don't answer wildcard queries with data not from /etc/hosts
1809 or DHCP leases */
3bb51da8 1810 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
26128d27
SK
1811 break;
1812
0fc2f313
SK
1813 if (!(crecp->flags & F_DNSSECOK))
1814 sec_data = 0;
1815
fd9fa481
SK
1816 if (crecp->flags & F_CNAME)
1817 {
d56a604a
SK
1818 char *cname_target = cache_get_cname_target(crecp);
1819
fd9fa481
SK
1820 if (!dryrun)
1821 {
7622fc06 1822 log_query(crecp->flags, name, NULL, record_source(crecp->uid));
9009d746
SK
1823 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1824 crec_ttl(crecp, now), &nameoffset,
d56a604a 1825 T_CNAME, C_IN, "d", cname_target))
f6b7dc47 1826 anscount++;
fd9fa481 1827 }
f6b7dc47 1828
d56a604a
SK
1829 strcpy(name, cname_target);
1830 /* check if target interface_name */
1831 if (crecp->addr.cname.uid == -1)
1832 goto intname_restart;
1833 else
1834 goto cname_restart;
fd9fa481 1835 }
f6b7dc47 1836
9e4abcb5
SK
1837 if (crecp->flags & F_NEG)
1838 {
feba5c1d 1839 ans = 1;
f6b7dc47
SK
1840 auth = 0;
1841 if (crecp->flags & F_NXDOMAIN)
1842 nxdomain = 1;
feba5c1d 1843 if (!dryrun)
1a6bca81 1844 log_query(crecp->flags, name, NULL, NULL);
9e4abcb5 1845 }
a25720a3 1846 else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd || option_bool(OPT_DNSSEC_VALID))
9e4abcb5 1847 {
f6b7dc47
SK
1848 /* If we are returning local answers depending on network,
1849 filter here. */
1850 if (localise &&
1851 (crecp->flags & F_HOSTS) &&
1852 !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1853 continue;
1854
1855 if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1856 auth = 0;
1857
feba5c1d
SK
1858 ans = 1;
1859 if (!dryrun)
1860 {
fd9fa481 1861 log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
7622fc06 1862 record_source(crecp->uid));
feba5c1d 1863
9009d746
SK
1864 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1865 crec_ttl(crecp, now), NULL, type, C_IN,
f6b7dc47
SK
1866 type == T_A ? "4" : "6", &crecp->addr))
1867 anscount++;
feba5c1d 1868 }
9e4abcb5 1869 }
f6b7dc47 1870 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
9e4abcb5 1871 }
2bb73af7
SK
1872 else if (is_name_synthetic(flag, name, &addr))
1873 {
1874 ans = 1;
1875 if (!dryrun)
1876 {
1877 log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
1878 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1879 daemon->local_ttl, NULL, type, C_IN, type == T_A ? "4" : "6", &addr))
1880 anscount++;
1881 }
1882 }
f6b7dc47 1883 }
d1c759c5
SK
1884
1885 if (qtype == T_CNAME || qtype == T_ANY)
1886 {
1887 if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME)) &&
7b174c25 1888 (qtype == T_CNAME || (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))))
d1c759c5 1889 {
0fc2f313
SK
1890 if (!(crecp->flags & F_DNSSECOK))
1891 sec_data = 0;
1892
d1c759c5
SK
1893 ans = 1;
1894 if (!dryrun)
1895 {
1896 log_query(crecp->flags, name, NULL, record_source(crecp->uid));
1897 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1898 crec_ttl(crecp, now), &nameoffset,
d56a604a 1899 T_CNAME, C_IN, "d", cache_get_cname_target(crecp)))
d1c759c5
SK
1900 anscount++;
1901 }
1902 }
1903 }
f6b7dc47
SK
1904
1905 if (qtype == T_MX || qtype == T_ANY)
1906 {
1907 int found = 0;
0a852541
SK
1908 for (rec = daemon->mxnames; rec; rec = rec->next)
1909 if (!rec->issrv && hostname_isequal(name, rec->name))
f6b7dc47
SK
1910 {
1911 ans = found = 1;
1912 if (!dryrun)
feba5c1d 1913 {
e1ff419c 1914 int offset;
28866e95 1915 log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
0a852541
SK
1916 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1917 &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
1918 {
1919 anscount++;
1920 if (rec->target)
1921 rec->offset = offset;
1922 }
feba5c1d 1923 }
f6b7dc47
SK
1924 }
1925
28866e95 1926 if (!found && (option_bool(OPT_SELFMX) || option_bool(OPT_LOCALMX)) &&
f6b7dc47
SK
1927 cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP))
1928 {
1929 ans = 1;
1930 if (!dryrun)
1931 {
28866e95 1932 log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
f6b7dc47
SK
1933 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
1934 T_MX, C_IN, "sd", 1,
28866e95 1935 option_bool(OPT_SELFMX) ? name : daemon->mxtarget))
f6b7dc47 1936 anscount++;
9e4abcb5
SK
1937 }
1938 }
f6b7dc47
SK
1939 }
1940
1941 if (qtype == T_SRV || qtype == T_ANY)
1942 {
1943 int found = 0;
28866e95
SK
1944 struct mx_srv_record *move = NULL, **up = &daemon->mxnames;
1945
0a852541
SK
1946 for (rec = daemon->mxnames; rec; rec = rec->next)
1947 if (rec->issrv && hostname_isequal(name, rec->name))
f6b7dc47
SK
1948 {
1949 found = ans = 1;
1950 if (!dryrun)
1951 {
e1ff419c 1952 int offset;
28866e95 1953 log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>");
f6b7dc47 1954 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
0a852541
SK
1955 &offset, T_SRV, C_IN, "sssd",
1956 rec->priority, rec->weight, rec->srvport, rec->target))
1957 {
1958 anscount++;
1959 if (rec->target)
1960 rec->offset = offset;
1961 }
f6b7dc47 1962 }
28866e95
SK
1963
1964 /* unlink first SRV record found */
1965 if (!move)
1966 {
1967 move = rec;
1968 *up = rec->next;
1969 }
1970 else
1971 up = &rec->next;
f6b7dc47 1972 }
28866e95
SK
1973 else
1974 up = &rec->next;
1975
1976 /* put first SRV record back at the end. */
1977 if (move)
1978 {
1979 *up = move;
1980 move->next = NULL;
1981 }
feba5c1d 1982
28866e95 1983 if (!found && option_bool(OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
f6b7dc47
SK
1984 {
1985 ans = 1;
1986 if (!dryrun)
1a6bca81 1987 log_query(F_CONFIG | F_NEG, name, NULL, NULL);
f6b7dc47
SK
1988 }
1989 }
1a6bca81
SK
1990
1991 if (qtype == T_NAPTR || qtype == T_ANY)
1992 {
1993 struct naptr *na;
1994 for (na = daemon->naptr; na; na = na->next)
1995 if (hostname_isequal(name, na->name))
1996 {
1997 ans = 1;
1998 if (!dryrun)
1999 {
28866e95 2000 log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>");
1a6bca81
SK
2001 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
2002 NULL, T_NAPTR, C_IN, "sszzzd",
2003 na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
2004 anscount++;
2005 }
2006 }
2007 }
f6b7dc47
SK
2008
2009 if (qtype == T_MAILB)
2010 ans = 1, nxdomain = 1;
2011
28866e95 2012 if (qtype == T_SOA && option_bool(OPT_FILTER))
f6b7dc47
SK
2013 {
2014 ans = 1;
2015 if (!dryrun)
1a6bca81 2016 log_query(F_CONFIG | F_NEG, name, &addr, NULL);
feba5c1d 2017 }
9e4abcb5 2018 }
f6b7dc47
SK
2019
2020 if (!ans)
9e4abcb5 2021 return 0; /* failed to answer a question */
feba5c1d 2022 }
f6b7dc47 2023
feba5c1d
SK
2024 if (dryrun)
2025 {
2026 dryrun = 0;
2027 goto rerun;
9e4abcb5
SK
2028 }
2029
0a852541
SK
2030 /* create an additional data section, for stuff in SRV and MX record replies. */
2031 for (rec = daemon->mxnames; rec; rec = rec->next)
2032 if (rec->offset != 0)
2033 {
2034 /* squash dupes */
2035 struct mx_srv_record *tmp;
2036 for (tmp = rec->next; tmp; tmp = tmp->next)
2037 if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
2038 tmp->offset = 0;
2039
2040 crecp = NULL;
2041 while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
2042 {
0a852541
SK
2043#ifdef HAVE_IPV6
2044 int type = crecp->flags & F_IPV4 ? T_A : T_AAAA;
2045#else
2046 int type = T_A;
2047#endif
2048 if (crecp->flags & F_NEG)
2049 continue;
2050
9009d746
SK
2051 if (add_resource_record(header, limit, NULL, rec->offset, &ansp,
2052 crec_ttl(crecp, now), NULL, type, C_IN,
0a852541
SK
2053 crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
2054 addncount++;
2055 }
2056 }
2057
9e4abcb5 2058 /* done all questions, set up header and return length of result */
572b41eb
SK
2059 /* clear authoritative and truncated flags, set QR flag */
2060 header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
2061 /* set RA flag */
2062 header->hb4 |= HB4_RA;
2063
2064 /* authoritive - only hosts and DHCP derived names. */
2065 if (auth)
2066 header->hb3 |= HB3_AA;
2067
2068 /* truncation */
2069 if (trunc)
2070 header->hb3 |= HB3_TC;
0fc2f313 2071
45cca585 2072 if (nxdomain)
572b41eb 2073 SET_RCODE(header, NXDOMAIN);
9e4abcb5 2074 else
572b41eb 2075 SET_RCODE(header, NOERROR); /* no error */
9e4abcb5
SK
2076 header->ancount = htons(anscount);
2077 header->nscount = htons(0);
0a852541 2078 header->arcount = htons(addncount);
a25720a3
SK
2079
2080 header->hb4 &= ~HB4_AD;
2081 len = ansp - (unsigned char *)header;
2082
2083 if (have_pseudoheader)
2084 {
2085 len = add_pseudoheader(header, len, (unsigned char *)limit, 0, NULL, 0, sec_reqd);
2086 if (sec_reqd && sec_data)
2087 header->hb4 |= HB4_AD;
2088
2089 }
2090
2091 return len ;
9e4abcb5
SK
2092}
2093