]> git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/rfc1035.c
a95241f83523c0c5c1c31da79991bcbfbf879ff8
[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+7/8/9 chars */
98 namelen += digs+7;
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 + 1; /* include period */
129 if (namelen >= 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(SAFE_PKTSZ, p); /* max packet length, this will be overwritten */
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 {
1122 if ((flags & F_IPV4) &&
1123 private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
1124 return 1;
1125
1126 #ifdef HAVE_IPV6
1127 if ((flags & F_IPV6) &&
1128 IN6_IS_ADDR_V4MAPPED(&addr.addr.addr6))
1129 {
1130 struct in_addr v4;
1131 v4.s_addr = ((const uint32_t *) (&addr.addr.addr6))[3];
1132 if (private_net(v4, !option_bool(OPT_LOCAL_REBIND)))
1133 return 1;
1134 }
1135 #endif
1136 }
1137
1138 #ifdef HAVE_IPSET
1139 if (ipsets && (flags & (F_IPV4 | F_IPV6)))
1140 {
1141 ipsets_cur = ipsets;
1142 while (*ipsets_cur)
1143 {
1144 log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur);
1145 add_to_ipset(*ipsets_cur++, &addr, flags, 0);
1146 }
1147 }
1148 #endif
1149
1150 newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD | secflag);
1151 if (newc && cpp)
1152 {
1153 cpp->addr.cname.target.cache = newc;
1154 cpp->addr.cname.uid = newc->uid;
1155 }
1156 cpp = NULL;
1157 }
1158 }
1159
1160 p1 = endrr;
1161 if (!CHECK_LEN(header, p1, qlen, 0))
1162 return 0; /* bad packet */
1163 }
1164
1165 if (!found && !option_bool(OPT_NO_NEG))
1166 {
1167 if (!searched_soa)
1168 {
1169 searched_soa = 1;
1170 ttl = find_soa(header, qlen, NULL, doctored);
1171 }
1172 /* If there's no SOA to get the TTL from, but there is a CNAME
1173 pointing at this, inherit its TTL */
1174 if (ttl || cpp)
1175 {
1176 newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | secflag);
1177 if (newc && cpp)
1178 {
1179 cpp->addr.cname.target.cache = newc;
1180 cpp->addr.cname.uid = newc->uid;
1181 }
1182 }
1183 }
1184 }
1185 }
1186
1187 /* Don't put stuff from a truncated packet into the cache.
1188 Don't cache replies from non-recursive nameservers, since we may get a
1189 reply containing a CNAME but not its target, even though the target
1190 does exist. */
1191 if (!(header->hb3 & HB3_TC) &&
1192 !(header->hb4 & HB4_CD) &&
1193 (header->hb4 & HB4_RA) &&
1194 !no_cache_dnssec)
1195 cache_end_insert();
1196
1197 return 0;
1198 }
1199
1200 /* If the packet holds exactly one query
1201 return F_IPV4 or F_IPV6 and leave the name from the query in name */
1202 unsigned int extract_request(struct dns_header *header, size_t qlen, char *name, unsigned short *typep)
1203 {
1204 unsigned char *p = (unsigned char *)(header+1);
1205 int qtype, qclass;
1206
1207 if (typep)
1208 *typep = 0;
1209
1210 if (ntohs(header->qdcount) != 1 || OPCODE(header) != QUERY)
1211 return 0; /* must be exactly one query. */
1212
1213 if (!extract_name(header, qlen, &p, name, 1, 4))
1214 return 0; /* bad packet */
1215
1216 GETSHORT(qtype, p);
1217 GETSHORT(qclass, p);
1218
1219 if (typep)
1220 *typep = qtype;
1221
1222 if (qclass == C_IN)
1223 {
1224 if (qtype == T_A)
1225 return F_IPV4;
1226 if (qtype == T_AAAA)
1227 return F_IPV6;
1228 if (qtype == T_ANY)
1229 return F_IPV4 | F_IPV6;
1230 }
1231
1232 return F_QUERY;
1233 }
1234
1235
1236 size_t setup_reply(struct dns_header *header, size_t qlen,
1237 struct all_addr *addrp, unsigned int flags, unsigned long ttl)
1238 {
1239 unsigned char *p;
1240
1241 if (!(p = skip_questions(header, qlen)))
1242 return 0;
1243
1244 /* clear authoritative and truncated flags, set QR flag */
1245 header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
1246 /* set RA flag */
1247 header->hb4 |= HB4_RA;
1248
1249 header->nscount = htons(0);
1250 header->arcount = htons(0);
1251 header->ancount = htons(0); /* no answers unless changed below */
1252 if (flags == F_NEG)
1253 SET_RCODE(header, SERVFAIL); /* couldn't get memory */
1254 else if (flags == F_NOERR)
1255 SET_RCODE(header, NOERROR); /* empty domain */
1256 else if (flags == F_NXDOMAIN)
1257 SET_RCODE(header, NXDOMAIN);
1258 else if (flags == F_IPV4)
1259 { /* we know the address */
1260 SET_RCODE(header, NOERROR);
1261 header->ancount = htons(1);
1262 header->hb3 |= HB3_AA;
1263 add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_A, C_IN, "4", addrp);
1264 }
1265 #ifdef HAVE_IPV6
1266 else if (flags == F_IPV6)
1267 {
1268 SET_RCODE(header, NOERROR);
1269 header->ancount = htons(1);
1270 header->hb3 |= HB3_AA;
1271 add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
1272 }
1273 #endif
1274 else /* nowhere to forward to */
1275 SET_RCODE(header, REFUSED);
1276
1277 return p - (unsigned char *)header;
1278 }
1279
1280 /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
1281 int check_for_local_domain(char *name, time_t now)
1282 {
1283 struct crec *crecp;
1284 struct mx_srv_record *mx;
1285 struct txt_record *txt;
1286 struct interface_name *intr;
1287 struct ptr_record *ptr;
1288 struct naptr *naptr;
1289
1290 /* Note: the call to cache_find_by_name is intended to find any record which matches
1291 ie A, AAAA, CNAME, DS. Because RRSIG records are marked by setting both F_DS and F_DNSKEY,
1292 cache_find_by name ordinarily only returns records with an exact match on those bits (ie
1293 for the call below, only DS records). The F_NSIGMATCH bit changes this behaviour */
1294
1295 if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME | F_DS | F_NO_RR | F_NSIGMATCH)) &&
1296 (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
1297 return 1;
1298
1299 for (naptr = daemon->naptr; naptr; naptr = naptr->next)
1300 if (hostname_isequal(name, naptr->name))
1301 return 1;
1302
1303 for (mx = daemon->mxnames; mx; mx = mx->next)
1304 if (hostname_isequal(name, mx->name))
1305 return 1;
1306
1307 for (txt = daemon->txt; txt; txt = txt->next)
1308 if (hostname_isequal(name, txt->name))
1309 return 1;
1310
1311 for (intr = daemon->int_names; intr; intr = intr->next)
1312 if (hostname_isequal(name, intr->name))
1313 return 1;
1314
1315 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1316 if (hostname_isequal(name, ptr->name))
1317 return 1;
1318
1319 return 0;
1320 }
1321
1322 /* Is the packet a reply with the answer address equal to addr?
1323 If so mung is into an NXDOMAIN reply and also put that information
1324 in the cache. */
1325 int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
1326 struct bogus_addr *baddr, time_t now)
1327 {
1328 unsigned char *p;
1329 int i, qtype, qclass, rdlen;
1330 unsigned long ttl;
1331 struct bogus_addr *baddrp;
1332
1333 /* skip over questions */
1334 if (!(p = skip_questions(header, qlen)))
1335 return 0; /* bad packet */
1336
1337 for (i = ntohs(header->ancount); i != 0; i--)
1338 {
1339 if (!extract_name(header, qlen, &p, name, 1, 10))
1340 return 0; /* bad packet */
1341
1342 GETSHORT(qtype, p);
1343 GETSHORT(qclass, p);
1344 GETLONG(ttl, p);
1345 GETSHORT(rdlen, p);
1346
1347 if (qclass == C_IN && qtype == T_A)
1348 {
1349 if (!CHECK_LEN(header, p, qlen, INADDRSZ))
1350 return 0;
1351
1352 for (baddrp = baddr; baddrp; baddrp = baddrp->next)
1353 if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
1354 {
1355 /* Found a bogus address. Insert that info here, since there no SOA record
1356 to get the ttl from in the normal processing */
1357 cache_start_insert();
1358 cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
1359 cache_end_insert();
1360
1361 return 1;
1362 }
1363 }
1364
1365 if (!ADD_RDLEN(header, p, qlen, rdlen))
1366 return 0;
1367 }
1368
1369 return 0;
1370 }
1371
1372 int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr)
1373 {
1374 unsigned char *p;
1375 int i, qtype, qclass, rdlen;
1376 struct bogus_addr *baddrp;
1377
1378 /* skip over questions */
1379 if (!(p = skip_questions(header, qlen)))
1380 return 0; /* bad packet */
1381
1382 for (i = ntohs(header->ancount); i != 0; i--)
1383 {
1384 if (!(p = skip_name(p, header, qlen, 10)))
1385 return 0; /* bad packet */
1386
1387 GETSHORT(qtype, p);
1388 GETSHORT(qclass, p);
1389 p += 4; /* TTL */
1390 GETSHORT(rdlen, p);
1391
1392 if (qclass == C_IN && qtype == T_A)
1393 {
1394 if (!CHECK_LEN(header, p, qlen, INADDRSZ))
1395 return 0;
1396
1397 for (baddrp = baddr; baddrp; baddrp = baddrp->next)
1398 if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
1399 return 1;
1400 }
1401
1402 if (!ADD_RDLEN(header, p, qlen, rdlen))
1403 return 0;
1404 }
1405
1406 return 0;
1407 }
1408
1409 int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp,
1410 unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
1411 {
1412 va_list ap;
1413 unsigned char *sav, *p = *pp;
1414 int j;
1415 unsigned short usval;
1416 long lval;
1417 char *sval;
1418
1419 if (truncp && *truncp)
1420 return 0;
1421
1422 va_start(ap, format); /* make ap point to 1st unamed argument */
1423
1424 if (nameoffset > 0)
1425 {
1426 PUTSHORT(nameoffset | 0xc000, p);
1427 }
1428 else
1429 {
1430 char *name = va_arg(ap, char *);
1431 if (name)
1432 p = do_rfc1035_name(p, name);
1433 if (nameoffset < 0)
1434 {
1435 PUTSHORT(-nameoffset | 0xc000, p);
1436 }
1437 else
1438 *p++ = 0;
1439 }
1440
1441 PUTSHORT(type, p);
1442 PUTSHORT(class, p);
1443 PUTLONG(ttl, p); /* TTL */
1444
1445 sav = p; /* Save pointer to RDLength field */
1446 PUTSHORT(0, p); /* Placeholder RDLength */
1447
1448 for (; *format; format++)
1449 switch (*format)
1450 {
1451 #ifdef HAVE_IPV6
1452 case '6':
1453 sval = va_arg(ap, char *);
1454 memcpy(p, sval, IN6ADDRSZ);
1455 p += IN6ADDRSZ;
1456 break;
1457 #endif
1458
1459 case '4':
1460 sval = va_arg(ap, char *);
1461 memcpy(p, sval, INADDRSZ);
1462 p += INADDRSZ;
1463 break;
1464
1465 case 'b':
1466 usval = va_arg(ap, int);
1467 *p++ = usval;
1468 break;
1469
1470 case 's':
1471 usval = va_arg(ap, int);
1472 PUTSHORT(usval, p);
1473 break;
1474
1475 case 'l':
1476 lval = va_arg(ap, long);
1477 PUTLONG(lval, p);
1478 break;
1479
1480 case 'd':
1481 /* get domain-name answer arg and store it in RDATA field */
1482 if (offset)
1483 *offset = p - (unsigned char *)header;
1484 p = do_rfc1035_name(p, va_arg(ap, char *));
1485 *p++ = 0;
1486 break;
1487
1488 case 't':
1489 usval = va_arg(ap, int);
1490 sval = va_arg(ap, char *);
1491 if (usval != 0)
1492 memcpy(p, sval, usval);
1493 p += usval;
1494 break;
1495
1496 case 'z':
1497 sval = va_arg(ap, char *);
1498 usval = sval ? strlen(sval) : 0;
1499 if (usval > 255)
1500 usval = 255;
1501 *p++ = (unsigned char)usval;
1502 memcpy(p, sval, usval);
1503 p += usval;
1504 break;
1505 }
1506
1507 va_end(ap); /* clean up variable argument pointer */
1508
1509 j = p - sav - 2;
1510 PUTSHORT(j, sav); /* Now, store real RDLength */
1511
1512 /* check for overflow of buffer */
1513 if (limit && ((unsigned char *)limit - p) < 0)
1514 {
1515 if (truncp)
1516 *truncp = 1;
1517 return 0;
1518 }
1519
1520 *pp = p;
1521 return 1;
1522 }
1523
1524 static unsigned long crec_ttl(struct crec *crecp, time_t now)
1525 {
1526 /* Return 0 ttl for DHCP entries, which might change
1527 before the lease expires. */
1528
1529 if (crecp->flags & (F_IMMORTAL | F_DHCP))
1530 return daemon->local_ttl;
1531
1532 /* Return the Max TTL value if it is lower then the actual TTL */
1533 if (daemon->max_ttl == 0 || ((unsigned)(crecp->ttd - now) < daemon->max_ttl))
1534 return crecp->ttd - now;
1535 else
1536 return daemon->max_ttl;
1537 }
1538
1539
1540 /* return zero if we can't answer from cache, or packet size if we can */
1541 size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
1542 struct in_addr local_addr, struct in_addr local_netmask,
1543 time_t now, int *ad_reqd, int *do_bit)
1544 {
1545 char *name = daemon->namebuff;
1546 unsigned char *p, *ansp, *pheader;
1547 unsigned int qtype, qclass;
1548 struct all_addr addr;
1549 int nameoffset;
1550 unsigned short flag;
1551 int q, ans, anscount = 0, addncount = 0;
1552 int dryrun = 0, sec_reqd = 0, have_pseudoheader = 0;
1553 struct crec *crecp;
1554 int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1;
1555 struct mx_srv_record *rec;
1556 size_t len;
1557
1558 /* Don't return AD set if checking disabled. */
1559 if (header->hb4 & HB4_CD)
1560 sec_data = 0;
1561
1562 /* RFC 6840 5.7 */
1563 *ad_reqd = header->hb4 & HB4_AD;
1564 *do_bit = 0;
1565
1566 /* If there is an RFC2671 pseudoheader then it will be overwritten by
1567 partial replies, so we have to do a dry run to see if we can answer
1568 the query. We check to see if the do bit is set, if so we always
1569 forward rather than answering from the cache, which doesn't include
1570 security information, unless we're in DNSSEC validation mode. */
1571
1572 if (find_pseudoheader(header, qlen, NULL, &pheader, NULL))
1573 {
1574 unsigned short flags;
1575
1576 have_pseudoheader = 1;
1577
1578 pheader += 4; /* udp size, ext_rcode */
1579 GETSHORT(flags, pheader);
1580
1581 if ((sec_reqd = flags & 0x8000))
1582 *do_bit = 1;/* do bit */
1583
1584 *ad_reqd = 1;
1585 dryrun = 1;
1586 }
1587
1588 if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
1589 return 0;
1590
1591 for (rec = daemon->mxnames; rec; rec = rec->next)
1592 rec->offset = 0;
1593
1594 rerun:
1595 /* determine end of question section (we put answers there) */
1596 if (!(ansp = skip_questions(header, qlen)))
1597 return 0; /* bad packet */
1598
1599 /* now process each question, answers go in RRs after the question */
1600 p = (unsigned char *)(header+1);
1601
1602 for (q = ntohs(header->qdcount); q != 0; q--)
1603 {
1604 /* save pointer to name for copying into answers */
1605 nameoffset = p - (unsigned char *)header;
1606
1607 /* now extract name as .-concatenated string into name */
1608 if (!extract_name(header, qlen, &p, name, 1, 4))
1609 return 0; /* bad packet */
1610
1611 GETSHORT(qtype, p);
1612 GETSHORT(qclass, p);
1613
1614 /* Don't filter RRSIGS from answers to ANY queries, even if do-bit
1615 not set. */
1616 if (qtype == T_ANY)
1617 *do_bit = 1;
1618
1619 ans = 0; /* have we answered this question */
1620
1621 if (qtype == T_TXT || qtype == T_ANY)
1622 {
1623 struct txt_record *t;
1624 for(t = daemon->txt; t ; t = t->next)
1625 {
1626 if (t->class == qclass && hostname_isequal(name, t->name))
1627 {
1628 ans = 1;
1629 if (!dryrun)
1630 {
1631 unsigned long ttl = daemon->local_ttl;
1632 int ok = 1;
1633 log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
1634 /* Dynamically generate stat record */
1635 if (t->stat != 0)
1636 {
1637 ttl = 0;
1638 if (!cache_make_stat(t))
1639 ok = 0;
1640 }
1641
1642 if (ok && add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1643 ttl, NULL,
1644 T_TXT, t->class, "t", t->len, t->txt))
1645 anscount++;
1646
1647 }
1648 }
1649 }
1650 }
1651
1652 #ifdef HAVE_DNSSEC
1653 if (option_bool(OPT_DNSSEC_VALID) && (qtype == T_DNSKEY || qtype == T_DS))
1654 {
1655 int gotone = 0;
1656 struct blockdata *keydata;
1657
1658 /* Do we have RRSIG? Can't do DS or DNSKEY otherwise. */
1659 if (sec_reqd)
1660 {
1661 crecp = NULL;
1662 while ((crecp = cache_find_by_name(crecp, name, now, F_DNSKEY | F_DS)))
1663 if (crecp->uid == qclass && crecp->addr.sig.type_covered == qtype)
1664 break;
1665 }
1666
1667 if (!sec_reqd || crecp)
1668 {
1669 if (qtype == T_DS)
1670 {
1671 crecp = NULL;
1672 while ((crecp = cache_find_by_name(crecp, name, now, F_DS)))
1673 if (crecp->uid == qclass)
1674 {
1675 gotone = 1;
1676 if (!dryrun)
1677 {
1678 if (crecp->flags & F_NEG)
1679 {
1680 if (crecp->flags & F_NXDOMAIN)
1681 nxdomain = 1;
1682 log_query(F_UPSTREAM, name, NULL, "no DS");
1683 }
1684 else if ((keydata = blockdata_retrieve(crecp->addr.ds.keydata, crecp->addr.ds.keylen, NULL)))
1685 {
1686 struct all_addr a;
1687 a.addr.keytag = crecp->addr.ds.keytag;
1688 log_query(F_KEYTAG | (crecp->flags & F_CONFIG), name, &a, "DS keytag %u");
1689 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1690 crec_ttl(crecp, now), &nameoffset,
1691 T_DS, qclass, "sbbt",
1692 crecp->addr.ds.keytag, crecp->addr.ds.algo,
1693 crecp->addr.ds.digest, crecp->addr.ds.keylen, keydata))
1694 anscount++;
1695
1696 }
1697 }
1698 }
1699 }
1700 else /* DNSKEY */
1701 {
1702 crecp = NULL;
1703 while ((crecp = cache_find_by_name(crecp, name, now, F_DNSKEY)))
1704 if (crecp->uid == qclass)
1705 {
1706 gotone = 1;
1707 if (!dryrun && (keydata = blockdata_retrieve(crecp->addr.key.keydata, crecp->addr.key.keylen, NULL)))
1708 {
1709 struct all_addr a;
1710 a.addr.keytag = crecp->addr.key.keytag;
1711 log_query(F_KEYTAG | (crecp->flags & F_CONFIG), name, &a, "DNSKEY keytag %u");
1712 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1713 crec_ttl(crecp, now), &nameoffset,
1714 T_DNSKEY, qclass, "sbbt",
1715 crecp->addr.key.flags, 3, crecp->addr.key.algo, crecp->addr.key.keylen, keydata))
1716 anscount++;
1717 }
1718 }
1719 }
1720 }
1721
1722 /* Now do RRSIGs */
1723 if (gotone)
1724 {
1725 ans = 1;
1726 auth = 0;
1727 if (!dryrun && sec_reqd)
1728 {
1729 crecp = NULL;
1730 while ((crecp = cache_find_by_name(crecp, name, now, F_DNSKEY | F_DS)))
1731 if (crecp->uid == qclass && crecp->addr.sig.type_covered == qtype &&
1732 (keydata = blockdata_retrieve(crecp->addr.sig.keydata, crecp->addr.sig.keylen, NULL)))
1733 {
1734 add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1735 crec_ttl(crecp, now), &nameoffset,
1736 T_RRSIG, qclass, "t", crecp->addr.sig.keylen, keydata);
1737 anscount++;
1738 }
1739 }
1740 }
1741 }
1742 #endif
1743
1744 if (qclass == C_IN)
1745 {
1746 struct txt_record *t;
1747
1748 for (t = daemon->rr; t; t = t->next)
1749 if ((t->class == qtype || qtype == T_ANY) && hostname_isequal(name, t->name))
1750 {
1751 ans = 1;
1752 if (!dryrun)
1753 {
1754 log_query(F_CONFIG | F_RRNAME, name, NULL, "<RR>");
1755 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1756 daemon->local_ttl, NULL,
1757 t->class, C_IN, "t", t->len, t->txt))
1758 anscount ++;
1759 }
1760 }
1761
1762 if (qtype == T_PTR || qtype == T_ANY)
1763 {
1764 /* see if it's w.z.y.z.in-addr.arpa format */
1765 int is_arpa = in_arpa_name_2_addr(name, &addr);
1766 struct ptr_record *ptr;
1767 struct interface_name* intr = NULL;
1768
1769 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1770 if (hostname_isequal(name, ptr->name))
1771 break;
1772
1773 if (is_arpa == F_IPV4)
1774 for (intr = daemon->int_names; intr; intr = intr->next)
1775 {
1776 struct addrlist *addrlist;
1777
1778 for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1779 if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
1780 break;
1781
1782 if (addrlist)
1783 break;
1784 else
1785 while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1786 intr = intr->next;
1787 }
1788 #ifdef HAVE_IPV6
1789 else if (is_arpa == F_IPV6)
1790 for (intr = daemon->int_names; intr; intr = intr->next)
1791 {
1792 struct addrlist *addrlist;
1793
1794 for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1795 if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
1796 break;
1797
1798 if (addrlist)
1799 break;
1800 else
1801 while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1802 intr = intr->next;
1803 }
1804 #endif
1805
1806 if (intr)
1807 {
1808 ans = 1;
1809 if (!dryrun)
1810 {
1811 log_query(is_arpa | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
1812 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1813 daemon->local_ttl, NULL,
1814 T_PTR, C_IN, "d", intr->name))
1815 anscount++;
1816 }
1817 }
1818 else if (ptr)
1819 {
1820 ans = 1;
1821 if (!dryrun)
1822 {
1823 log_query(F_CONFIG | F_RRNAME, name, NULL, "<PTR>");
1824 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1825 if (hostname_isequal(name, ptr->name) &&
1826 add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1827 daemon->local_ttl, NULL,
1828 T_PTR, C_IN, "d", ptr->ptr))
1829 anscount++;
1830
1831 }
1832 }
1833 else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
1834 {
1835 if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && sec_reqd)
1836 {
1837 if (!option_bool(OPT_DNSSEC_VALID) || ((crecp->flags & F_NEG) && (crecp->flags & F_DNSSECOK)))
1838 crecp = NULL;
1839 #ifdef HAVE_DNSSEC
1840 else if (crecp->flags & F_DNSSECOK)
1841 {
1842 int gotsig = 0;
1843 struct crec *rr_crec = NULL;
1844
1845 while ((rr_crec = cache_find_by_name(rr_crec, name, now, F_DS | F_DNSKEY)))
1846 {
1847 if (rr_crec->addr.sig.type_covered == T_PTR && rr_crec->uid == C_IN)
1848 {
1849 char *sigdata = blockdata_retrieve(rr_crec->addr.sig.keydata, rr_crec->addr.sig.keylen, NULL);
1850 gotsig = 1;
1851
1852 if (!dryrun &&
1853 add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1854 rr_crec->ttd - now, &nameoffset,
1855 T_RRSIG, C_IN, "t", crecp->addr.sig.keylen, sigdata))
1856 anscount++;
1857 }
1858 }
1859
1860 if (!gotsig)
1861 crecp = NULL;
1862 }
1863 #endif
1864 }
1865
1866 if (crecp)
1867 {
1868 do
1869 {
1870 /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
1871 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1872 continue;
1873
1874 if (!(crecp->flags & F_DNSSECOK))
1875 sec_data = 0;
1876
1877 if (crecp->flags & F_NEG)
1878 {
1879 ans = 1;
1880 auth = 0;
1881 if (crecp->flags & F_NXDOMAIN)
1882 nxdomain = 1;
1883 if (!dryrun)
1884 log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
1885 }
1886 else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd || option_bool(OPT_DNSSEC_VALID))
1887 {
1888 ans = 1;
1889 if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1890 auth = 0;
1891 if (!dryrun)
1892 {
1893 log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
1894 record_source(crecp->uid));
1895
1896 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1897 crec_ttl(crecp, now), NULL,
1898 T_PTR, C_IN, "d", cache_get_name(crecp)))
1899 anscount++;
1900 }
1901 }
1902 } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
1903 }
1904 }
1905 else if (is_rev_synth(is_arpa, &addr, name))
1906 {
1907 ans = 1;
1908 if (!dryrun)
1909 {
1910 log_query(F_CONFIG | F_REVERSE | is_arpa, name, &addr, NULL);
1911
1912 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1913 daemon->local_ttl, NULL,
1914 T_PTR, C_IN, "d", name))
1915 anscount++;
1916 }
1917 }
1918 else if (is_arpa == F_IPV4 &&
1919 option_bool(OPT_BOGUSPRIV) &&
1920 private_net(addr.addr.addr4, 1))
1921 {
1922 /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
1923 ans = 1;
1924 nxdomain = 1;
1925 if (!dryrun)
1926 log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN,
1927 name, &addr, NULL);
1928 }
1929 }
1930
1931 for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
1932 {
1933 unsigned short type = T_A;
1934 struct interface_name *intr;
1935
1936 if (flag == F_IPV6)
1937 #ifdef HAVE_IPV6
1938 type = T_AAAA;
1939 #else
1940 break;
1941 #endif
1942
1943 if (qtype != type && qtype != T_ANY)
1944 continue;
1945
1946 /* Check for "A for A" queries; be rather conservative
1947 about what looks like dotted-quad. */
1948 if (qtype == T_A)
1949 {
1950 char *cp;
1951 unsigned int i, a;
1952 int x;
1953
1954 for (cp = name, i = 0, a = 0; *cp; i++)
1955 {
1956 if (!isdigit((unsigned char)*cp) || (x = strtol(cp, &cp, 10)) > 255)
1957 {
1958 i = 5;
1959 break;
1960 }
1961
1962 a = (a << 8) + x;
1963
1964 if (*cp == '.')
1965 cp++;
1966 }
1967
1968 if (i == 4)
1969 {
1970 ans = 1;
1971 if (!dryrun)
1972 {
1973 addr.addr.addr4.s_addr = htonl(a);
1974 log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
1975 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1976 daemon->local_ttl, NULL, type, C_IN, "4", &addr))
1977 anscount++;
1978 }
1979 continue;
1980 }
1981 }
1982
1983 /* interface name stuff */
1984 intname_restart:
1985 for (intr = daemon->int_names; intr; intr = intr->next)
1986 if (hostname_isequal(name, intr->name))
1987 break;
1988
1989 if (intr)
1990 {
1991 struct addrlist *addrlist;
1992 int gotit = 0;
1993
1994 enumerate_interfaces(0);
1995
1996 for (intr = daemon->int_names; intr; intr = intr->next)
1997 if (hostname_isequal(name, intr->name))
1998 {
1999 for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
2000 #ifdef HAVE_IPV6
2001 if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
2002 #endif
2003 {
2004 #ifdef HAVE_IPV6
2005 if (addrlist->flags & ADDRLIST_REVONLY)
2006 continue;
2007 #endif
2008 ans = 1;
2009 if (!dryrun)
2010 {
2011 gotit = 1;
2012 log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
2013 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
2014 daemon->local_ttl, NULL, type, C_IN,
2015 type == T_A ? "4" : "6", &addrlist->addr))
2016 anscount++;
2017 }
2018 }
2019 }
2020
2021 if (!dryrun && !gotit)
2022 log_query(F_FORWARD | F_CONFIG | flag | F_NEG, name, NULL, NULL);
2023
2024 continue;
2025 }
2026
2027 cname_restart:
2028 if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME | (dryrun ? F_NO_RR : 0))))
2029 {
2030 int localise = 0;
2031
2032 /* See if a putative address is on the network from which we recieved
2033 the query, is so we'll filter other answers. */
2034 if (local_addr.s_addr != 0 && option_bool(OPT_LOCALISE) && flag == F_IPV4)
2035 {
2036 struct crec *save = crecp;
2037 do {
2038 if ((crecp->flags & F_HOSTS) &&
2039 is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
2040 {
2041 localise = 1;
2042 break;
2043 }
2044 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
2045 crecp = save;
2046 }
2047
2048 /* If the client asked for DNSSEC and we can't provide RRSIGs, either
2049 because we've not doing DNSSEC or the cached answer is signed by negative,
2050 don't answer from the cache, forward instead. */
2051 if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && sec_reqd)
2052 {
2053 if (!option_bool(OPT_DNSSEC_VALID) || ((crecp->flags & F_NEG) && (crecp->flags & F_DNSSECOK)))
2054 crecp = NULL;
2055 #ifdef HAVE_DNSSEC
2056 else if (crecp->flags & F_DNSSECOK)
2057 {
2058 /* We're returning validated data, need to return the RRSIG too. */
2059 struct crec *rr_crec = NULL;
2060 int sigtype = type;
2061 /* The signature may have expired even though the data is still in cache,
2062 forward instead of answering from cache if so. */
2063 int gotsig = 0;
2064
2065 if (crecp->flags & F_CNAME)
2066 sigtype = T_CNAME;
2067
2068 while ((rr_crec = cache_find_by_name(rr_crec, name, now, F_DS | F_DNSKEY)))
2069 {
2070 if (rr_crec->addr.sig.type_covered == sigtype && rr_crec->uid == C_IN)
2071 {
2072 char *sigdata = blockdata_retrieve(rr_crec->addr.sig.keydata, rr_crec->addr.sig.keylen, NULL);
2073 gotsig = 1;
2074
2075 if (!dryrun &&
2076 add_resource_record(header, limit, &trunc, nameoffset, &ansp,
2077 rr_crec->ttd - now, &nameoffset,
2078 T_RRSIG, C_IN, "t", rr_crec->addr.sig.keylen, sigdata))
2079 anscount++;
2080 }
2081 }
2082
2083 if (!gotsig)
2084 crecp = NULL;
2085 }
2086 #endif
2087 }
2088
2089 if (crecp)
2090 do
2091 {
2092 /* don't answer wildcard queries with data not from /etc/hosts
2093 or DHCP leases */
2094 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
2095 break;
2096
2097 if (!(crecp->flags & F_DNSSECOK))
2098 sec_data = 0;
2099
2100 if (crecp->flags & F_CNAME)
2101 {
2102 char *cname_target = cache_get_cname_target(crecp);
2103
2104 if (!dryrun)
2105 {
2106 log_query(crecp->flags, name, NULL, record_source(crecp->uid));
2107 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
2108 crec_ttl(crecp, now), &nameoffset,
2109 T_CNAME, C_IN, "d", cname_target))
2110 anscount++;
2111 }
2112
2113 strcpy(name, cname_target);
2114 /* check if target interface_name */
2115 if (crecp->addr.cname.uid == SRC_INTERFACE)
2116 goto intname_restart;
2117 else
2118 goto cname_restart;
2119 }
2120
2121 if (crecp->flags & F_NEG)
2122 {
2123 /* We don't cache NSEC records, so if a DNSSEC-validated negative answer
2124 is cached and the client wants DNSSEC, forward rather than answering from the cache */
2125 if (!sec_reqd || !(crecp->flags & F_DNSSECOK))
2126 {
2127 ans = 1;
2128 auth = 0;
2129 if (crecp->flags & F_NXDOMAIN)
2130 nxdomain = 1;
2131 if (!dryrun)
2132 log_query(crecp->flags, name, NULL, NULL);
2133 }
2134 }
2135 else
2136 {
2137 /* If we are returning local answers depending on network,
2138 filter here. */
2139 if (localise &&
2140 (crecp->flags & F_HOSTS) &&
2141 !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
2142 continue;
2143
2144 if (!(crecp->flags & (F_HOSTS | F_DHCP)))
2145 auth = 0;
2146
2147 ans = 1;
2148 if (!dryrun)
2149 {
2150 log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
2151 record_source(crecp->uid));
2152
2153 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
2154 crec_ttl(crecp, now), NULL, type, C_IN,
2155 type == T_A ? "4" : "6", &crecp->addr))
2156 anscount++;
2157 }
2158 }
2159 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
2160 }
2161 else if (is_name_synthetic(flag, name, &addr))
2162 {
2163 ans = 1;
2164 if (!dryrun)
2165 {
2166 log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
2167 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
2168 daemon->local_ttl, NULL, type, C_IN, type == T_A ? "4" : "6", &addr))
2169 anscount++;
2170 }
2171 }
2172 }
2173
2174 if (qtype == T_CNAME || qtype == T_ANY)
2175 {
2176 if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME)) &&
2177 (qtype == T_CNAME || (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG | (dryrun ? F_NO_RR : 0)))))
2178 {
2179 if (!(crecp->flags & F_DNSSECOK))
2180 sec_data = 0;
2181
2182 ans = 1;
2183 if (!dryrun)
2184 {
2185 log_query(crecp->flags, name, NULL, record_source(crecp->uid));
2186 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
2187 crec_ttl(crecp, now), &nameoffset,
2188 T_CNAME, C_IN, "d", cache_get_cname_target(crecp)))
2189 anscount++;
2190 }
2191 }
2192 }
2193
2194 if (qtype == T_MX || qtype == T_ANY)
2195 {
2196 int found = 0;
2197 for (rec = daemon->mxnames; rec; rec = rec->next)
2198 if (!rec->issrv && hostname_isequal(name, rec->name))
2199 {
2200 ans = found = 1;
2201 if (!dryrun)
2202 {
2203 int offset;
2204 log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
2205 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
2206 &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
2207 {
2208 anscount++;
2209 if (rec->target)
2210 rec->offset = offset;
2211 }
2212 }
2213 }
2214
2215 if (!found && (option_bool(OPT_SELFMX) || option_bool(OPT_LOCALMX)) &&
2216 cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP | F_NO_RR))
2217 {
2218 ans = 1;
2219 if (!dryrun)
2220 {
2221 log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
2222 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
2223 T_MX, C_IN, "sd", 1,
2224 option_bool(OPT_SELFMX) ? name : daemon->mxtarget))
2225 anscount++;
2226 }
2227 }
2228 }
2229
2230 if (qtype == T_SRV || qtype == T_ANY)
2231 {
2232 int found = 0;
2233 struct mx_srv_record *move = NULL, **up = &daemon->mxnames;
2234
2235 for (rec = daemon->mxnames; rec; rec = rec->next)
2236 if (rec->issrv && hostname_isequal(name, rec->name))
2237 {
2238 found = ans = 1;
2239 if (!dryrun)
2240 {
2241 int offset;
2242 log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>");
2243 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
2244 &offset, T_SRV, C_IN, "sssd",
2245 rec->priority, rec->weight, rec->srvport, rec->target))
2246 {
2247 anscount++;
2248 if (rec->target)
2249 rec->offset = offset;
2250 }
2251 }
2252
2253 /* unlink first SRV record found */
2254 if (!move)
2255 {
2256 move = rec;
2257 *up = rec->next;
2258 }
2259 else
2260 up = &rec->next;
2261 }
2262 else
2263 up = &rec->next;
2264
2265 /* put first SRV record back at the end. */
2266 if (move)
2267 {
2268 *up = move;
2269 move->next = NULL;
2270 }
2271
2272 if (!found && option_bool(OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
2273 {
2274 ans = 1;
2275 if (!dryrun)
2276 log_query(F_CONFIG | F_NEG, name, NULL, NULL);
2277 }
2278 }
2279
2280 if (qtype == T_NAPTR || qtype == T_ANY)
2281 {
2282 struct naptr *na;
2283 for (na = daemon->naptr; na; na = na->next)
2284 if (hostname_isequal(name, na->name))
2285 {
2286 ans = 1;
2287 if (!dryrun)
2288 {
2289 log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>");
2290 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
2291 NULL, T_NAPTR, C_IN, "sszzzd",
2292 na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
2293 anscount++;
2294 }
2295 }
2296 }
2297
2298 if (qtype == T_MAILB)
2299 ans = 1, nxdomain = 1;
2300
2301 if (qtype == T_SOA && option_bool(OPT_FILTER))
2302 {
2303 ans = 1;
2304 if (!dryrun)
2305 log_query(F_CONFIG | F_NEG, name, &addr, NULL);
2306 }
2307 }
2308
2309 if (!ans)
2310 return 0; /* failed to answer a question */
2311 }
2312
2313 if (dryrun)
2314 {
2315 dryrun = 0;
2316 goto rerun;
2317 }
2318
2319 /* create an additional data section, for stuff in SRV and MX record replies. */
2320 for (rec = daemon->mxnames; rec; rec = rec->next)
2321 if (rec->offset != 0)
2322 {
2323 /* squash dupes */
2324 struct mx_srv_record *tmp;
2325 for (tmp = rec->next; tmp; tmp = tmp->next)
2326 if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
2327 tmp->offset = 0;
2328
2329 crecp = NULL;
2330 while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
2331 {
2332 #ifdef HAVE_IPV6
2333 int type = crecp->flags & F_IPV4 ? T_A : T_AAAA;
2334 #else
2335 int type = T_A;
2336 #endif
2337 if (crecp->flags & F_NEG)
2338 continue;
2339
2340 if (add_resource_record(header, limit, NULL, rec->offset, &ansp,
2341 crec_ttl(crecp, now), NULL, type, C_IN,
2342 crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
2343 addncount++;
2344 }
2345 }
2346
2347 /* done all questions, set up header and return length of result */
2348 /* clear authoritative and truncated flags, set QR flag */
2349 header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
2350 /* set RA flag */
2351 header->hb4 |= HB4_RA;
2352
2353 /* authoritive - only hosts and DHCP derived names. */
2354 if (auth)
2355 header->hb3 |= HB3_AA;
2356
2357 /* truncation */
2358 if (trunc)
2359 header->hb3 |= HB3_TC;
2360
2361 if (nxdomain)
2362 SET_RCODE(header, NXDOMAIN);
2363 else
2364 SET_RCODE(header, NOERROR); /* no error */
2365 header->ancount = htons(anscount);
2366 header->nscount = htons(0);
2367 header->arcount = htons(addncount);
2368
2369 len = ansp - (unsigned char *)header;
2370
2371 if (have_pseudoheader)
2372 len = add_pseudoheader(header, len, (unsigned char *)limit, 0, NULL, 0, sec_reqd);
2373
2374 if (*ad_reqd && sec_data)
2375 header->hb4 |= HB4_AD;
2376 else
2377 header->hb4 &= ~HB4_AD;
2378
2379 return len;
2380 }
2381