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