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