Tomato 1.28
[tomato.git] / release / src / router / dnsmasq / src / rfc1035.c
blob3289bf3a86a762a3bbbb72e97e257c9e90d3e82d
1 /* dnsmasq is Copyright (c) 2000-2010 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"
19 static int add_resource_record(HEADER *header, char *limit, int *truncp,
20 unsigned int nameoffset, unsigned char **pp,
21 unsigned long ttl, unsigned int *offset, unsigned short type,
22 unsigned short class, char *format, ...);
24 #define CHECK_LEN(header, pp, plen, len) \
25 ((size_t)((pp) - (unsigned char *)(header) + (len)) <= (plen))
27 #define ADD_RDLEN(header, pp, plen, len) \
28 (!CHECK_LEN(header, pp, plen, len) ? 0 : (long)((pp) += (len)), 1)
30 static int extract_name(HEADER *header, size_t plen, unsigned char **pp,
31 char *name, int isExtract, int extrabytes)
33 unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL;
34 unsigned int j, l, hops = 0;
35 int retvalue = 1;
37 if (isExtract)
38 *cp = 0;
40 while (1)
42 unsigned int label_type;
44 if (!CHECK_LEN(header, p, plen, 1))
45 return 0;
47 if ((l = *p++) == 0)
48 /* end marker */
50 /* check that there are the correct no of bytes after the name */
51 if (!CHECK_LEN(header, p, plen, extrabytes))
52 return 0;
54 if (isExtract)
56 if (cp != (unsigned char *)name)
57 cp--;
58 *cp = 0; /* terminate: lose final period */
60 else if (*cp != 0)
61 retvalue = 2;
63 if (p1) /* we jumped via compression */
64 *pp = p1;
65 else
66 *pp = p;
68 return retvalue;
71 label_type = l & 0xc0;
73 if (label_type == 0xc0) /* pointer */
75 if (!CHECK_LEN(header, p, plen, 1))
76 return 0;
78 /* get offset */
79 l = (l&0x3f) << 8;
80 l |= *p++;
82 if (!p1) /* first jump, save location to go back to */
83 p1 = p;
85 hops++; /* break malicious infinite loops */
86 if (hops > 255)
87 return 0;
89 p = l + (unsigned char *)header;
91 else if (label_type == 0x80)
92 return 0; /* reserved */
93 else if (label_type == 0x40)
94 { /* ELT */
95 unsigned int count, digs;
97 if ((l & 0x3f) != 1)
98 return 0; /* we only understand bitstrings */
100 if (!isExtract)
101 return 0; /* Cannot compare bitsrings */
103 count = *p++;
104 if (count == 0)
105 count = 256;
106 digs = ((count-1)>>2)+1;
108 /* output is \[x<hex>/siz]. which is digs+9 chars */
109 if (cp - (unsigned char *)name + digs + 9 >= MAXDNAME)
110 return 0;
111 if (!CHECK_LEN(header, p, plen, (count-1)>>3))
112 return 0;
114 *cp++ = '\\';
115 *cp++ = '[';
116 *cp++ = 'x';
117 for (j=0; j<digs; j++)
119 unsigned int dig;
120 if (j%2 == 0)
121 dig = *p >> 4;
122 else
123 dig = *p++ & 0x0f;
125 *cp++ = dig < 10 ? dig + '0' : dig + 'A' - 10;
127 cp += sprintf((char *)cp, "/%d]", count);
128 /* do this here to overwrite the zero char from sprintf */
129 *cp++ = '.';
131 else
132 { /* label_type = 0 -> label. */
133 if (cp - (unsigned char *)name + l + 1 >= MAXDNAME)
134 return 0;
135 if (!CHECK_LEN(header, p, plen, l))
136 return 0;
138 for(j=0; j<l; j++, p++)
139 if (isExtract)
141 unsigned char c = *p;
142 if (isascii(c) && !iscntrl(c) && c != '.')
143 *cp++ = *p;
144 else
145 return 0;
147 else
149 unsigned char c1 = *cp, c2 = *p;
151 if (c1 == 0)
152 retvalue = 2;
153 else
155 cp++;
156 if (c1 >= 'A' && c1 <= 'Z')
157 c1 += 'a' - 'A';
158 if (c2 >= 'A' && c2 <= 'Z')
159 c2 += 'a' - 'A';
161 if (c1 != c2)
162 retvalue = 2;
166 if (isExtract)
167 *cp++ = '.';
168 else if (*cp != 0 && *cp++ != '.')
169 retvalue = 2;
174 /* Max size of input string (for IPv6) is 75 chars.) */
175 #define MAXARPANAME 75
176 static int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
178 int j;
179 char name[MAXARPANAME+1], *cp1;
180 unsigned char *addr = (unsigned char *)addrp;
181 char *lastchunk = NULL, *penchunk = NULL;
183 if (strlen(namein) > MAXARPANAME)
184 return 0;
186 memset(addrp, 0, sizeof(struct all_addr));
188 /* turn name into a series of asciiz strings */
189 /* j counts no of labels */
190 for(j = 1,cp1 = name; *namein; cp1++, namein++)
191 if (*namein == '.')
193 penchunk = lastchunk;
194 lastchunk = cp1 + 1;
195 *cp1 = 0;
196 j++;
198 else
199 *cp1 = *namein;
201 *cp1 = 0;
203 if (j<3)
204 return 0;
206 if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr"))
208 /* IP v4 */
209 /* address arives as a name of the form
210 www.xxx.yyy.zzz.in-addr.arpa
211 some of the low order address octets might be missing
212 and should be set to zero. */
213 for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
215 /* check for digits only (weeds out things like
216 50.0/24.67.28.64.in-addr.arpa which are used
217 as CNAME targets according to RFC 2317 */
218 char *cp;
219 for (cp = cp1; *cp; cp++)
220 if (!isdigit((int)*cp))
221 return 0;
223 addr[3] = addr[2];
224 addr[2] = addr[1];
225 addr[1] = addr[0];
226 addr[0] = atoi(cp1);
229 return F_IPV4;
231 #ifdef HAVE_IPV6
232 else if (hostname_isequal(penchunk, "ip6") &&
233 (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa")))
235 /* IP v6:
236 Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
237 or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]
239 Note that most of these the various reprentations are obsolete and
240 left-over from the many DNS-for-IPv6 wars. We support all the formats
241 that we can since there is no reason not to.
244 if (*name == '\\' && *(name+1) == '[' &&
245 (*(name+2) == 'x' || *(name+2) == 'X'))
247 for (j = 0, cp1 = name+3; *cp1 && isxdigit((int) *cp1) && j < 32; cp1++, j++)
249 char xdig[2];
250 xdig[0] = *cp1;
251 xdig[1] = 0;
252 if (j%2)
253 addr[j/2] |= strtol(xdig, NULL, 16);
254 else
255 addr[j/2] = strtol(xdig, NULL, 16) << 4;
258 if (*cp1 == '/' && j == 32)
259 return F_IPV6;
261 else
263 for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
265 if (*(cp1+1) || !isxdigit((int)*cp1))
266 return 0;
268 for (j = sizeof(struct all_addr)-1; j>0; j--)
269 addr[j] = (addr[j] >> 4) | (addr[j-1] << 4);
270 addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
273 return F_IPV6;
276 #endif
278 return 0;
281 static unsigned char *skip_name(unsigned char *ansp, HEADER *header, size_t plen, int extrabytes)
283 while(1)
285 unsigned int label_type;
287 if (!CHECK_LEN(header, ansp, plen, 1))
288 return NULL;
290 label_type = (*ansp) & 0xc0;
292 if (label_type == 0xc0)
294 /* pointer for compression. */
295 ansp += 2;
296 break;
298 else if (label_type == 0x80)
299 return NULL; /* reserved */
300 else if (label_type == 0x40)
302 /* Extended label type */
303 unsigned int count;
305 if (!CHECK_LEN(header, ansp, plen, 2))
306 return NULL;
308 if (((*ansp++) & 0x3f) != 1)
309 return NULL; /* we only understand bitstrings */
311 count = *(ansp++); /* Bits in bitstring */
313 if (count == 0) /* count == 0 means 256 bits */
314 ansp += 32;
315 else
316 ansp += ((count-1)>>3)+1;
318 else
319 { /* label type == 0 Bottom six bits is length */
320 unsigned int len = (*ansp++) & 0x3f;
322 if (!ADD_RDLEN(header, ansp, plen, len))
323 return NULL;
325 if (len == 0)
326 break; /* zero length label marks the end. */
330 if (!CHECK_LEN(header, ansp, plen, extrabytes))
331 return NULL;
333 return ansp;
336 static unsigned char *skip_questions(HEADER *header, size_t plen)
338 int q;
339 unsigned char *ansp = (unsigned char *)(header+1);
341 for (q = ntohs(header->qdcount); q != 0; q--)
343 if (!(ansp = skip_name(ansp, header, plen, 4)))
344 return NULL;
345 ansp += 4; /* class and type */
348 return ansp;
351 static unsigned char *skip_section(unsigned char *ansp, int count, HEADER *header, size_t plen)
353 int i, rdlen;
355 for (i = 0; i < count; i++)
357 if (!(ansp = skip_name(ansp, header, plen, 10)))
358 return NULL;
359 ansp += 8; /* type, class, TTL */
360 GETSHORT(rdlen, ansp);
361 if (!ADD_RDLEN(header, ansp, plen, rdlen))
362 return NULL;
365 return ansp;
368 /* CRC the question section. This is used to safely detect query
369 retransmision and to detect answers to questions we didn't ask, which
370 might be poisoning attacks. Note that we decode the name rather
371 than CRC the raw bytes, since replies might be compressed differently.
372 We ignore case in the names for the same reason. Return all-ones
373 if there is not question section. */
374 unsigned int questions_crc(HEADER *header, size_t plen, char *name)
376 int q;
377 unsigned int crc = 0xffffffff;
378 unsigned char *p1, *p = (unsigned char *)(header+1);
380 for (q = ntohs(header->qdcount); q != 0; q--)
382 if (!extract_name(header, plen, &p, name, 1, 4))
383 return crc; /* bad packet */
385 for (p1 = (unsigned char *)name; *p1; p1++)
387 int i = 8;
388 char c = *p1;
390 if (c >= 'A' && c <= 'Z')
391 c += 'a' - 'A';
393 crc ^= c << 24;
394 while (i--)
395 crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
398 /* CRC the class and type as well */
399 for (p1 = p; p1 < p+4; p1++)
401 int i = 8;
402 crc ^= *p1 << 24;
403 while (i--)
404 crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
407 p += 4;
408 if (!CHECK_LEN(header, p, plen, 0))
409 return crc; /* bad packet */
412 return crc;
416 size_t resize_packet(HEADER *header, size_t plen, unsigned char *pheader, size_t hlen)
418 unsigned char *ansp = skip_questions(header, plen);
420 /* if packet is malformed, just return as-is. */
421 if (!ansp)
422 return plen;
424 if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
425 header, plen)))
426 return plen;
428 /* restore pseudoheader */
429 if (pheader && ntohs(header->arcount) == 0)
431 /* must use memmove, may overlap */
432 memmove(ansp, pheader, hlen);
433 header->arcount = htons(1);
434 ansp += hlen;
437 return ansp - (unsigned char *)header;
440 unsigned char *find_pseudoheader(HEADER *header, size_t plen, size_t *len, unsigned char **p, int *is_sign)
442 /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
443 also return length of pseudoheader in *len and pointer to the UDP size in *p
444 Finally, check to see if a packet is signed. If it is we cannot change a single bit before
445 forwarding. We look for SIG and TSIG in the addition section, and TKEY queries (for GSS-TSIG) */
447 int i, arcount = ntohs(header->arcount);
448 unsigned char *ansp = (unsigned char *)(header+1);
449 unsigned short rdlen, type, class;
450 unsigned char *ret = NULL;
452 if (is_sign)
454 *is_sign = 0;
456 if (header->opcode == QUERY)
458 for (i = ntohs(header->qdcount); i != 0; i--)
460 if (!(ansp = skip_name(ansp, header, plen, 4)))
461 return NULL;
463 GETSHORT(type, ansp);
464 GETSHORT(class, ansp);
466 if (class == C_IN && type == T_TKEY)
467 *is_sign = 1;
471 else
473 if (!(ansp = skip_questions(header, plen)))
474 return NULL;
477 if (arcount == 0)
478 return NULL;
480 if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount), header, plen)))
481 return NULL;
483 for (i = 0; i < arcount; i++)
485 unsigned char *save, *start = ansp;
486 if (!(ansp = skip_name(ansp, header, plen, 10)))
487 return NULL;
489 GETSHORT(type, ansp);
490 save = ansp;
491 GETSHORT(class, ansp);
492 ansp += 4; /* TTL */
493 GETSHORT(rdlen, ansp);
494 if (!ADD_RDLEN(header, ansp, plen, rdlen))
495 return NULL;
496 if (type == T_OPT)
498 if (len)
499 *len = ansp - start;
500 if (p)
501 *p = save;
502 ret = start;
504 else if (is_sign &&
505 i == arcount - 1 &&
506 class == C_ANY &&
507 (type == T_SIG || type == T_TSIG))
508 *is_sign = 1;
511 return ret;
515 /* is addr in the non-globally-routed IP space? */
516 static int private_net(struct in_addr addr, int ban_localhost)
518 in_addr_t ip_addr = ntohl(addr.s_addr);
520 return
521 (((ip_addr & 0xFF000000) == 0x7F000000) && ban_localhost) /* 127.0.0.0/8 (loopback) */ ||
522 ((ip_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168.0.0/16 (private) */ ||
523 ((ip_addr & 0xFF000000) == 0x0A000000) /* 10.0.0.0/8 (private) */ ||
524 ((ip_addr & 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12 (private) */ ||
525 ((ip_addr & 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */ ;
528 static unsigned char *do_doctor(unsigned char *p, int count, HEADER *header, size_t qlen, char *name)
530 int i, qtype, qclass, rdlen;
531 unsigned long ttl;
533 for (i = count; i != 0; i--)
535 if (name && (daemon->options & OPT_LOG))
537 if (!extract_name(header, qlen, &p, name, 1, 10))
538 return 0;
540 else if (!(p = skip_name(p, header, qlen, 10)))
541 return 0; /* bad packet */
543 GETSHORT(qtype, p);
544 GETSHORT(qclass, p);
545 GETLONG(ttl, p);
546 GETSHORT(rdlen, p);
548 if (qclass == C_IN && qtype == T_A)
550 struct doctor *doctor;
551 struct in_addr addr;
553 if (!CHECK_LEN(header, p, qlen, INADDRSZ))
554 return 0;
556 /* alignment */
557 memcpy(&addr, p, INADDRSZ);
559 for (doctor = daemon->doctors; doctor; doctor = doctor->next)
561 if (doctor->end.s_addr == 0)
563 if (!is_same_net(doctor->in, addr, doctor->mask))
564 continue;
566 else if (ntohl(doctor->in.s_addr) > ntohl(addr.s_addr) ||
567 ntohl(doctor->end.s_addr) < ntohl(addr.s_addr))
568 continue;
570 addr.s_addr &= ~doctor->mask.s_addr;
571 addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
572 /* Since we munged the data, the server it came from is no longer authoritative */
573 header->aa = 0;
574 memcpy(p, &addr, INADDRSZ);
575 break;
578 else if (qtype == T_TXT && name && (daemon->options & OPT_LOG))
580 unsigned char *p1 = p;
581 if (!CHECK_LEN(header, p1, qlen, rdlen))
582 return 0;
583 while ((p1 - p) < rdlen)
585 unsigned int i, len = *p1;
586 unsigned char *p2 = p1;
587 /* make counted string zero-term and sanitise */
588 for (i = 0; i < len; i++)
589 if (isprint(*(p2+1)))
591 *p2 = *(p2+1);
592 p2++;
594 *p2 = 0;
595 my_syslog(LOG_DEBUG, "reply %s is %s", name, p1);
596 /* restore */
597 memmove(p1 + 1, p1, len);
598 *p1 = len;
599 p1 += len+1;
603 if (!ADD_RDLEN(header, p, qlen, rdlen))
604 return 0; /* bad packet */
607 return p;
610 static int find_soa(HEADER *header, size_t qlen, char *name)
612 unsigned char *p;
613 int qtype, qclass, rdlen;
614 unsigned long ttl, minttl = ULONG_MAX;
615 int i, found_soa = 0;
617 /* first move to NS section and find TTL from any SOA section */
618 if (!(p = skip_questions(header, qlen)) ||
619 !(p = do_doctor(p, ntohs(header->ancount), header, qlen, name)))
620 return 0; /* bad packet */
622 for (i = ntohs(header->nscount); i != 0; i--)
624 if (!(p = skip_name(p, header, qlen, 10)))
625 return 0; /* bad packet */
627 GETSHORT(qtype, p);
628 GETSHORT(qclass, p);
629 GETLONG(ttl, p);
630 GETSHORT(rdlen, p);
632 if ((qclass == C_IN) && (qtype == T_SOA))
634 found_soa = 1;
635 if (ttl < minttl)
636 minttl = ttl;
638 /* MNAME */
639 if (!(p = skip_name(p, header, qlen, 0)))
640 return 0;
641 /* RNAME */
642 if (!(p = skip_name(p, header, qlen, 20)))
643 return 0;
644 p += 16; /* SERIAL REFRESH RETRY EXPIRE */
646 GETLONG(ttl, p); /* minTTL */
647 if (ttl < minttl)
648 minttl = ttl;
650 else if (!ADD_RDLEN(header, p, qlen, rdlen))
651 return 0; /* bad packet */
654 /* rewrite addresses in additioal section too */
655 if (!do_doctor(p, ntohs(header->arcount), header, qlen, NULL))
656 return 0;
658 if (!found_soa)
659 minttl = daemon->neg_ttl;
661 return minttl;
664 /* Note that the following code can create CNAME chains that don't point to a real record,
665 either because of lack of memory, or lack of SOA records. These are treated by the cache code as
666 expired and cleaned out that way.
667 Return 1 if we reject an address because it look like part of dns-rebinding attack. */
668 int extract_addresses(HEADER *header, size_t qlen, char *name, time_t now, int is_sign, int check_rebind)
670 unsigned char *p, *p1, *endrr, *namep;
671 int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
672 unsigned long ttl = 0;
673 struct all_addr addr;
675 cache_start_insert();
677 /* find_soa is needed for dns_doctor and logging side-effects, so don't call it lazily if there are any. */
678 if (daemon->doctors || (daemon->options & OPT_LOG))
680 searched_soa = 1;
681 ttl = find_soa(header, qlen, name);
684 /* go through the questions. */
685 p = (unsigned char *)(header+1);
687 for (i = ntohs(header->qdcount); i != 0; i--)
689 int found = 0, cname_count = 5;
690 struct crec *cpp = NULL;
691 int flags = header->rcode == NXDOMAIN ? F_NXDOMAIN : 0;
692 unsigned long cttl = ULONG_MAX, attl;
694 namep = p;
695 if (!extract_name(header, qlen, &p, name, 1, 4))
696 return 0; /* bad packet */
698 GETSHORT(qtype, p);
699 GETSHORT(qclass, p);
701 if (qclass != C_IN)
702 continue;
704 /* PTRs: we chase CNAMEs here, since we have no way to
705 represent them in the cache. */
706 if (qtype == T_PTR)
708 int name_encoding = in_arpa_name_2_addr(name, &addr);
710 if (!name_encoding)
711 continue;
713 if (!(flags & F_NXDOMAIN))
715 cname_loop:
716 if (!(p1 = skip_questions(header, qlen)))
717 return 0;
719 for (j = ntohs(header->ancount); j != 0; j--)
721 unsigned char *tmp = namep;
722 /* the loop body overwrites the original name, so get it back here. */
723 if (!extract_name(header, qlen, &tmp, name, 1, 0) ||
724 !(res = extract_name(header, qlen, &p1, name, 0, 10)))
725 return 0; /* bad packet */
727 GETSHORT(aqtype, p1);
728 GETSHORT(aqclass, p1);
729 GETLONG(attl, p1);
730 if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
732 (p1) -= NS_INT32SZ;
733 PUTLONG(daemon->max_ttl, p1);
735 GETSHORT(ardlen, p1);
736 endrr = p1+ardlen;
738 /* TTL of record is minimum of CNAMES and PTR */
739 if (attl < cttl)
740 cttl = attl;
742 if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
744 if (!extract_name(header, qlen, &p1, name, 1, 0))
745 return 0;
747 if (aqtype == T_CNAME)
749 if (!cname_count--)
750 return 0; /* looped CNAMES */
751 goto cname_loop;
754 cache_insert(name, &addr, now, cttl, name_encoding | F_REVERSE);
755 found = 1;
758 p1 = endrr;
759 if (!CHECK_LEN(header, p1, qlen, 0))
760 return 0; /* bad packet */
764 if (!found && !(daemon->options & OPT_NO_NEG))
766 if (!searched_soa)
768 searched_soa = 1;
769 ttl = find_soa(header, qlen, NULL);
771 if (ttl)
772 cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags);
775 else
777 /* everything other than PTR */
778 struct crec *newc;
779 int addrlen;
781 if (qtype == T_A)
783 addrlen = INADDRSZ;
784 flags |= F_IPV4;
786 #ifdef HAVE_IPV6
787 else if (qtype == T_AAAA)
789 addrlen = IN6ADDRSZ;
790 flags |= F_IPV6;
792 #endif
793 else
794 continue;
796 if (!(flags & F_NXDOMAIN))
798 cname_loop1:
799 if (!(p1 = skip_questions(header, qlen)))
800 return 0;
802 for (j = ntohs(header->ancount); j != 0; j--)
804 if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
805 return 0; /* bad packet */
807 GETSHORT(aqtype, p1);
808 GETSHORT(aqclass, p1);
809 GETLONG(attl, p1);
810 if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
812 (p1) -= NS_INT32SZ;
813 PUTLONG(daemon->max_ttl, p1);
815 GETSHORT(ardlen, p1);
816 endrr = p1+ardlen;
818 if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
820 if (aqtype == T_CNAME)
822 if (!cname_count--)
823 return 0; /* looped CNAMES */
824 newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD);
825 if (newc && cpp)
827 cpp->addr.cname.cache = newc;
828 cpp->addr.cname.uid = newc->uid;
831 cpp = newc;
832 if (attl < cttl)
833 cttl = attl;
835 if (!extract_name(header, qlen, &p1, name, 1, 0))
836 return 0;
837 goto cname_loop1;
839 else
841 found = 1;
843 /* copy address into aligned storage */
844 if (!CHECK_LEN(header, p1, qlen, addrlen))
845 return 0; /* bad packet */
846 memcpy(&addr, p1, addrlen);
848 /* check for returned address in private space */
849 if (check_rebind &&
850 (flags & F_IPV4) &&
851 private_net(addr.addr.addr4, !(daemon->options & OPT_LOCAL_REBIND)))
852 return 1;
854 newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
855 if (newc && cpp)
857 cpp->addr.cname.cache = newc;
858 cpp->addr.cname.uid = newc->uid;
860 cpp = NULL;
864 p1 = endrr;
865 if (!CHECK_LEN(header, p1, qlen, 0))
866 return 0; /* bad packet */
870 if (!found && !(daemon->options & OPT_NO_NEG))
872 if (!searched_soa)
874 searched_soa = 1;
875 ttl = find_soa(header, qlen, NULL);
877 /* If there's no SOA to get the TTL from, but there is a CNAME
878 pointing at this, inherit its TTL */
879 if (ttl || cpp)
881 newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags);
882 if (newc && cpp)
884 cpp->addr.cname.cache = newc;
885 cpp->addr.cname.uid = newc->uid;
892 /* Don't put stuff from a truncated packet into the cache, but do everything else */
893 if (!header->tc)
894 cache_end_insert();
896 return 0;
899 /* If the packet holds exactly one query
900 return F_IPV4 or F_IPV6 and leave the name from the query in name.
901 Abuse F_BIGNAME to indicate an NS query - yuck. */
903 unsigned short extract_request(HEADER *header, size_t qlen, char *name, unsigned short *typep)
905 unsigned char *p = (unsigned char *)(header+1);
906 int qtype, qclass;
908 if (typep)
909 *typep = 0;
911 if (ntohs(header->qdcount) != 1 || header->opcode != QUERY)
912 return 0; /* must be exactly one query. */
914 if (!extract_name(header, qlen, &p, name, 1, 4))
915 return 0; /* bad packet */
917 GETSHORT(qtype, p);
918 GETSHORT(qclass, p);
920 if (typep)
921 *typep = qtype;
923 if (qclass == C_IN)
925 if (qtype == T_A)
926 return F_IPV4;
927 if (qtype == T_AAAA)
928 return F_IPV6;
929 if (qtype == T_ANY)
930 return F_IPV4 | F_IPV6;
931 if (qtype == T_NS || qtype == T_SOA)
932 return F_QUERY | F_BIGNAME;
935 return F_QUERY;
939 size_t setup_reply(HEADER *header, size_t qlen,
940 struct all_addr *addrp, unsigned short flags, unsigned long ttl)
942 unsigned char *p = skip_questions(header, qlen);
944 header->qr = 1; /* response */
945 header->aa = 0; /* authoritive */
946 header->ra = 1; /* recursion if available */
947 header->tc = 0; /* not truncated */
948 header->nscount = htons(0);
949 header->arcount = htons(0);
950 header->ancount = htons(0); /* no answers unless changed below */
951 if (flags == F_NEG)
952 header->rcode = SERVFAIL; /* couldn't get memory */
953 else if (flags == F_NOERR)
954 header->rcode = NOERROR; /* empty domain */
955 else if (flags == F_NXDOMAIN)
956 header->rcode = NXDOMAIN;
957 else if (p && flags == F_IPV4)
958 { /* we know the address */
959 header->rcode = NOERROR;
960 header->ancount = htons(1);
961 header->aa = 1;
962 add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_A, C_IN, "4", addrp);
964 #ifdef HAVE_IPV6
965 else if (p && flags == F_IPV6)
967 header->rcode = NOERROR;
968 header->ancount = htons(1);
969 header->aa = 1;
970 add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
972 #endif
973 else /* nowhere to forward to */
974 header->rcode = REFUSED;
976 return p - (unsigned char *)header;
979 /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
980 int check_for_local_domain(char *name, time_t now)
982 struct crec *crecp;
983 struct mx_srv_record *mx;
984 struct txt_record *txt;
985 struct interface_name *intr;
986 struct ptr_record *ptr;
988 if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)) &&
989 (crecp->flags & (F_HOSTS | F_DHCP)))
990 return 1;
992 for (mx = daemon->mxnames; mx; mx = mx->next)
993 if (hostname_isequal(name, mx->name))
994 return 1;
996 for (txt = daemon->txt; txt; txt = txt->next)
997 if (hostname_isequal(name, txt->name))
998 return 1;
1000 for (intr = daemon->int_names; intr; intr = intr->next)
1001 if (hostname_isequal(name, intr->name))
1002 return 1;
1004 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1005 if (hostname_isequal(name, ptr->name))
1006 return 1;
1008 return 0;
1011 /* Is the packet a reply with the answer address equal to addr?
1012 If so mung is into an NXDOMAIN reply and also put that information
1013 in the cache. */
1014 int check_for_bogus_wildcard(HEADER *header, size_t qlen, char *name,
1015 struct bogus_addr *baddr, time_t now)
1017 unsigned char *p;
1018 int i, qtype, qclass, rdlen;
1019 unsigned long ttl;
1020 struct bogus_addr *baddrp;
1022 /* skip over questions */
1023 if (!(p = skip_questions(header, qlen)))
1024 return 0; /* bad packet */
1026 for (i = ntohs(header->ancount); i != 0; i--)
1028 if (!extract_name(header, qlen, &p, name, 1, 10))
1029 return 0; /* bad packet */
1031 GETSHORT(qtype, p);
1032 GETSHORT(qclass, p);
1033 GETLONG(ttl, p);
1034 GETSHORT(rdlen, p);
1036 if (qclass == C_IN && qtype == T_A)
1038 if (!CHECK_LEN(header, p, qlen, INADDRSZ))
1039 return 0;
1041 for (baddrp = baddr; baddrp; baddrp = baddrp->next)
1042 if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
1044 /* Found a bogus address. Insert that info here, since there no SOA record
1045 to get the ttl from in the normal processing */
1046 cache_start_insert();
1047 cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN | F_CONFIG);
1048 cache_end_insert();
1050 return 1;
1054 if (!ADD_RDLEN(header, p, qlen, rdlen))
1055 return 0;
1058 return 0;
1061 static int add_resource_record(HEADER *header, char *limit, int *truncp, unsigned int nameoffset, unsigned char **pp,
1062 unsigned long ttl, unsigned int *offset, unsigned short type, unsigned short class, char *format, ...)
1064 va_list ap;
1065 unsigned char *sav, *p = *pp;
1066 int j;
1067 unsigned short usval;
1068 long lval;
1069 char *sval;
1071 if (truncp && *truncp)
1072 return 0;
1074 PUTSHORT(nameoffset | 0xc000, p);
1075 PUTSHORT(type, p);
1076 PUTSHORT(class, p);
1077 PUTLONG(ttl, p); /* TTL */
1079 sav = p; /* Save pointer to RDLength field */
1080 PUTSHORT(0, p); /* Placeholder RDLength */
1082 va_start(ap, format); /* make ap point to 1st unamed argument */
1084 for (; *format; format++)
1085 switch (*format)
1087 #ifdef HAVE_IPV6
1088 case '6':
1089 sval = va_arg(ap, char *);
1090 memcpy(p, sval, IN6ADDRSZ);
1091 p += IN6ADDRSZ;
1092 break;
1093 #endif
1095 case '4':
1096 sval = va_arg(ap, char *);
1097 memcpy(p, sval, INADDRSZ);
1098 p += INADDRSZ;
1099 break;
1101 case 's':
1102 usval = va_arg(ap, int);
1103 PUTSHORT(usval, p);
1104 break;
1106 case 'l':
1107 lval = va_arg(ap, long);
1108 PUTLONG(lval, p);
1109 break;
1111 case 'd':
1112 /* get domain-name answer arg and store it in RDATA field */
1113 if (offset)
1114 *offset = p - (unsigned char *)header;
1115 p = do_rfc1035_name(p, va_arg(ap, char *));
1116 *p++ = 0;
1117 break;
1119 case 't':
1120 usval = va_arg(ap, int);
1121 sval = va_arg(ap, char *);
1122 memcpy(p, sval, usval);
1123 p += usval;
1124 break;
1126 case 'z':
1127 sval = va_arg(ap, char *);
1128 usval = sval ? strlen(sval) : 0;
1129 if (usval > 255)
1130 usval = 255;
1131 *p++ = (unsigned char)usval;
1132 memcpy(p, sval, usval);
1133 p += usval;
1134 break;
1137 va_end(ap); /* clean up variable argument pointer */
1139 j = p - sav - 2;
1140 PUTSHORT(j, sav); /* Now, store real RDLength */
1142 /* check for overflow of buffer */
1143 if (limit && ((unsigned char *)limit - p) < 0)
1145 if (truncp)
1146 *truncp = 1;
1147 return 0;
1150 *pp = p;
1151 return 1;
1154 static unsigned long crec_ttl(struct crec *crecp, time_t now)
1156 /* Return 0 ttl for DHCP entries, which might change
1157 before the lease expires. */
1159 if (crecp->flags & (F_IMMORTAL | F_DHCP))
1160 return daemon->local_ttl;
1162 /* Return the Max TTL value if it is lower then the actual TTL */
1163 if (daemon->max_ttl == 0 || ((unsigned)(crecp->ttd - now) < daemon->max_ttl))
1164 return crecp->ttd - now;
1165 else
1166 return daemon->max_ttl;
1170 /* return zero if we can't answer from cache, or packet size if we can */
1171 size_t answer_request(HEADER *header, char *limit, size_t qlen,
1172 struct in_addr local_addr, struct in_addr local_netmask, time_t now)
1174 char *name = daemon->namebuff;
1175 unsigned char *p, *ansp, *pheader;
1176 int qtype, qclass;
1177 struct all_addr addr;
1178 unsigned int nameoffset;
1179 unsigned short flag;
1180 int q, ans, anscount = 0, addncount = 0;
1181 int dryrun = 0, sec_reqd = 0;
1182 int is_sign;
1183 struct crec *crecp;
1184 int nxdomain = 0, auth = 1, trunc = 0;
1185 struct mx_srv_record *rec;
1187 /* If there is an RFC2671 pseudoheader then it will be overwritten by
1188 partial replies, so we have to do a dry run to see if we can answer
1189 the query. We check to see if the do bit is set, if so we always
1190 forward rather than answering from the cache, which doesn't include
1191 security information. */
1193 if (find_pseudoheader(header, qlen, NULL, &pheader, &is_sign))
1195 unsigned short udpsz, ext_rcode, flags;
1196 unsigned char *psave = pheader;
1198 GETSHORT(udpsz, pheader);
1199 GETSHORT(ext_rcode, pheader);
1200 GETSHORT(flags, pheader);
1202 sec_reqd = flags & 0x8000; /* do bit */
1204 /* If our client is advertising a larger UDP packet size
1205 than we allow, trim it so that we don't get an overlarge
1206 response from upstream */
1208 if (!is_sign && (udpsz > daemon->edns_pktsz))
1209 PUTSHORT(daemon->edns_pktsz, psave);
1211 dryrun = 1;
1214 if (ntohs(header->qdcount) == 0 || header->opcode != QUERY )
1215 return 0;
1217 for (rec = daemon->mxnames; rec; rec = rec->next)
1218 rec->offset = 0;
1220 rerun:
1221 /* determine end of question section (we put answers there) */
1222 if (!(ansp = skip_questions(header, qlen)))
1223 return 0; /* bad packet */
1225 /* now process each question, answers go in RRs after the question */
1226 p = (unsigned char *)(header+1);
1228 for (q = ntohs(header->qdcount); q != 0; q--)
1230 /* save pointer to name for copying into answers */
1231 nameoffset = p - (unsigned char *)header;
1233 /* now extract name as .-concatenated string into name */
1234 if (!extract_name(header, qlen, &p, name, 1, 4))
1235 return 0; /* bad packet */
1237 GETSHORT(qtype, p);
1238 GETSHORT(qclass, p);
1240 ans = 0; /* have we answered this question */
1242 if (qtype == T_TXT || qtype == T_ANY)
1244 struct txt_record *t;
1245 for(t = daemon->txt; t ; t = t->next)
1247 if (t->class == qclass && hostname_isequal(name, t->name))
1249 ans = 1;
1250 if (!dryrun)
1252 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<TXT>");
1253 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1254 daemon->local_ttl, NULL,
1255 T_TXT, t->class, "t", t->len, t->txt))
1256 anscount++;
1263 if (qclass == C_IN)
1265 if (qtype == T_PTR || qtype == T_ANY)
1267 /* see if it's w.z.y.z.in-addr.arpa format */
1268 int is_arpa = in_arpa_name_2_addr(name, &addr);
1269 struct ptr_record *ptr;
1270 struct interface_name* intr = NULL;
1272 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1273 if (hostname_isequal(name, ptr->name))
1274 break;
1276 if (is_arpa == F_IPV4)
1277 for (intr = daemon->int_names; intr; intr = intr->next)
1279 if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr)
1280 break;
1281 else
1282 while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1283 intr = intr->next;
1286 if (intr)
1288 ans = 1;
1289 if (!dryrun)
1291 log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
1292 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1293 daemon->local_ttl, NULL,
1294 T_PTR, C_IN, "d", intr->name))
1295 anscount++;
1298 else if (ptr)
1300 ans = 1;
1301 if (!dryrun)
1303 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<PTR>");
1304 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1305 if (hostname_isequal(name, ptr->name) &&
1306 add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1307 daemon->local_ttl, NULL,
1308 T_PTR, C_IN, "d", ptr->ptr))
1309 anscount++;
1313 else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
1316 /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
1317 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1318 continue;
1320 if (crecp->flags & F_NEG)
1322 ans = 1;
1323 auth = 0;
1324 if (crecp->flags & F_NXDOMAIN)
1325 nxdomain = 1;
1326 if (!dryrun)
1327 log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
1329 else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
1331 ans = 1;
1332 if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1333 auth = 0;
1334 if (!dryrun)
1336 log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
1337 record_source(crecp->uid));
1339 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1340 crec_ttl(crecp, now), NULL,
1341 T_PTR, C_IN, "d", cache_get_name(crecp)))
1342 anscount++;
1345 } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
1346 else if (is_arpa == F_IPV4 &&
1347 (daemon->options & OPT_BOGUSPRIV) &&
1348 private_net(addr.addr.addr4, 1))
1350 /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
1351 ans = 1;
1352 nxdomain = 1;
1353 if (!dryrun)
1354 log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN,
1355 name, &addr, NULL);
1359 for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
1361 unsigned short type = T_A;
1363 if (flag == F_IPV6)
1364 #ifdef HAVE_IPV6
1365 type = T_AAAA;
1366 #else
1367 break;
1368 #endif
1370 if (qtype != type && qtype != T_ANY)
1371 continue;
1373 /* Check for "A for A" queries; be rather conservative
1374 about what looks like dotted-quad. */
1375 if (qtype == T_A)
1377 char *cp;
1378 unsigned int i, a;
1379 int x;
1381 for (cp = name, i = 0, a = 0; *cp; i++)
1383 if (!isdigit(*cp) || (x = strtol(cp, &cp, 10)) > 255)
1385 i = 5;
1386 break;
1389 a = (a << 8) + x;
1391 if (*cp == '.')
1392 cp++;
1395 if (i == 4)
1397 ans = 1;
1398 if (!dryrun)
1400 addr.addr.addr4.s_addr = htonl(a);
1401 log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
1402 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1403 daemon->local_ttl, NULL, type, C_IN, "4", &addr))
1404 anscount++;
1406 continue;
1410 /* interface name stuff */
1411 if (qtype == T_A)
1413 struct interface_name *intr;
1415 for (intr = daemon->int_names; intr; intr = intr->next)
1416 if (hostname_isequal(name, intr->name))
1417 break;
1419 if (intr)
1421 ans = 1;
1422 if (!dryrun)
1424 if ((addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr == (in_addr_t) -1)
1425 log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, NULL);
1426 else
1428 log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
1429 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1430 daemon->local_ttl, NULL, type, C_IN, "4", &addr))
1431 anscount++;
1434 continue;
1438 cname_restart:
1439 if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME)))
1441 int localise = 0;
1443 /* See if a putative address is on the network from which we recieved
1444 the query, is so we'll filter other answers. */
1445 if (local_addr.s_addr != 0 && (daemon->options & OPT_LOCALISE) && flag == F_IPV4)
1447 struct crec *save = crecp;
1448 do {
1449 if ((crecp->flags & F_HOSTS) &&
1450 is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1452 localise = 1;
1453 break;
1455 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
1456 crecp = save;
1461 /* don't answer wildcard queries with data not from /etc/hosts
1462 or DHCP leases */
1463 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1464 break;
1466 if (crecp->flags & F_CNAME)
1468 if (!dryrun)
1470 log_query(crecp->flags, name, NULL, record_source(crecp->uid));
1471 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1472 crec_ttl(crecp, now), &nameoffset,
1473 T_CNAME, C_IN, "d", cache_get_name(crecp->addr.cname.cache)))
1474 anscount++;
1477 strcpy(name, cache_get_name(crecp->addr.cname.cache));
1478 goto cname_restart;
1481 if (crecp->flags & F_NEG)
1483 ans = 1;
1484 auth = 0;
1485 if (crecp->flags & F_NXDOMAIN)
1486 nxdomain = 1;
1487 if (!dryrun)
1488 log_query(crecp->flags, name, NULL, NULL);
1490 else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
1492 /* If we are returning local answers depending on network,
1493 filter here. */
1494 if (localise &&
1495 (crecp->flags & F_HOSTS) &&
1496 !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1497 continue;
1499 if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1500 auth = 0;
1502 ans = 1;
1503 if (!dryrun)
1505 log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
1506 record_source(crecp->uid));
1508 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1509 crec_ttl(crecp, now), NULL, type, C_IN,
1510 type == T_A ? "4" : "6", &crecp->addr))
1511 anscount++;
1514 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
1518 if (qtype == T_MX || qtype == T_ANY)
1520 int found = 0;
1521 for (rec = daemon->mxnames; rec; rec = rec->next)
1522 if (!rec->issrv && hostname_isequal(name, rec->name))
1524 ans = found = 1;
1525 if (!dryrun)
1527 unsigned int offset;
1528 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>");
1529 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1530 &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
1532 anscount++;
1533 if (rec->target)
1534 rec->offset = offset;
1539 if (!found && (daemon->options & (OPT_SELFMX | OPT_LOCALMX)) &&
1540 cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP))
1542 ans = 1;
1543 if (!dryrun)
1545 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>");
1546 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
1547 T_MX, C_IN, "sd", 1,
1548 (daemon->options & OPT_SELFMX) ? name : daemon->mxtarget))
1549 anscount++;
1554 if (qtype == T_SRV || qtype == T_ANY)
1556 int found = 0;
1558 for (rec = daemon->mxnames; rec; rec = rec->next)
1559 if (rec->issrv && hostname_isequal(name, rec->name))
1561 found = ans = 1;
1562 if (!dryrun)
1564 unsigned int offset;
1565 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<SRV>");
1566 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1567 &offset, T_SRV, C_IN, "sssd",
1568 rec->priority, rec->weight, rec->srvport, rec->target))
1570 anscount++;
1571 if (rec->target)
1572 rec->offset = offset;
1577 if (!found && (daemon->options & OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
1579 ans = 1;
1580 if (!dryrun)
1581 log_query(F_CONFIG | F_NEG, name, NULL, NULL);
1585 if (qtype == T_NAPTR || qtype == T_ANY)
1587 struct naptr *na;
1588 for (na = daemon->naptr; na; na = na->next)
1589 if (hostname_isequal(name, na->name))
1591 ans = 1;
1592 if (!dryrun)
1594 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<NAPTR>");
1595 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1596 NULL, T_NAPTR, C_IN, "sszzzd",
1597 na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
1598 anscount++;
1603 if (qtype == T_MAILB)
1604 ans = 1, nxdomain = 1;
1606 if (qtype == T_SOA && (daemon->options & OPT_FILTER))
1608 ans = 1;
1609 if (!dryrun)
1610 log_query(F_CONFIG | F_NEG, name, &addr, NULL);
1614 if (!ans)
1615 return 0; /* failed to answer a question */
1618 if (dryrun)
1620 dryrun = 0;
1621 goto rerun;
1624 /* create an additional data section, for stuff in SRV and MX record replies. */
1625 for (rec = daemon->mxnames; rec; rec = rec->next)
1626 if (rec->offset != 0)
1628 /* squash dupes */
1629 struct mx_srv_record *tmp;
1630 for (tmp = rec->next; tmp; tmp = tmp->next)
1631 if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
1632 tmp->offset = 0;
1634 crecp = NULL;
1635 while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
1637 #ifdef HAVE_IPV6
1638 int type = crecp->flags & F_IPV4 ? T_A : T_AAAA;
1639 #else
1640 int type = T_A;
1641 #endif
1642 if (crecp->flags & F_NEG)
1643 continue;
1645 if (add_resource_record(header, limit, NULL, rec->offset, &ansp,
1646 crec_ttl(crecp, now), NULL, type, C_IN,
1647 crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
1648 addncount++;
1652 /* done all questions, set up header and return length of result */
1653 header->qr = 1; /* response */
1654 header->aa = auth; /* authoritive - only hosts and DHCP derived names. */
1655 header->ra = 1; /* recursion if available */
1656 header->tc = trunc; /* truncation */
1657 if (anscount == 0 && nxdomain)
1658 header->rcode = NXDOMAIN;
1659 else
1660 header->rcode = NOERROR; /* no error */
1661 header->ancount = htons(anscount);
1662 header->nscount = htons(0);
1663 header->arcount = htons(addncount);
1664 return ansp - (unsigned char *)header;