Dnsmasq 2.67rc4 + Simon's tweaks up & incl 21 Oct 2013 20:47
[tomato.git] / release / src / router / dnsmasq / src / rfc1035.c
blobfc6d09ca7cedaea4f17111931f69234c815e8dc7
1 /* dnsmasq is Copyright (c) 2000-2013 Simon Kelley
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.
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.
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/>.
17 #include "dnsmasq.h"
20 #define CHECK_LEN(header, pp, plen, len) \
21 ((size_t)((pp) - (unsigned char *)(header) + (len)) <= (plen))
23 #define ADD_RDLEN(header, pp, plen, len) \
24 (!CHECK_LEN(header, pp, plen, len) ? 0 : (((pp) += (len)), 1))
26 int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
27 char *name, int isExtract, int extrabytes)
29 unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL;
30 unsigned int j, l, hops = 0;
31 int retvalue = 1;
33 if (isExtract)
34 *cp = 0;
36 while (1)
38 unsigned int label_type;
40 if (!CHECK_LEN(header, p, plen, 1))
41 return 0;
43 if ((l = *p++) == 0)
44 /* end marker */
46 /* check that there are the correct no of bytes after the name */
47 if (!CHECK_LEN(header, p, plen, extrabytes))
48 return 0;
50 if (isExtract)
52 if (cp != (unsigned char *)name)
53 cp--;
54 *cp = 0; /* terminate: lose final period */
56 else if (*cp != 0)
57 retvalue = 2;
59 if (p1) /* we jumped via compression */
60 *pp = p1;
61 else
62 *pp = p;
64 return retvalue;
67 label_type = l & 0xc0;
69 if (label_type == 0xc0) /* pointer */
71 if (!CHECK_LEN(header, p, plen, 1))
72 return 0;
74 /* get offset */
75 l = (l&0x3f) << 8;
76 l |= *p++;
78 if (!p1) /* first jump, save location to go back to */
79 p1 = p;
81 hops++; /* break malicious infinite loops */
82 if (hops > 255)
83 return 0;
85 p = l + (unsigned char *)header;
87 else if (label_type == 0x80)
88 return 0; /* reserved */
89 else if (label_type == 0x40)
90 { /* ELT */
91 unsigned int count, digs;
93 if ((l & 0x3f) != 1)
94 return 0; /* we only understand bitstrings */
96 if (!isExtract)
97 return 0; /* Cannot compare bitsrings */
99 count = *p++;
100 if (count == 0)
101 count = 256;
102 digs = ((count-1)>>2)+1;
104 /* output is \[x<hex>/siz]. which is digs+9 chars */
105 if (cp - (unsigned char *)name + digs + 9 >= MAXDNAME)
106 return 0;
107 if (!CHECK_LEN(header, p, plen, (count-1)>>3))
108 return 0;
110 *cp++ = '\\';
111 *cp++ = '[';
112 *cp++ = 'x';
113 for (j=0; j<digs; j++)
115 unsigned int dig;
116 if (j%2 == 0)
117 dig = *p >> 4;
118 else
119 dig = *p++ & 0x0f;
121 *cp++ = dig < 10 ? dig + '0' : dig + 'A' - 10;
123 cp += sprintf((char *)cp, "/%d]", count);
124 /* do this here to overwrite the zero char from sprintf */
125 *cp++ = '.';
127 else
128 { /* label_type = 0 -> label. */
129 if (cp - (unsigned char *)name + l + 1 >= MAXDNAME)
130 return 0;
131 if (!CHECK_LEN(header, p, plen, l))
132 return 0;
134 for(j=0; j<l; j++, p++)
135 if (isExtract)
137 unsigned char c = *p;
138 if (isascii(c) && !iscntrl(c) && c != '.')
139 *cp++ = *p;
140 else
141 return 0;
143 else
145 unsigned char c1 = *cp, c2 = *p;
147 if (c1 == 0)
148 retvalue = 2;
149 else
151 cp++;
152 if (c1 >= 'A' && c1 <= 'Z')
153 c1 += 'a' - 'A';
154 if (c2 >= 'A' && c2 <= 'Z')
155 c2 += 'a' - 'A';
157 if (c1 != c2)
158 retvalue = 2;
162 if (isExtract)
163 *cp++ = '.';
164 else if (*cp != 0 && *cp++ != '.')
165 retvalue = 2;
170 /* Max size of input string (for IPv6) is 75 chars.) */
171 #define MAXARPANAME 75
172 int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
174 int j;
175 char name[MAXARPANAME+1], *cp1;
176 unsigned char *addr = (unsigned char *)addrp;
177 char *lastchunk = NULL, *penchunk = NULL;
179 if (strlen(namein) > MAXARPANAME)
180 return 0;
182 memset(addrp, 0, sizeof(struct all_addr));
184 /* turn name into a series of asciiz strings */
185 /* j counts no of labels */
186 for(j = 1,cp1 = name; *namein; cp1++, namein++)
187 if (*namein == '.')
189 penchunk = lastchunk;
190 lastchunk = cp1 + 1;
191 *cp1 = 0;
192 j++;
194 else
195 *cp1 = *namein;
197 *cp1 = 0;
199 if (j<3)
200 return 0;
202 if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr"))
204 /* IP v4 */
205 /* address arives as a name of the form
206 www.xxx.yyy.zzz.in-addr.arpa
207 some of the low order address octets might be missing
208 and should be set to zero. */
209 for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
211 /* check for digits only (weeds out things like
212 50.0/24.67.28.64.in-addr.arpa which are used
213 as CNAME targets according to RFC 2317 */
214 char *cp;
215 for (cp = cp1; *cp; cp++)
216 if (!isdigit((unsigned char)*cp))
217 return 0;
219 addr[3] = addr[2];
220 addr[2] = addr[1];
221 addr[1] = addr[0];
222 addr[0] = atoi(cp1);
225 return F_IPV4;
227 #ifdef HAVE_IPV6
228 else if (hostname_isequal(penchunk, "ip6") &&
229 (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa")))
231 /* IP v6:
232 Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
233 or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]
235 Note that most of these the various reprentations are obsolete and
236 left-over from the many DNS-for-IPv6 wars. We support all the formats
237 that we can since there is no reason not to.
240 if (*name == '\\' && *(name+1) == '[' &&
241 (*(name+2) == 'x' || *(name+2) == 'X'))
243 for (j = 0, cp1 = name+3; *cp1 && isxdigit((unsigned char) *cp1) && j < 32; cp1++, j++)
245 char xdig[2];
246 xdig[0] = *cp1;
247 xdig[1] = 0;
248 if (j%2)
249 addr[j/2] |= strtol(xdig, NULL, 16);
250 else
251 addr[j/2] = strtol(xdig, NULL, 16) << 4;
254 if (*cp1 == '/' && j == 32)
255 return F_IPV6;
257 else
259 for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
261 if (*(cp1+1) || !isxdigit((unsigned char)*cp1))
262 return 0;
264 for (j = sizeof(struct all_addr)-1; j>0; j--)
265 addr[j] = (addr[j] >> 4) | (addr[j-1] << 4);
266 addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
269 return F_IPV6;
272 #endif
274 return 0;
277 static unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes)
279 while(1)
281 unsigned int label_type;
283 if (!CHECK_LEN(header, ansp, plen, 1))
284 return NULL;
286 label_type = (*ansp) & 0xc0;
288 if (label_type == 0xc0)
290 /* pointer for compression. */
291 ansp += 2;
292 break;
294 else if (label_type == 0x80)
295 return NULL; /* reserved */
296 else if (label_type == 0x40)
298 /* Extended label type */
299 unsigned int count;
301 if (!CHECK_LEN(header, ansp, plen, 2))
302 return NULL;
304 if (((*ansp++) & 0x3f) != 1)
305 return NULL; /* we only understand bitstrings */
307 count = *(ansp++); /* Bits in bitstring */
309 if (count == 0) /* count == 0 means 256 bits */
310 ansp += 32;
311 else
312 ansp += ((count-1)>>3)+1;
314 else
315 { /* label type == 0 Bottom six bits is length */
316 unsigned int len = (*ansp++) & 0x3f;
318 if (!ADD_RDLEN(header, ansp, plen, len))
319 return NULL;
321 if (len == 0)
322 break; /* zero length label marks the end. */
326 if (!CHECK_LEN(header, ansp, plen, extrabytes))
327 return NULL;
329 return ansp;
332 unsigned char *skip_questions(struct dns_header *header, size_t plen)
334 int q;
335 unsigned char *ansp = (unsigned char *)(header+1);
337 for (q = ntohs(header->qdcount); q != 0; q--)
339 if (!(ansp = skip_name(ansp, header, plen, 4)))
340 return NULL;
341 ansp += 4; /* class and type */
344 return ansp;
347 static unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen)
349 int i, rdlen;
351 for (i = 0; i < count; i++)
353 if (!(ansp = skip_name(ansp, header, plen, 10)))
354 return NULL;
355 ansp += 8; /* type, class, TTL */
356 GETSHORT(rdlen, ansp);
357 if (!ADD_RDLEN(header, ansp, plen, rdlen))
358 return NULL;
361 return ansp;
364 /* CRC the question section. This is used to safely detect query
365 retransmision and to detect answers to questions we didn't ask, which
366 might be poisoning attacks. Note that we decode the name rather
367 than CRC the raw bytes, since replies might be compressed differently.
368 We ignore case in the names for the same reason. Return all-ones
369 if there is not question section. */
370 unsigned int questions_crc(struct dns_header *header, size_t plen, char *name)
372 int q;
373 unsigned int crc = 0xffffffff;
374 unsigned char *p1, *p = (unsigned char *)(header+1);
376 for (q = ntohs(header->qdcount); q != 0; q--)
378 if (!extract_name(header, plen, &p, name, 1, 4))
379 return crc; /* bad packet */
381 for (p1 = (unsigned char *)name; *p1; p1++)
383 int i = 8;
384 char c = *p1;
386 if (c >= 'A' && c <= 'Z')
387 c += 'a' - 'A';
389 crc ^= c << 24;
390 while (i--)
391 crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
394 /* CRC the class and type as well */
395 for (p1 = p; p1 < p+4; p1++)
397 int i = 8;
398 crc ^= *p1 << 24;
399 while (i--)
400 crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
403 p += 4;
404 if (!CHECK_LEN(header, p, plen, 0))
405 return crc; /* bad packet */
408 return crc;
412 size_t resize_packet(struct dns_header *header, size_t plen, unsigned char *pheader, size_t hlen)
414 unsigned char *ansp = skip_questions(header, plen);
416 /* if packet is malformed, just return as-is. */
417 if (!ansp)
418 return plen;
420 if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
421 header, plen)))
422 return plen;
424 /* restore pseudoheader */
425 if (pheader && ntohs(header->arcount) == 0)
427 /* must use memmove, may overlap */
428 memmove(ansp, pheader, hlen);
429 header->arcount = htons(1);
430 ansp += hlen;
433 return ansp - (unsigned char *)header;
436 unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, size_t *len, unsigned char **p, int *is_sign)
438 /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
439 also return length of pseudoheader in *len and pointer to the UDP size in *p
440 Finally, check to see if a packet is signed. If it is we cannot change a single bit before
441 forwarding. We look for SIG and TSIG in the addition section, and TKEY queries (for GSS-TSIG) */
443 int i, arcount = ntohs(header->arcount);
444 unsigned char *ansp = (unsigned char *)(header+1);
445 unsigned short rdlen, type, class;
446 unsigned char *ret = NULL;
448 if (is_sign)
450 *is_sign = 0;
452 if (OPCODE(header) == QUERY)
454 for (i = ntohs(header->qdcount); i != 0; i--)
456 if (!(ansp = skip_name(ansp, header, plen, 4)))
457 return NULL;
459 GETSHORT(type, ansp);
460 GETSHORT(class, ansp);
462 if (class == C_IN && type == T_TKEY)
463 *is_sign = 1;
467 else
469 if (!(ansp = skip_questions(header, plen)))
470 return NULL;
473 if (arcount == 0)
474 return NULL;
476 if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount), header, plen)))
477 return NULL;
479 for (i = 0; i < arcount; i++)
481 unsigned char *save, *start = ansp;
482 if (!(ansp = skip_name(ansp, header, plen, 10)))
483 return NULL;
485 GETSHORT(type, ansp);
486 save = ansp;
487 GETSHORT(class, ansp);
488 ansp += 4; /* TTL */
489 GETSHORT(rdlen, ansp);
490 if (!ADD_RDLEN(header, ansp, plen, rdlen))
491 return NULL;
492 if (type == T_OPT)
494 if (len)
495 *len = ansp - start;
496 if (p)
497 *p = save;
498 ret = start;
500 else if (is_sign &&
501 i == arcount - 1 &&
502 class == C_ANY &&
503 (type == T_SIG || type == T_TSIG))
504 *is_sign = 1;
507 return ret;
510 struct macparm {
511 unsigned char *limit;
512 struct dns_header *header;
513 size_t plen;
514 union mysockaddr *l3;
517 static size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
518 int optno, unsigned char *opt, size_t optlen)
520 unsigned char *lenp, *datap, *p;
521 int rdlen;
523 if (ntohs(header->arcount) == 0)
525 /* We are adding the pseudoheader */
526 if (!(p = skip_questions(header, plen)) ||
527 !(p = skip_section(p,
528 ntohs(header->ancount) + ntohs(header->nscount),
529 header, plen)))
530 return plen;
531 *p++ = 0; /* empty name */
532 PUTSHORT(T_OPT, p);
533 PUTSHORT(daemon->edns_pktsz, p); /* max packet length */
534 PUTLONG(0, p); /* extended RCODE */
535 lenp = p;
536 PUTSHORT(0, p); /* RDLEN */
537 rdlen = 0;
538 if (((ssize_t)optlen) > (limit - (p + 4)))
539 return plen; /* Too big */
540 header->arcount = htons(1);
541 datap = p;
543 else
545 int i, is_sign;
546 unsigned short code, len;
548 if (ntohs(header->arcount) != 1 ||
549 !(p = find_pseudoheader(header, plen, NULL, NULL, &is_sign)) ||
550 is_sign ||
551 (!(p = skip_name(p, header, plen, 10))))
552 return plen;
554 p += 8; /* skip UDP length and RCODE */
556 lenp = p;
557 GETSHORT(rdlen, p);
558 if (!CHECK_LEN(header, p, plen, rdlen))
559 return plen; /* bad packet */
560 datap = p;
562 /* check if option already there */
563 for (i = 0; i + 4 < rdlen; i += len + 4)
565 GETSHORT(code, p);
566 GETSHORT(len, p);
567 if (code == optno)
568 return plen;
569 p += len;
572 if (((ssize_t)optlen) > (limit - (p + 4)))
573 return plen; /* Too big */
576 PUTSHORT(optno, p);
577 PUTSHORT(optlen, p);
578 memcpy(p, opt, optlen);
579 p += optlen;
581 PUTSHORT(p - datap, lenp);
582 return p - (unsigned char *)header;
586 static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *parmv)
588 struct macparm *parm = parmv;
589 int match = 0;
591 if (family == parm->l3->sa.sa_family)
593 if (family == AF_INET && memcmp (&parm->l3->in.sin_addr, addrp, INADDRSZ) == 0)
594 match = 1;
595 #ifdef HAVE_IPV6
596 else
597 if (family == AF_INET6 && memcmp (&parm->l3->in6.sin6_addr, addrp, IN6ADDRSZ) == 0)
598 match = 1;
599 #endif
602 if (!match)
603 return 1; /* continue */
605 parm->plen = add_pseudoheader(parm->header, parm->plen, parm->limit, EDNS0_OPTION_MAC, (unsigned char *)mac, maclen);
607 return 0; /* done */
610 size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysockaddr *l3)
612 struct macparm parm;
614 /* Must have an existing pseudoheader as the only ar-record,
615 or have no ar-records. Must also not be signed */
617 if (ntohs(header->arcount) > 1)
618 return plen;
620 parm.header = header;
621 parm.limit = (unsigned char *)limit;
622 parm.plen = plen;
623 parm.l3 = l3;
625 iface_enumerate(AF_UNSPEC, &parm, filter_mac);
627 return parm.plen;
630 struct subnet_opt {
631 u16 family;
632 u8 source_netmask, scope_netmask;
633 #ifdef HAVE_IPV6
634 u8 addr[IN6ADDRSZ];
635 #else
636 u8 addr[INADDRSZ];
637 #endif
640 size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
642 /* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
644 int len;
645 void *addrp;
647 #ifdef HAVE_IPV6
648 if (source->sa.sa_family == AF_INET6)
650 opt->family = htons(2);
651 opt->source_netmask = daemon->addr6_netmask;
652 addrp = &source->in6.sin6_addr;
654 else
655 #endif
657 opt->family = htons(1);
658 opt->source_netmask = daemon->addr4_netmask;
659 addrp = &source->in.sin_addr;
662 opt->scope_netmask = 0;
663 len = 0;
665 if (opt->source_netmask != 0)
667 len = ((opt->source_netmask - 1) >> 3) + 1;
668 memcpy(opt->addr, addrp, len);
669 if (opt->source_netmask & 7)
670 opt->addr[len-1] &= 0xff << (8 - (opt->source_netmask & 7));
673 return len + 4;
676 size_t add_source_addr(struct dns_header *header, size_t plen, char *limit, union mysockaddr *source)
678 /* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
680 int len;
681 struct subnet_opt opt;
683 len = calc_subnet_opt(&opt, source);
684 return add_pseudoheader(header, plen, (unsigned char *)limit, EDNS0_OPTION_CLIENT_SUBNET, (unsigned char *)&opt, len);
687 int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer)
689 /* Section 9.2, Check that subnet option in reply matches. */
692 int len, calc_len;
693 struct subnet_opt opt;
694 unsigned char *p;
695 int code, i, rdlen;
697 calc_len = calc_subnet_opt(&opt, peer);
699 if (!(p = skip_name(pseudoheader, header, plen, 10)))
700 return 1;
702 p += 8; /* skip UDP length and RCODE */
704 GETSHORT(rdlen, p);
705 if (!CHECK_LEN(header, p, plen, rdlen))
706 return 1; /* bad packet */
708 /* check if option there */
709 for (i = 0; i + 4 < rdlen; i += len + 4)
711 GETSHORT(code, p);
712 GETSHORT(len, p);
713 if (code == EDNS0_OPTION_CLIENT_SUBNET)
715 /* make sure this doesn't mismatch. */
716 opt.scope_netmask = p[3];
717 if (len != calc_len || memcmp(p, &opt, len) != 0)
718 return 0;
720 p += len;
723 return 1;
726 /* is addr in the non-globally-routed IP space? */
727 int private_net(struct in_addr addr, int ban_localhost)
729 in_addr_t ip_addr = ntohl(addr.s_addr);
731 return
732 (((ip_addr & 0xFF000000) == 0x7F000000) && ban_localhost) /* 127.0.0.0/8 (loopback) */ ||
733 ((ip_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168.0.0/16 (private) */ ||
734 ((ip_addr & 0xFF000000) == 0x0A000000) /* 10.0.0.0/8 (private) */ ||
735 ((ip_addr & 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12 (private) */ ||
736 ((ip_addr & 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */ ;
739 static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *header, size_t qlen, char *name)
741 int i, qtype, qclass, rdlen;
743 for (i = count; i != 0; i--)
745 if (name && option_bool(OPT_LOG))
747 if (!extract_name(header, qlen, &p, name, 1, 10))
748 return 0;
750 else if (!(p = skip_name(p, header, qlen, 10)))
751 return 0; /* bad packet */
753 GETSHORT(qtype, p);
754 GETSHORT(qclass, p);
755 p += 4; /* ttl */
756 GETSHORT(rdlen, p);
758 if (qclass == C_IN && qtype == T_A)
760 struct doctor *doctor;
761 struct in_addr addr;
763 if (!CHECK_LEN(header, p, qlen, INADDRSZ))
764 return 0;
766 /* alignment */
767 memcpy(&addr, p, INADDRSZ);
769 for (doctor = daemon->doctors; doctor; doctor = doctor->next)
771 if (doctor->end.s_addr == 0)
773 if (!is_same_net(doctor->in, addr, doctor->mask))
774 continue;
776 else if (ntohl(doctor->in.s_addr) > ntohl(addr.s_addr) ||
777 ntohl(doctor->end.s_addr) < ntohl(addr.s_addr))
778 continue;
780 addr.s_addr &= ~doctor->mask.s_addr;
781 addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
782 /* Since we munged the data, the server it came from is no longer authoritative */
783 header->hb3 &= ~HB3_AA;
784 memcpy(p, &addr, INADDRSZ);
785 break;
788 else if (qtype == T_TXT && name && option_bool(OPT_LOG))
790 unsigned char *p1 = p;
791 if (!CHECK_LEN(header, p1, qlen, rdlen))
792 return 0;
793 while ((p1 - p) < rdlen)
795 unsigned int i, len = *p1;
796 unsigned char *p2 = p1;
797 /* make counted string zero-term and sanitise */
798 for (i = 0; i < len; i++)
800 if (!isprint((int)*(p2+1)))
801 break;
803 *p2 = *(p2+1);
804 p2++;
806 *p2 = 0;
807 my_syslog(LOG_INFO, "reply %s is %s", name, p1);
808 /* restore */
809 memmove(p1 + 1, p1, i);
810 *p1 = len;
811 p1 += len+1;
815 if (!ADD_RDLEN(header, p, qlen, rdlen))
816 return 0; /* bad packet */
819 return p;
822 static int find_soa(struct dns_header *header, size_t qlen, char *name)
824 unsigned char *p;
825 int qtype, qclass, rdlen;
826 unsigned long ttl, minttl = ULONG_MAX;
827 int i, found_soa = 0;
829 /* first move to NS section and find TTL from any SOA section */
830 if (!(p = skip_questions(header, qlen)) ||
831 !(p = do_doctor(p, ntohs(header->ancount), header, qlen, name)))
832 return 0; /* bad packet */
834 for (i = ntohs(header->nscount); i != 0; i--)
836 if (!(p = skip_name(p, header, qlen, 10)))
837 return 0; /* bad packet */
839 GETSHORT(qtype, p);
840 GETSHORT(qclass, p);
841 GETLONG(ttl, p);
842 GETSHORT(rdlen, p);
844 if ((qclass == C_IN) && (qtype == T_SOA))
846 found_soa = 1;
847 if (ttl < minttl)
848 minttl = ttl;
850 /* MNAME */
851 if (!(p = skip_name(p, header, qlen, 0)))
852 return 0;
853 /* RNAME */
854 if (!(p = skip_name(p, header, qlen, 20)))
855 return 0;
856 p += 16; /* SERIAL REFRESH RETRY EXPIRE */
858 GETLONG(ttl, p); /* minTTL */
859 if (ttl < minttl)
860 minttl = ttl;
862 else if (!ADD_RDLEN(header, p, qlen, rdlen))
863 return 0; /* bad packet */
866 /* rewrite addresses in additioal section too */
867 if (!do_doctor(p, ntohs(header->arcount), header, qlen, NULL))
868 return 0;
870 if (!found_soa)
871 minttl = daemon->neg_ttl;
873 return minttl;
876 /* Note that the following code can create CNAME chains that don't point to a real record,
877 either because of lack of memory, or lack of SOA records. These are treated by the cache code as
878 expired and cleaned out that way.
879 Return 1 if we reject an address because it look like part of dns-rebinding attack. */
880 int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t now,
881 char **ipsets, int is_sign, int check_rebind, int checking_disabled)
883 unsigned char *p, *p1, *endrr, *namep;
884 int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
885 unsigned long ttl = 0;
886 struct all_addr addr;
887 #ifdef HAVE_IPSET
888 char **ipsets_cur;
889 #else
890 (void)ipsets; /* unused */
891 #endif
893 cache_start_insert();
895 /* find_soa is needed for dns_doctor and logging side-effects, so don't call it lazily if there are any. */
896 if (daemon->doctors || option_bool(OPT_LOG))
898 searched_soa = 1;
899 ttl = find_soa(header, qlen, name);
902 /* go through the questions. */
903 p = (unsigned char *)(header+1);
905 for (i = ntohs(header->qdcount); i != 0; i--)
907 int found = 0, cname_count = 5;
908 struct crec *cpp = NULL;
909 int flags = RCODE(header) == NXDOMAIN ? F_NXDOMAIN : 0;
910 unsigned long cttl = ULONG_MAX, attl;
912 namep = p;
913 if (!extract_name(header, qlen, &p, name, 1, 4))
914 return 0; /* bad packet */
916 GETSHORT(qtype, p);
917 GETSHORT(qclass, p);
919 if (qclass != C_IN)
920 continue;
922 /* PTRs: we chase CNAMEs here, since we have no way to
923 represent them in the cache. */
924 if (qtype == T_PTR)
926 int name_encoding = in_arpa_name_2_addr(name, &addr);
928 if (!name_encoding)
929 continue;
931 if (!(flags & F_NXDOMAIN))
933 cname_loop:
934 if (!(p1 = skip_questions(header, qlen)))
935 return 0;
937 for (j = ntohs(header->ancount); j != 0; j--)
939 unsigned char *tmp = namep;
940 /* the loop body overwrites the original name, so get it back here. */
941 if (!extract_name(header, qlen, &tmp, name, 1, 0) ||
942 !(res = extract_name(header, qlen, &p1, name, 0, 10)))
943 return 0; /* bad packet */
945 GETSHORT(aqtype, p1);
946 GETSHORT(aqclass, p1);
947 GETLONG(attl, p1);
948 if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
950 (p1) -= 4;
951 PUTLONG(daemon->max_ttl, p1);
953 GETSHORT(ardlen, p1);
954 endrr = p1+ardlen;
956 /* TTL of record is minimum of CNAMES and PTR */
957 if (attl < cttl)
958 cttl = attl;
960 if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
962 if (!extract_name(header, qlen, &p1, name, 1, 0))
963 return 0;
965 if (aqtype == T_CNAME)
967 if (!cname_count--)
968 return 0; /* looped CNAMES */
969 goto cname_loop;
972 cache_insert(name, &addr, now, cttl, name_encoding | F_REVERSE);
973 found = 1;
976 p1 = endrr;
977 if (!CHECK_LEN(header, p1, qlen, 0))
978 return 0; /* bad packet */
982 if (!found && !option_bool(OPT_NO_NEG))
984 if (!searched_soa)
986 searched_soa = 1;
987 ttl = find_soa(header, qlen, NULL);
989 if (ttl)
990 cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags);
993 else
995 /* everything other than PTR */
996 struct crec *newc;
997 int addrlen;
999 if (qtype == T_A)
1001 addrlen = INADDRSZ;
1002 flags |= F_IPV4;
1004 #ifdef HAVE_IPV6
1005 else if (qtype == T_AAAA)
1007 addrlen = IN6ADDRSZ;
1008 flags |= F_IPV6;
1010 #endif
1011 else
1012 continue;
1014 cname_loop1:
1015 if (!(p1 = skip_questions(header, qlen)))
1016 return 0;
1018 for (j = ntohs(header->ancount); j != 0; j--)
1020 if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
1021 return 0; /* bad packet */
1023 GETSHORT(aqtype, p1);
1024 GETSHORT(aqclass, p1);
1025 GETLONG(attl, p1);
1026 if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
1028 (p1) -= 4;
1029 PUTLONG(daemon->max_ttl, p1);
1031 GETSHORT(ardlen, p1);
1032 endrr = p1+ardlen;
1034 if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
1036 if (aqtype == T_CNAME)
1038 if (!cname_count--)
1039 return 0; /* looped CNAMES */
1040 newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD);
1041 if (newc)
1043 newc->addr.cname.target.cache = NULL;
1044 if (cpp)
1046 cpp->addr.cname.target.cache = newc;
1047 cpp->addr.cname.uid = newc->uid;
1051 cpp = newc;
1052 if (attl < cttl)
1053 cttl = attl;
1055 if (!extract_name(header, qlen, &p1, name, 1, 0))
1056 return 0;
1057 goto cname_loop1;
1059 else if (!(flags & F_NXDOMAIN))
1061 found = 1;
1063 /* copy address into aligned storage */
1064 if (!CHECK_LEN(header, p1, qlen, addrlen))
1065 return 0; /* bad packet */
1066 memcpy(&addr, p1, addrlen);
1068 /* check for returned address in private space */
1069 if (check_rebind &&
1070 (flags & F_IPV4) &&
1071 private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
1072 return 1;
1074 #ifdef HAVE_IPSET
1075 if (ipsets && (flags & (F_IPV4 | F_IPV6)))
1077 ipsets_cur = ipsets;
1078 while (*ipsets_cur)
1079 add_to_ipset(*ipsets_cur++, &addr, flags, 0);
1081 #endif
1083 newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
1084 if (newc && cpp)
1086 cpp->addr.cname.target.cache = newc;
1087 cpp->addr.cname.uid = newc->uid;
1089 cpp = NULL;
1093 p1 = endrr;
1094 if (!CHECK_LEN(header, p1, qlen, 0))
1095 return 0; /* bad packet */
1098 if (!found && !option_bool(OPT_NO_NEG))
1100 if (!searched_soa)
1102 searched_soa = 1;
1103 ttl = find_soa(header, qlen, NULL);
1105 /* If there's no SOA to get the TTL from, but there is a CNAME
1106 pointing at this, inherit its TTL */
1107 if (ttl || cpp)
1109 newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags);
1110 if (newc && cpp)
1112 cpp->addr.cname.target.cache = newc;
1113 cpp->addr.cname.uid = newc->uid;
1120 /* Don't put stuff from a truncated packet into the cache.
1121 Don't cache replies where DNSSEC validation was turned off, either
1122 the upstream server told us so, or the original query specified it.
1123 Don't cache replies from non-recursive nameservers, since we may get a
1124 reply containing a CNAME but not its target, even though the target
1125 does exist. */
1126 if (!(header->hb3 & HB3_TC) &&
1127 !(header->hb4 & HB4_CD) &&
1128 (header->hb4 & HB4_RA) &&
1129 !checking_disabled)
1130 cache_end_insert();
1132 return 0;
1135 /* If the packet holds exactly one query
1136 return F_IPV4 or F_IPV6 and leave the name from the query in name */
1138 unsigned int extract_request(struct dns_header *header, size_t qlen, char *name, unsigned short *typep)
1140 unsigned char *p = (unsigned char *)(header+1);
1141 int qtype, qclass;
1143 if (typep)
1144 *typep = 0;
1146 if (ntohs(header->qdcount) != 1 || OPCODE(header) != QUERY)
1147 return 0; /* must be exactly one query. */
1149 if (!extract_name(header, qlen, &p, name, 1, 4))
1150 return 0; /* bad packet */
1152 GETSHORT(qtype, p);
1153 GETSHORT(qclass, p);
1155 if (typep)
1156 *typep = qtype;
1158 if (qclass == C_IN)
1160 if (qtype == T_A)
1161 return F_IPV4;
1162 if (qtype == T_AAAA)
1163 return F_IPV6;
1164 if (qtype == T_ANY)
1165 return F_IPV4 | F_IPV6;
1168 return F_QUERY;
1172 size_t setup_reply(struct dns_header *header, size_t qlen,
1173 struct all_addr *addrp, unsigned int flags, unsigned long ttl)
1175 unsigned char *p = skip_questions(header, qlen);
1177 /* clear authoritative and truncated flags, set QR flag */
1178 header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
1179 /* set RA flag */
1180 header->hb4 |= HB4_RA;
1182 header->nscount = htons(0);
1183 header->arcount = htons(0);
1184 header->ancount = htons(0); /* no answers unless changed below */
1185 if (flags == F_NEG)
1186 SET_RCODE(header, SERVFAIL); /* couldn't get memory */
1187 else if (flags == F_NOERR)
1188 SET_RCODE(header, NOERROR); /* empty domain */
1189 else if (flags == F_NXDOMAIN)
1190 SET_RCODE(header, NXDOMAIN);
1191 else if (p && flags == F_IPV4)
1192 { /* we know the address */
1193 SET_RCODE(header, NOERROR);
1194 header->ancount = htons(1);
1195 header->hb3 |= HB3_AA;
1196 add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_A, C_IN, "4", addrp);
1198 #ifdef HAVE_IPV6
1199 else if (p && flags == F_IPV6)
1201 SET_RCODE(header, NOERROR);
1202 header->ancount = htons(1);
1203 header->hb3 |= HB3_AA;
1204 add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
1206 #endif
1207 else /* nowhere to forward to */
1208 SET_RCODE(header, REFUSED);
1210 return p - (unsigned char *)header;
1213 /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
1214 int check_for_local_domain(char *name, time_t now)
1216 struct crec *crecp;
1217 struct mx_srv_record *mx;
1218 struct txt_record *txt;
1219 struct interface_name *intr;
1220 struct ptr_record *ptr;
1221 struct naptr *naptr;
1223 if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME)) &&
1224 (crecp->flags & (F_HOSTS | F_DHCP)))
1225 return 1;
1227 for (naptr = daemon->naptr; naptr; naptr = naptr->next)
1228 if (hostname_isequal(name, naptr->name))
1229 return 1;
1231 for (mx = daemon->mxnames; mx; mx = mx->next)
1232 if (hostname_isequal(name, mx->name))
1233 return 1;
1235 for (txt = daemon->txt; txt; txt = txt->next)
1236 if (hostname_isequal(name, txt->name))
1237 return 1;
1239 for (intr = daemon->int_names; intr; intr = intr->next)
1240 if (hostname_isequal(name, intr->name))
1241 return 1;
1243 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1244 if (hostname_isequal(name, ptr->name))
1245 return 1;
1247 return 0;
1250 /* Is the packet a reply with the answer address equal to addr?
1251 If so mung is into an NXDOMAIN reply and also put that information
1252 in the cache. */
1253 int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
1254 struct bogus_addr *baddr, time_t now)
1256 unsigned char *p;
1257 int i, qtype, qclass, rdlen;
1258 unsigned long ttl;
1259 struct bogus_addr *baddrp;
1261 /* skip over questions */
1262 if (!(p = skip_questions(header, qlen)))
1263 return 0; /* bad packet */
1265 for (i = ntohs(header->ancount); i != 0; i--)
1267 if (!extract_name(header, qlen, &p, name, 1, 10))
1268 return 0; /* bad packet */
1270 GETSHORT(qtype, p);
1271 GETSHORT(qclass, p);
1272 GETLONG(ttl, p);
1273 GETSHORT(rdlen, p);
1275 if (qclass == C_IN && qtype == T_A)
1277 if (!CHECK_LEN(header, p, qlen, INADDRSZ))
1278 return 0;
1280 for (baddrp = baddr; baddrp; baddrp = baddrp->next)
1281 if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
1283 /* Found a bogus address. Insert that info here, since there no SOA record
1284 to get the ttl from in the normal processing */
1285 cache_start_insert();
1286 cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN | F_CONFIG);
1287 cache_end_insert();
1289 return 1;
1293 if (!ADD_RDLEN(header, p, qlen, rdlen))
1294 return 0;
1297 return 0;
1300 int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp,
1301 unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
1303 va_list ap;
1304 unsigned char *sav, *p = *pp;
1305 int j;
1306 unsigned short usval;
1307 long lval;
1308 char *sval;
1310 if (truncp && *truncp)
1311 return 0;
1313 va_start(ap, format); /* make ap point to 1st unamed argument */
1315 if (nameoffset > 0)
1317 PUTSHORT(nameoffset | 0xc000, p);
1319 else
1321 char *name = va_arg(ap, char *);
1322 if (name)
1323 p = do_rfc1035_name(p, name);
1324 if (nameoffset < 0)
1326 PUTSHORT(-nameoffset | 0xc000, p);
1328 else
1329 *p++ = 0;
1332 PUTSHORT(type, p);
1333 PUTSHORT(class, p);
1334 PUTLONG(ttl, p); /* TTL */
1336 sav = p; /* Save pointer to RDLength field */
1337 PUTSHORT(0, p); /* Placeholder RDLength */
1339 for (; *format; format++)
1340 switch (*format)
1342 #ifdef HAVE_IPV6
1343 case '6':
1344 sval = va_arg(ap, char *);
1345 memcpy(p, sval, IN6ADDRSZ);
1346 p += IN6ADDRSZ;
1347 break;
1348 #endif
1350 case '4':
1351 sval = va_arg(ap, char *);
1352 memcpy(p, sval, INADDRSZ);
1353 p += INADDRSZ;
1354 break;
1356 case 's':
1357 usval = va_arg(ap, int);
1358 PUTSHORT(usval, p);
1359 break;
1361 case 'l':
1362 lval = va_arg(ap, long);
1363 PUTLONG(lval, p);
1364 break;
1366 case 'd':
1367 /* get domain-name answer arg and store it in RDATA field */
1368 if (offset)
1369 *offset = p - (unsigned char *)header;
1370 p = do_rfc1035_name(p, va_arg(ap, char *));
1371 *p++ = 0;
1372 break;
1374 case 't':
1375 usval = va_arg(ap, int);
1376 sval = va_arg(ap, char *);
1377 if (usval != 0)
1378 memcpy(p, sval, usval);
1379 p += usval;
1380 break;
1382 case 'z':
1383 sval = va_arg(ap, char *);
1384 usval = sval ? strlen(sval) : 0;
1385 if (usval > 255)
1386 usval = 255;
1387 *p++ = (unsigned char)usval;
1388 memcpy(p, sval, usval);
1389 p += usval;
1390 break;
1393 va_end(ap); /* clean up variable argument pointer */
1395 j = p - sav - 2;
1396 PUTSHORT(j, sav); /* Now, store real RDLength */
1398 /* check for overflow of buffer */
1399 if (limit && ((unsigned char *)limit - p) < 0)
1401 if (truncp)
1402 *truncp = 1;
1403 return 0;
1406 *pp = p;
1407 return 1;
1410 static unsigned long crec_ttl(struct crec *crecp, time_t now)
1412 /* Return 0 ttl for DHCP entries, which might change
1413 before the lease expires. */
1415 if (crecp->flags & (F_IMMORTAL | F_DHCP))
1416 return daemon->local_ttl;
1418 /* Return the Max TTL value if it is lower then the actual TTL */
1419 if (daemon->max_ttl == 0 || ((unsigned)(crecp->ttd - now) < daemon->max_ttl))
1420 return crecp->ttd - now;
1421 else
1422 return daemon->max_ttl;
1426 /* return zero if we can't answer from cache, or packet size if we can */
1427 size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
1428 struct in_addr local_addr, struct in_addr local_netmask, time_t now)
1430 char *name = daemon->namebuff;
1431 unsigned char *p, *ansp, *pheader;
1432 int qtype, qclass;
1433 struct all_addr addr;
1434 int nameoffset;
1435 unsigned short flag;
1436 int q, ans, anscount = 0, addncount = 0;
1437 int dryrun = 0, sec_reqd = 0;
1438 int is_sign;
1439 struct crec *crecp;
1440 int nxdomain = 0, auth = 1, trunc = 0;
1441 struct mx_srv_record *rec;
1443 /* If there is an RFC2671 pseudoheader then it will be overwritten by
1444 partial replies, so we have to do a dry run to see if we can answer
1445 the query. We check to see if the do bit is set, if so we always
1446 forward rather than answering from the cache, which doesn't include
1447 security information. */
1449 if (find_pseudoheader(header, qlen, NULL, &pheader, &is_sign))
1451 unsigned short udpsz, flags;
1452 unsigned char *psave = pheader;
1454 GETSHORT(udpsz, pheader);
1455 pheader += 2; /* ext_rcode */
1456 GETSHORT(flags, pheader);
1458 sec_reqd = flags & 0x8000; /* do bit */
1460 /* If our client is advertising a larger UDP packet size
1461 than we allow, trim it so that we don't get an overlarge
1462 response from upstream */
1464 if (!is_sign && (udpsz > daemon->edns_pktsz))
1465 PUTSHORT(daemon->edns_pktsz, psave);
1467 dryrun = 1;
1470 if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
1471 return 0;
1473 for (rec = daemon->mxnames; rec; rec = rec->next)
1474 rec->offset = 0;
1476 rerun:
1477 /* determine end of question section (we put answers there) */
1478 if (!(ansp = skip_questions(header, qlen)))
1479 return 0; /* bad packet */
1481 /* now process each question, answers go in RRs after the question */
1482 p = (unsigned char *)(header+1);
1484 for (q = ntohs(header->qdcount); q != 0; q--)
1486 /* save pointer to name for copying into answers */
1487 nameoffset = p - (unsigned char *)header;
1489 /* now extract name as .-concatenated string into name */
1490 if (!extract_name(header, qlen, &p, name, 1, 4))
1491 return 0; /* bad packet */
1493 GETSHORT(qtype, p);
1494 GETSHORT(qclass, p);
1496 ans = 0; /* have we answered this question */
1498 if (qtype == T_TXT || qtype == T_ANY)
1500 struct txt_record *t;
1501 for(t = daemon->txt; t ; t = t->next)
1503 if (t->class == qclass && hostname_isequal(name, t->name))
1505 ans = 1;
1506 if (!dryrun)
1508 log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
1509 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1510 daemon->local_ttl, NULL,
1511 T_TXT, t->class, "t", t->len, t->txt))
1512 anscount++;
1519 if (qclass == C_IN)
1521 struct txt_record *t;
1523 for (t = daemon->rr; t; t = t->next)
1524 if ((t->class == qtype || qtype == T_ANY) && hostname_isequal(name, t->name))
1526 ans = 1;
1527 if (!dryrun)
1529 log_query(F_CONFIG | F_RRNAME, name, NULL, "<RR>");
1530 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1531 daemon->local_ttl, NULL,
1532 t->class, C_IN, "t", t->len, t->txt))
1533 anscount ++;
1537 if (qtype == T_PTR || qtype == T_ANY)
1539 /* see if it's w.z.y.z.in-addr.arpa format */
1540 int is_arpa = in_arpa_name_2_addr(name, &addr);
1541 struct ptr_record *ptr;
1542 struct interface_name* intr = NULL;
1544 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1545 if (hostname_isequal(name, ptr->name))
1546 break;
1548 if (is_arpa == F_IPV4)
1549 for (intr = daemon->int_names; intr; intr = intr->next)
1551 struct addrlist *addrlist;
1553 for (addrlist = intr->addr4; addrlist; addrlist = addrlist->next)
1554 if (addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
1555 break;
1557 if (addrlist)
1558 break;
1559 else
1560 while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1561 intr = intr->next;
1563 #ifdef HAVE_IPV6
1564 else if (is_arpa == F_IPV6)
1565 for (intr = daemon->int_names; intr; intr = intr->next)
1567 struct addrlist *addrlist;
1569 for (addrlist = intr->addr6; addrlist; addrlist = addrlist->next)
1570 if (IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
1571 break;
1573 if (addrlist)
1574 break;
1575 else
1576 while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1577 intr = intr->next;
1579 #endif
1581 if (intr)
1583 ans = 1;
1584 if (!dryrun)
1586 log_query(is_arpa | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
1587 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1588 daemon->local_ttl, NULL,
1589 T_PTR, C_IN, "d", intr->name))
1590 anscount++;
1593 else if (ptr)
1595 ans = 1;
1596 if (!dryrun)
1598 log_query(F_CONFIG | F_RRNAME, name, NULL, "<PTR>");
1599 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1600 if (hostname_isequal(name, ptr->name) &&
1601 add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1602 daemon->local_ttl, NULL,
1603 T_PTR, C_IN, "d", ptr->ptr))
1604 anscount++;
1608 else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
1611 /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
1612 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1613 continue;
1615 if (crecp->flags & F_NEG)
1617 ans = 1;
1618 auth = 0;
1619 if (crecp->flags & F_NXDOMAIN)
1620 nxdomain = 1;
1621 if (!dryrun)
1622 log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
1624 else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
1626 ans = 1;
1627 if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1628 auth = 0;
1629 if (!dryrun)
1631 log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
1632 record_source(crecp->uid));
1634 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1635 crec_ttl(crecp, now), NULL,
1636 T_PTR, C_IN, "d", cache_get_name(crecp)))
1637 anscount++;
1640 } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
1641 else if (is_rev_synth(is_arpa, &addr, name))
1643 ans = 1;
1644 if (!dryrun)
1646 log_query(F_CONFIG | F_REVERSE | is_arpa, name, &addr, NULL);
1648 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1649 daemon->local_ttl, NULL,
1650 T_PTR, C_IN, "d", name))
1651 anscount++;
1654 else if (is_arpa == F_IPV4 &&
1655 option_bool(OPT_BOGUSPRIV) &&
1656 private_net(addr.addr.addr4, 1))
1658 /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
1659 ans = 1;
1660 nxdomain = 1;
1661 if (!dryrun)
1662 log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN,
1663 name, &addr, NULL);
1667 for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
1669 unsigned short type = T_A;
1670 struct interface_name *intr;
1672 if (flag == F_IPV6)
1673 #ifdef HAVE_IPV6
1674 type = T_AAAA;
1675 #else
1676 break;
1677 #endif
1679 if (qtype != type && qtype != T_ANY)
1680 continue;
1682 /* Check for "A for A" queries; be rather conservative
1683 about what looks like dotted-quad. */
1684 if (qtype == T_A)
1686 char *cp;
1687 unsigned int i, a;
1688 int x;
1690 for (cp = name, i = 0, a = 0; *cp; i++)
1692 if (!isdigit((unsigned char)*cp) || (x = strtol(cp, &cp, 10)) > 255)
1694 i = 5;
1695 break;
1698 a = (a << 8) + x;
1700 if (*cp == '.')
1701 cp++;
1704 if (i == 4)
1706 ans = 1;
1707 if (!dryrun)
1709 addr.addr.addr4.s_addr = htonl(a);
1710 log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
1711 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1712 daemon->local_ttl, NULL, type, C_IN, "4", &addr))
1713 anscount++;
1715 continue;
1719 /* interface name stuff */
1720 intname_restart:
1721 for (intr = daemon->int_names; intr; intr = intr->next)
1722 if (hostname_isequal(name, intr->name))
1723 break;
1725 if (intr)
1727 struct addrlist *addrlist;
1728 int gotit = 0;
1730 enumerate_interfaces(0);
1732 for (intr = daemon->int_names; intr; intr = intr->next)
1733 if (hostname_isequal(name, intr->name))
1735 addrlist = intr->addr4;
1736 #ifdef HAVE_IPV6
1737 if (type == T_AAAA)
1738 addrlist = intr->addr6;
1739 #endif
1740 ans = 1;
1741 if (!dryrun)
1743 if (addrlist)
1745 gotit = 1;
1746 for (; addrlist; addrlist = addrlist->next)
1748 log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
1749 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1750 daemon->local_ttl, NULL, type, C_IN,
1751 type == T_A ? "4" : "6", &addrlist->addr))
1752 anscount++;
1758 if (!dryrun && !gotit)
1759 log_query(F_FORWARD | F_CONFIG | flag | F_NEG, name, NULL, NULL);
1761 continue;
1764 cname_restart:
1765 if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME)))
1767 int localise = 0;
1769 /* See if a putative address is on the network from which we recieved
1770 the query, is so we'll filter other answers. */
1771 if (local_addr.s_addr != 0 && option_bool(OPT_LOCALISE) && flag == F_IPV4)
1773 struct crec *save = crecp;
1774 do {
1775 if ((crecp->flags & F_HOSTS) &&
1776 is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1778 localise = 1;
1779 break;
1781 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
1782 crecp = save;
1787 /* don't answer wildcard queries with data not from /etc/hosts
1788 or DHCP leases */
1789 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
1790 break;
1792 if (crecp->flags & F_CNAME)
1794 char *cname_target = cache_get_cname_target(crecp);
1796 if (!dryrun)
1798 log_query(crecp->flags, name, NULL, record_source(crecp->uid));
1799 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1800 crec_ttl(crecp, now), &nameoffset,
1801 T_CNAME, C_IN, "d", cname_target))
1802 anscount++;
1805 strcpy(name, cname_target);
1806 /* check if target interface_name */
1807 if (crecp->addr.cname.uid == -1)
1808 goto intname_restart;
1809 else
1810 goto cname_restart;
1813 if (crecp->flags & F_NEG)
1815 ans = 1;
1816 auth = 0;
1817 if (crecp->flags & F_NXDOMAIN)
1818 nxdomain = 1;
1819 if (!dryrun)
1820 log_query(crecp->flags, name, NULL, NULL);
1822 else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
1824 /* If we are returning local answers depending on network,
1825 filter here. */
1826 if (localise &&
1827 (crecp->flags & F_HOSTS) &&
1828 !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1829 continue;
1831 if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1832 auth = 0;
1834 ans = 1;
1835 if (!dryrun)
1837 log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
1838 record_source(crecp->uid));
1840 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1841 crec_ttl(crecp, now), NULL, type, C_IN,
1842 type == T_A ? "4" : "6", &crecp->addr))
1843 anscount++;
1846 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
1848 else if (is_name_synthetic(flag, name, &addr))
1850 ans = 1;
1851 if (!dryrun)
1853 log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
1854 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1855 daemon->local_ttl, NULL, type, C_IN, type == T_A ? "4" : "6", &addr))
1856 anscount++;
1861 if (qtype == T_CNAME || qtype == T_ANY)
1863 if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME)) &&
1864 (qtype == T_CNAME || (crecp->flags & (F_HOSTS | F_DHCP))))
1866 ans = 1;
1867 if (!dryrun)
1869 log_query(crecp->flags, name, NULL, record_source(crecp->uid));
1870 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1871 crec_ttl(crecp, now), &nameoffset,
1872 T_CNAME, C_IN, "d", cache_get_cname_target(crecp)))
1873 anscount++;
1878 if (qtype == T_MX || qtype == T_ANY)
1880 int found = 0;
1881 for (rec = daemon->mxnames; rec; rec = rec->next)
1882 if (!rec->issrv && hostname_isequal(name, rec->name))
1884 ans = found = 1;
1885 if (!dryrun)
1887 int offset;
1888 log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
1889 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1890 &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
1892 anscount++;
1893 if (rec->target)
1894 rec->offset = offset;
1899 if (!found && (option_bool(OPT_SELFMX) || option_bool(OPT_LOCALMX)) &&
1900 cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP))
1902 ans = 1;
1903 if (!dryrun)
1905 log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
1906 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
1907 T_MX, C_IN, "sd", 1,
1908 option_bool(OPT_SELFMX) ? name : daemon->mxtarget))
1909 anscount++;
1914 if (qtype == T_SRV || qtype == T_ANY)
1916 int found = 0;
1917 struct mx_srv_record *move = NULL, **up = &daemon->mxnames;
1919 for (rec = daemon->mxnames; rec; rec = rec->next)
1920 if (rec->issrv && hostname_isequal(name, rec->name))
1922 found = ans = 1;
1923 if (!dryrun)
1925 int offset;
1926 log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>");
1927 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1928 &offset, T_SRV, C_IN, "sssd",
1929 rec->priority, rec->weight, rec->srvport, rec->target))
1931 anscount++;
1932 if (rec->target)
1933 rec->offset = offset;
1937 /* unlink first SRV record found */
1938 if (!move)
1940 move = rec;
1941 *up = rec->next;
1943 else
1944 up = &rec->next;
1946 else
1947 up = &rec->next;
1949 /* put first SRV record back at the end. */
1950 if (move)
1952 *up = move;
1953 move->next = NULL;
1956 if (!found && option_bool(OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
1958 ans = 1;
1959 if (!dryrun)
1960 log_query(F_CONFIG | F_NEG, name, NULL, NULL);
1964 if (qtype == T_NAPTR || qtype == T_ANY)
1966 struct naptr *na;
1967 for (na = daemon->naptr; na; na = na->next)
1968 if (hostname_isequal(name, na->name))
1970 ans = 1;
1971 if (!dryrun)
1973 log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>");
1974 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1975 NULL, T_NAPTR, C_IN, "sszzzd",
1976 na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
1977 anscount++;
1982 if (qtype == T_MAILB)
1983 ans = 1, nxdomain = 1;
1985 if (qtype == T_SOA && option_bool(OPT_FILTER))
1987 ans = 1;
1988 if (!dryrun)
1989 log_query(F_CONFIG | F_NEG, name, &addr, NULL);
1993 if (!ans)
1994 return 0; /* failed to answer a question */
1997 if (dryrun)
1999 dryrun = 0;
2000 goto rerun;
2003 /* create an additional data section, for stuff in SRV and MX record replies. */
2004 for (rec = daemon->mxnames; rec; rec = rec->next)
2005 if (rec->offset != 0)
2007 /* squash dupes */
2008 struct mx_srv_record *tmp;
2009 for (tmp = rec->next; tmp; tmp = tmp->next)
2010 if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
2011 tmp->offset = 0;
2013 crecp = NULL;
2014 while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
2016 #ifdef HAVE_IPV6
2017 int type = crecp->flags & F_IPV4 ? T_A : T_AAAA;
2018 #else
2019 int type = T_A;
2020 #endif
2021 if (crecp->flags & F_NEG)
2022 continue;
2024 if (add_resource_record(header, limit, NULL, rec->offset, &ansp,
2025 crec_ttl(crecp, now), NULL, type, C_IN,
2026 crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
2027 addncount++;
2031 /* done all questions, set up header and return length of result */
2032 /* clear authoritative and truncated flags, set QR flag */
2033 header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
2034 /* set RA flag */
2035 header->hb4 |= HB4_RA;
2037 /* authoritive - only hosts and DHCP derived names. */
2038 if (auth)
2039 header->hb3 |= HB3_AA;
2041 /* truncation */
2042 if (trunc)
2043 header->hb3 |= HB3_TC;
2045 if (nxdomain)
2046 SET_RCODE(header, NXDOMAIN);
2047 else
2048 SET_RCODE(header, NOERROR); /* no error */
2049 header->ancount = htons(anscount);
2050 header->nscount = htons(0);
2051 header->arcount = htons(addncount);
2052 return ansp - (unsigned char *)header;