]> git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/rfc1035.c
import of dnsmasq-2.42.tar.gz
[people/ms/dnsmasq.git] / src / rfc1035.c
1 /* dnsmasq is Copyright (c) 2000-2007 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 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, ...);
23
24 static int extract_name(HEADER *header, size_t plen, unsigned char **pp,
25 char *name, int isExtract)
26 {
27 unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL;
28 unsigned int j, l, hops = 0;
29 int retvalue = 1;
30
31 if (isExtract)
32 *cp = 0;
33
34 while ((l = *p++))
35 {
36 unsigned int label_type = l & 0xc0;
37 if (label_type == 0xc0) /* pointer */
38 {
39 if ((size_t)(p - (unsigned char *)header) >= plen)
40 return 0;
41
42 /* get offset */
43 l = (l&0x3f) << 8;
44 l |= *p++;
45 if (l >= plen)
46 return 0;
47
48 if (!p1) /* first jump, save location to go back to */
49 p1 = p;
50
51 hops++; /* break malicious infinite loops */
52 if (hops > 255)
53 return 0;
54
55 p = l + (unsigned char *)header;
56 }
57 else if (label_type == 0x80)
58 return 0; /* reserved */
59 else if (label_type == 0x40)
60 { /* ELT */
61 unsigned int count, digs;
62
63 if ((l & 0x3f) != 1)
64 return 0; /* we only understand bitstrings */
65
66 if (!isExtract)
67 return 0; /* Cannot compare bitsrings */
68
69 count = *p++;
70 if (count == 0)
71 count = 256;
72 digs = ((count-1)>>2)+1;
73
74 /* output is \[x<hex>/siz]. which is digs+9 chars */
75 if (cp - (unsigned char *)name + digs + 9 >= MAXDNAME)
76 return 0;
77 if ((size_t)(p - (unsigned char *)header + ((count-1)>>3)) >= plen)
78 return 0;
79
80 *cp++ = '\\';
81 *cp++ = '[';
82 *cp++ = 'x';
83 for (j=0; j<digs; j++)
84 {
85 unsigned int dig;
86 if (j%2 == 0)
87 dig = *p >> 4;
88 else
89 dig = *p++ & 0x0f;
90
91 *cp++ = dig < 10 ? dig + '0' : dig + 'A' - 10;
92 }
93 cp += sprintf((char *)cp, "/%d]", count);
94 /* do this here to overwrite the zero char from sprintf */
95 *cp++ = '.';
96 }
97 else
98 { /* label_type = 0 -> label. */
99 if (cp - (unsigned char *)name + l + 1 >= MAXDNAME)
100 return 0;
101 if ((size_t)(p - (unsigned char *)header) >= plen)
102 return 0;
103 for(j=0; j<l; j++, p++)
104 if (isExtract)
105 {
106 if (legal_char(*p))
107 *cp++ = *p;
108 else
109 return 0;
110 }
111 else
112 {
113 unsigned char c1 = *cp, c2 = *p;
114
115 if (c1 == 0)
116 retvalue = 2;
117 else
118 {
119 cp++;
120 if (c1 >= 'A' && c1 <= 'Z')
121 c1 += 'a' - 'A';
122 if (c2 >= 'A' && c2 <= 'Z')
123 c2 += 'a' - 'A';
124
125 if (c1 != c2)
126 retvalue = 2;
127 }
128 }
129
130 if (isExtract)
131 *cp++ = '.';
132 else if (*cp != 0 && *cp++ != '.')
133 retvalue = 2;
134 }
135
136 if ((unsigned int)(p - (unsigned char *)header) >= plen)
137 return 0;
138 }
139
140 if (isExtract)
141 {
142 if (cp != (unsigned char *)name)
143 cp--;
144 *cp = 0; /* terminate: lose final period */
145 }
146 else if (*cp != 0)
147 retvalue = 2;
148
149 if (p1) /* we jumped via compression */
150 *pp = p1;
151 else
152 *pp = p;
153
154 return retvalue;
155 }
156
157 /* Max size of input string (for IPv6) is 75 chars.) */
158 #define MAXARPANAME 75
159 static int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
160 {
161 int j;
162 char name[MAXARPANAME+1], *cp1;
163 unsigned char *addr = (unsigned char *)addrp;
164 char *lastchunk = NULL, *penchunk = NULL;
165
166 if (strlen(namein) > MAXARPANAME)
167 return 0;
168
169 memset(addrp, 0, sizeof(struct all_addr));
170
171 /* turn name into a series of asciiz strings */
172 /* j counts no of labels */
173 for(j = 1,cp1 = name; *namein; cp1++, namein++)
174 if (*namein == '.')
175 {
176 penchunk = lastchunk;
177 lastchunk = cp1 + 1;
178 *cp1 = 0;
179 j++;
180 }
181 else
182 *cp1 = *namein;
183
184 *cp1 = 0;
185
186 if (j<3)
187 return 0;
188
189 if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr"))
190 {
191 /* IP v4 */
192 /* address arives as a name of the form
193 www.xxx.yyy.zzz.in-addr.arpa
194 some of the low order address octets might be missing
195 and should be set to zero. */
196 for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
197 {
198 /* check for digits only (weeds out things like
199 50.0/24.67.28.64.in-addr.arpa which are used
200 as CNAME targets according to RFC 2317 */
201 char *cp;
202 for (cp = cp1; *cp; cp++)
203 if (!isdigit((int)*cp))
204 return 0;
205
206 addr[3] = addr[2];
207 addr[2] = addr[1];
208 addr[1] = addr[0];
209 addr[0] = atoi(cp1);
210 }
211
212 return F_IPV4;
213 }
214 #ifdef HAVE_IPV6
215 else if (hostname_isequal(penchunk, "ip6") &&
216 (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa")))
217 {
218 /* IP v6:
219 Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
220 or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]
221
222 Note that most of these the various reprentations are obsolete and
223 left-over from the many DNS-for-IPv6 wars. We support all the formats
224 that we can since there is no reason not to.
225 */
226
227 if (*name == '\\' && *(name+1) == '[' &&
228 (*(name+2) == 'x' || *(name+2) == 'X'))
229 {
230 for (j = 0, cp1 = name+3; *cp1 && isxdigit((int) *cp1) && j < 32; cp1++, j++)
231 {
232 char xdig[2];
233 xdig[0] = *cp1;
234 xdig[1] = 0;
235 if (j%2)
236 addr[j/2] |= strtol(xdig, NULL, 16);
237 else
238 addr[j/2] = strtol(xdig, NULL, 16) << 4;
239 }
240
241 if (*cp1 == '/' && j == 32)
242 return F_IPV6;
243 }
244 else
245 {
246 for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
247 {
248 if (*(cp1+1) || !isxdigit((int)*cp1))
249 return 0;
250
251 for (j = sizeof(struct all_addr)-1; j>0; j--)
252 addr[j] = (addr[j] >> 4) | (addr[j-1] << 4);
253 addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
254 }
255
256 return F_IPV6;
257 }
258 }
259 #endif
260
261 return 0;
262 }
263
264 static unsigned char *skip_name(unsigned char *ansp, HEADER *header, size_t plen)
265 {
266 while(1)
267 {
268 unsigned int label_type = (*ansp) & 0xc0;
269
270 if ((unsigned int)(ansp - (unsigned char *)header) >= plen)
271 return NULL;
272
273 if (label_type == 0xc0)
274 {
275 /* pointer for compression. */
276 ansp += 2;
277 break;
278 }
279 else if (label_type == 0x80)
280 return NULL; /* reserved */
281 else if (label_type == 0x40)
282 {
283 /* Extended label type */
284 unsigned int count;
285
286 if (((*ansp++) & 0x3f) != 1)
287 return NULL; /* we only understand bitstrings */
288
289 count = *(ansp++); /* Bits in bitstring */
290
291 if (count == 0) /* count == 0 means 256 bits */
292 ansp += 32;
293 else
294 ansp += ((count-1)>>3)+1;
295 }
296 else
297 { /* label type == 0 Bottom six bits is length */
298 unsigned int len = (*ansp++) & 0x3f;
299 if (len == 0)
300 break; /* zero length label marks the end. */
301
302 ansp += len;
303 }
304 }
305
306 return ansp;
307 }
308
309 static unsigned char *skip_questions(HEADER *header, size_t plen)
310 {
311 int q;
312 unsigned char *ansp = (unsigned char *)(header+1);
313
314 for (q = ntohs(header->qdcount); q != 0; q--)
315 {
316 if (!(ansp = skip_name(ansp, header, plen)))
317 return NULL;
318 ansp += 4; /* class and type */
319 }
320 if ((unsigned int)(ansp - (unsigned char *)header) > plen)
321 return NULL;
322
323 return ansp;
324 }
325
326 static unsigned char *skip_section(unsigned char *ansp, int count, HEADER *header, size_t plen)
327 {
328 int i, rdlen;
329
330 for (i = 0; i < count; i++)
331 {
332 if (!(ansp = skip_name(ansp, header, plen)))
333 return NULL;
334 ansp += 8; /* type, class, TTL */
335 GETSHORT(rdlen, ansp);
336 if ((unsigned int)(ansp + rdlen - (unsigned char *)header) > plen)
337 return NULL;
338 ansp += rdlen;
339 }
340
341 return ansp;
342 }
343
344 /* CRC the question section. This is used to safely detect query
345 retransmision and to detect answers to questions we didn't ask, which
346 might be poisoning attacks. Note that we decode the name rather
347 than CRC the raw bytes, since replies might be compressed differently.
348 We ignore case in the names for the same reason. Return all-ones
349 if there is not question section. */
350 unsigned int questions_crc(HEADER *header, size_t plen, char *name)
351 {
352 int q;
353 unsigned int crc = 0xffffffff;
354 unsigned char *p1, *p = (unsigned char *)(header+1);
355
356 for (q = ntohs(header->qdcount); q != 0; q--)
357 {
358 if (!extract_name(header, plen, &p, name, 1))
359 return crc; /* bad packet */
360
361 for (p1 = (unsigned char *)name; *p1; p1++)
362 {
363 int i = 8;
364 char c = *p1;
365
366 if (c >= 'A' && c <= 'Z')
367 c += 'a' - 'A';
368
369 crc ^= c << 24;
370 while (i--)
371 crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
372 }
373
374 /* CRC the class and type as well */
375 for (p1 = p; p1 < p+4; p1++)
376 {
377 int i = 8;
378 crc ^= *p1 << 24;
379 while (i--)
380 crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
381 }
382
383 p += 4;
384 if ((unsigned int)(p - (unsigned char *)header) > plen)
385 return crc; /* bad packet */
386 }
387
388 return crc;
389 }
390
391
392 size_t resize_packet(HEADER *header, size_t plen, unsigned char *pheader, size_t hlen)
393 {
394 unsigned char *ansp = skip_questions(header, plen);
395
396 if (!ansp)
397 return 0;
398
399 if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
400 header, plen)))
401 return 0;
402
403 /* restore pseudoheader */
404 if (pheader && ntohs(header->arcount) == 0)
405 {
406 /* must use memmove, may overlap */
407 memmove(ansp, pheader, hlen);
408 header->arcount = htons(1);
409 ansp += hlen;
410 }
411
412 return ansp - (unsigned char *)header;
413 }
414
415 unsigned char *find_pseudoheader(HEADER *header, size_t plen, size_t *len, unsigned char **p, int *is_sign)
416 {
417 /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
418 also return length of pseudoheader in *len and pointer to the UDP size in *p
419 Finally, check to see if a packet is signed. If it is we cannot change a single bit before
420 forwarding. We look for SIG and TSIG in the addition section, and TKEY queries (for GSS-TSIG) */
421
422 int i, arcount = ntohs(header->arcount);
423 unsigned char *ansp = (unsigned char *)(header+1);
424 unsigned short rdlen, type, class;
425 unsigned char *ret = NULL;
426
427 if (is_sign)
428 {
429 *is_sign = 0;
430
431 if (header->opcode == QUERY)
432 {
433 for (i = ntohs(header->qdcount); i != 0; i--)
434 {
435 if (!(ansp = skip_name(ansp, header, plen)))
436 return NULL;
437
438 GETSHORT(type, ansp);
439 GETSHORT(class, ansp);
440
441 if (class == C_IN && type == T_TKEY)
442 *is_sign = 1;
443 }
444 }
445 }
446 else
447 {
448 if (!(ansp = skip_questions(header, plen)))
449 return NULL;
450 }
451
452 if (arcount == 0)
453 return NULL;
454
455 if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount), header, plen)))
456 return NULL;
457
458 for (i = 0; i < arcount; i++)
459 {
460 unsigned char *save, *start = ansp;
461 if (!(ansp = skip_name(ansp, header, plen)))
462 return NULL;
463
464 GETSHORT(type, ansp);
465 save = ansp;
466 GETSHORT(class, ansp);
467 ansp += 4; /* TTL */
468 GETSHORT(rdlen, ansp);
469 if ((size_t)(ansp + rdlen - (unsigned char *)header) > plen)
470 return NULL;
471 ansp += rdlen;
472 if (type == T_OPT)
473 {
474 if (len)
475 *len = ansp - start;
476 if (p)
477 *p = save;
478 ret = start;
479 }
480 else if (is_sign &&
481 i == arcount - 1 &&
482 class == C_ANY &&
483 (type == T_SIG || type == T_TSIG))
484 *is_sign = 1;
485 }
486
487 return ret;
488 }
489
490
491 /* is addr in the non-globally-routed IP space? */
492 static int private_net(struct in_addr addr)
493 {
494 in_addr_t ip_addr = ntohl(addr.s_addr);
495
496 return
497 ((ip_addr & 0xFF000000) == 0x7F000000) /* 127.0.0.0/8 (loopback) */ ||
498 ((ip_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168.0.0/16 (private) */ ||
499 ((ip_addr & 0xFF000000) == 0x0A000000) /* 10.0.0.0/8 (private) */ ||
500 ((ip_addr & 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12 (private) */ ||
501 ((ip_addr & 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */ ;
502 }
503
504 static unsigned char *do_doctor(unsigned char *p, int count, HEADER *header, size_t qlen)
505 {
506 int i, qtype, qclass, rdlen;
507 unsigned long ttl;
508
509 for (i = count; i != 0; i--)
510 {
511 if (!(p = skip_name(p, header, qlen)))
512 return 0; /* bad packet */
513
514 GETSHORT(qtype, p);
515 GETSHORT(qclass, p);
516 GETLONG(ttl, p);
517 GETSHORT(rdlen, p);
518
519 if ((qclass == C_IN) && (qtype == T_A))
520 {
521 struct doctor *doctor;
522 struct in_addr addr;
523
524 /* alignment */
525 memcpy(&addr, p, INADDRSZ);
526
527 for (doctor = daemon->doctors; doctor; doctor = doctor->next)
528 if (is_same_net(doctor->in, addr, doctor->mask))
529 {
530 addr.s_addr &= ~doctor->mask.s_addr;
531 addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
532 /* Since we munged the data, the server it came from is no longer authoritative */
533 header->aa = 0;
534 memcpy(p, &addr, INADDRSZ);
535 break;
536 }
537 }
538
539 p += rdlen;
540
541 if ((size_t)(p - (unsigned char *)header) > qlen)
542 return 0; /* bad packet */
543 }
544
545 return p;
546 }
547
548 static int find_soa(HEADER *header, size_t qlen)
549 {
550 unsigned char *p;
551 int qtype, qclass, rdlen;
552 unsigned long ttl, minttl = ULONG_MAX;
553 int i, found_soa = 0;
554
555 /* first move to NS section and find TTL from any SOA section */
556 if (!(p = skip_questions(header, qlen)) ||
557 !(p = do_doctor(p, ntohs(header->ancount), header, qlen)))
558 return 0; /* bad packet */
559
560 for (i = ntohs(header->nscount); i != 0; i--)
561 {
562 if (!(p = skip_name(p, header, qlen)))
563 return 0; /* bad packet */
564
565 GETSHORT(qtype, p);
566 GETSHORT(qclass, p);
567 GETLONG(ttl, p);
568 GETSHORT(rdlen, p);
569
570 if ((qclass == C_IN) && (qtype == T_SOA))
571 {
572 found_soa = 1;
573 if (ttl < minttl)
574 minttl = ttl;
575
576 /* MNAME */
577 if (!(p = skip_name(p, header, qlen)))
578 return 0;
579 /* RNAME */
580 if (!(p = skip_name(p, header, qlen)))
581 return 0;
582 p += 16; /* SERIAL REFRESH RETRY EXPIRE */
583
584 GETLONG(ttl, p); /* minTTL */
585 if (ttl < minttl)
586 minttl = ttl;
587 }
588 else
589 p += rdlen;
590
591 if ((size_t)(p - (unsigned char *)header) > qlen)
592 return 0; /* bad packet */
593 }
594
595 /* rewrite addresses in additioal section too */
596 if (!do_doctor(p, ntohs(header->arcount), header, qlen))
597 return 0;
598
599 if (!found_soa)
600 minttl = daemon->neg_ttl;
601
602 return minttl;
603 }
604
605 /* Note that the following code can create CNAME chains that don't point to a real record,
606 either because of lack of memory, or lack of SOA records. These are treated by the cache code as
607 expired and cleaned out that way.
608 Return 1 if we reject an address because it look like parct of dns-rebinding attack. */
609 int extract_addresses(HEADER *header, size_t qlen, char *name, time_t now)
610 {
611 unsigned char *p, *p1, *endrr, *namep;
612 int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
613 unsigned long ttl = 0;
614 struct all_addr addr;
615
616 cache_start_insert();
617
618 /* find_soa is needed for dns_doctor side-effects, so don't call it lazily if there are any. */
619 if (daemon->doctors)
620 {
621 searched_soa = 1;
622 ttl = find_soa(header, qlen);
623 }
624
625 /* go through the questions. */
626 p = (unsigned char *)(header+1);
627
628 for (i = ntohs(header->qdcount); i != 0; i--)
629 {
630 int found = 0, cname_count = 5;
631 struct crec *cpp = NULL;
632 int flags = header->rcode == NXDOMAIN ? F_NXDOMAIN : 0;
633 unsigned long cttl = ULONG_MAX, attl;
634
635 namep = p;
636 if (!extract_name(header, qlen, &p, name, 1))
637 return 0; /* bad packet */
638
639 GETSHORT(qtype, p);
640 GETSHORT(qclass, p);
641
642 if (qclass != C_IN)
643 continue;
644
645 /* PTRs: we chase CNAMEs here, since we have no way to
646 represent them in the cache. */
647 if (qtype == T_PTR)
648 {
649 int name_encoding = in_arpa_name_2_addr(name, &addr);
650
651 if (!name_encoding)
652 continue;
653
654 if (!(flags & F_NXDOMAIN))
655 {
656 cname_loop:
657 if (!(p1 = skip_questions(header, qlen)))
658 return 0;
659
660 for (j = ntohs(header->ancount); j != 0; j--)
661 {
662 unsigned char *tmp = namep;
663 /* the loop body overwrites the original name, so get it back here. */
664 if (!extract_name(header, qlen, &tmp, name, 1) ||
665 !(res = extract_name(header, qlen, &p1, name, 0)))
666 return 0; /* bad packet */
667
668 GETSHORT(aqtype, p1);
669 GETSHORT(aqclass, p1);
670 GETLONG(attl, p1);
671 GETSHORT(ardlen, p1);
672 endrr = p1+ardlen;
673
674 /* TTL of record is minimum of CNAMES and PTR */
675 if (attl < cttl)
676 cttl = attl;
677
678 if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
679 {
680 if (!extract_name(header, qlen, &p1, name, 1))
681 return 0;
682
683 if (aqtype == T_CNAME)
684 {
685 if (!cname_count--)
686 return 0; /* looped CNAMES */
687 goto cname_loop;
688 }
689
690 cache_insert(name, &addr, now, cttl, name_encoding | F_REVERSE);
691 found = 1;
692 }
693
694 p1 = endrr;
695 if ((size_t)(p1 - (unsigned char *)header) > qlen)
696 return 0; /* bad packet */
697 }
698 }
699
700 if (!found && !(daemon->options & OPT_NO_NEG))
701 {
702 if (!searched_soa)
703 {
704 searched_soa = 1;
705 ttl = find_soa(header, qlen);
706 }
707 if (ttl)
708 cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags);
709 }
710 }
711 else
712 {
713 /* everything other than PTR */
714 struct crec *newc;
715 int addrlen;
716
717 if (qtype == T_A)
718 {
719 addrlen = INADDRSZ;
720 flags |= F_IPV4;
721 }
722 #ifdef HAVE_IPV6
723 else if (qtype == T_AAAA)
724 {
725 addrlen = IN6ADDRSZ;
726 flags |= F_IPV6;
727 }
728 #endif
729 else
730 continue;
731
732 if (!(flags & F_NXDOMAIN))
733 {
734 cname_loop1:
735 if (!(p1 = skip_questions(header, qlen)))
736 return 0;
737
738 for (j = ntohs(header->ancount); j != 0; j--)
739 {
740 if (!(res = extract_name(header, qlen, &p1, name, 0)))
741 return 0; /* bad packet */
742
743 GETSHORT(aqtype, p1);
744 GETSHORT(aqclass, p1);
745 GETLONG(attl, p1);
746 GETSHORT(ardlen, p1);
747 endrr = p1+ardlen;
748
749 if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
750 {
751 if (aqtype == T_CNAME)
752 {
753 if (!cname_count--)
754 return 0; /* looped CNAMES */
755 newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD);
756 if (newc && cpp)
757 {
758 cpp->addr.cname.cache = newc;
759 cpp->addr.cname.uid = newc->uid;
760 }
761
762 cpp = newc;
763 if (attl < cttl)
764 cttl = attl;
765
766 if (!extract_name(header, qlen, &p1, name, 1))
767 return 0;
768 goto cname_loop1;
769 }
770 else
771 {
772 found = 1;
773 /* copy address into aligned storage */
774 memcpy(&addr, p1, addrlen);
775
776 /* check for returned address in private space */
777 if ((daemon->options & OPT_NO_REBIND) &&
778 (flags & F_IPV4) &&
779 private_net(addr.addr.addr4))
780 return 1;
781
782 newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
783 if (newc && cpp)
784 {
785 cpp->addr.cname.cache = newc;
786 cpp->addr.cname.uid = newc->uid;
787 }
788 cpp = NULL;
789 }
790 }
791
792 p1 = endrr;
793 if ((size_t)(p1 - (unsigned char *)header) > qlen)
794 return 0; /* bad packet */
795 }
796 }
797
798 if (!found && !(daemon->options & OPT_NO_NEG))
799 {
800 if (!searched_soa)
801 {
802 searched_soa = 1;
803 ttl = find_soa(header, qlen);
804 }
805 /* If there's no SOA to get the TTL from, but there is a CNAME
806 pointing at this, inherit its TTL */
807 if (ttl || cpp)
808 {
809 newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags);
810 if (newc && cpp)
811 {
812 cpp->addr.cname.cache = newc;
813 cpp->addr.cname.uid = newc->uid;
814 }
815 }
816 }
817 }
818 }
819
820 /* Don't put stuff from a truncated packet into the cache, but do everything else */
821 if (!header->tc)
822 cache_end_insert();
823
824 return 0;
825 }
826
827 /* If the packet holds exactly one query
828 return F_IPV4 or F_IPV6 and leave the name from the query in name.
829 Abuse F_BIGNAME to indicate an NS query - yuck. */
830
831 unsigned short extract_request(HEADER *header, size_t qlen, char *name, unsigned short *typep)
832 {
833 unsigned char *p = (unsigned char *)(header+1);
834 int qtype, qclass;
835
836 if (typep)
837 *typep = 0;
838
839 if (ntohs(header->qdcount) != 1 || header->opcode != QUERY)
840 return 0; /* must be exactly one query. */
841
842 if (!extract_name(header, qlen, &p, name, 1))
843 return 0; /* bad packet */
844
845 GETSHORT(qtype, p);
846 GETSHORT(qclass, p);
847
848 if (typep)
849 *typep = qtype;
850
851 if (qclass == C_IN)
852 {
853 if (qtype == T_A)
854 return F_IPV4;
855 if (qtype == T_AAAA)
856 return F_IPV6;
857 if (qtype == T_ANY)
858 return F_IPV4 | F_IPV6;
859 if (qtype == T_NS || qtype == T_SOA)
860 return F_QUERY | F_BIGNAME;
861 }
862
863 return F_QUERY;
864 }
865
866
867 size_t setup_reply(HEADER *header, size_t qlen,
868 struct all_addr *addrp, unsigned short flags, unsigned long ttl)
869 {
870 unsigned char *p = skip_questions(header, qlen);
871
872 header->qr = 1; /* response */
873 header->aa = 0; /* authoritive */
874 header->ra = 1; /* recursion if available */
875 header->tc = 0; /* not truncated */
876 header->nscount = htons(0);
877 header->arcount = htons(0);
878 header->ancount = htons(0); /* no answers unless changed below */
879 if (flags == F_NEG)
880 header->rcode = SERVFAIL; /* couldn't get memory */
881 else if (flags == F_NOERR)
882 header->rcode = NOERROR; /* empty domain */
883 else if (flags == F_NXDOMAIN)
884 header->rcode = NXDOMAIN;
885 else if (p && flags == F_IPV4)
886 { /* we know the address */
887 header->rcode = NOERROR;
888 header->ancount = htons(1);
889 header->aa = 1;
890 add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_A, C_IN, "4", addrp);
891 }
892 #ifdef HAVE_IPV6
893 else if (p && flags == F_IPV6)
894 {
895 header->rcode = NOERROR;
896 header->ancount = htons(1);
897 header->aa = 1;
898 add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
899 }
900 #endif
901 else /* nowhere to forward to */
902 header->rcode = REFUSED;
903
904 return p - (unsigned char *)header;
905 }
906
907 /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
908 int check_for_local_domain(char *name, time_t now)
909 {
910 struct crec *crecp;
911 struct mx_srv_record *mx;
912 struct txt_record *txt;
913 struct interface_name *intr;
914 struct ptr_record *ptr;
915
916 if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)) &&
917 (crecp->flags & (F_HOSTS | F_DHCP)))
918 return 1;
919
920 for (mx = daemon->mxnames; mx; mx = mx->next)
921 if (hostname_isequal(name, mx->name))
922 return 1;
923
924 for (txt = daemon->txt; txt; txt = txt->next)
925 if (hostname_isequal(name, txt->name))
926 return 1;
927
928 for (intr = daemon->int_names; intr; intr = intr->next)
929 if (hostname_isequal(name, intr->name))
930 return 1;
931
932 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
933 if (hostname_isequal(name, ptr->name))
934 return 1;
935
936 return 0;
937 }
938
939 /* Is the packet a reply with the answer address equal to addr?
940 If so mung is into an NXDOMAIN reply and also put that information
941 in the cache. */
942 int check_for_bogus_wildcard(HEADER *header, size_t qlen, char *name,
943 struct bogus_addr *baddr, time_t now)
944 {
945 unsigned char *p;
946 int i, qtype, qclass, rdlen;
947 unsigned long ttl;
948 struct bogus_addr *baddrp;
949
950 /* skip over questions */
951 if (!(p = skip_questions(header, qlen)))
952 return 0; /* bad packet */
953
954 for (i = ntohs(header->ancount); i != 0; i--)
955 {
956 if (!extract_name(header, qlen, &p, name, 1))
957 return 0; /* bad packet */
958
959 GETSHORT(qtype, p);
960 GETSHORT(qclass, p);
961 GETLONG(ttl, p);
962 GETSHORT(rdlen, p);
963
964 if (qclass == C_IN && qtype == T_A)
965 for (baddrp = baddr; baddrp; baddrp = baddrp->next)
966 if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
967 {
968 /* Found a bogus address. Insert that info here, since there no SOA record
969 to get the ttl from in the normal processing */
970 cache_start_insert();
971 cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN | F_CONFIG);
972 cache_end_insert();
973
974 return 1;
975 }
976
977 p += rdlen;
978 }
979
980 return 0;
981 }
982
983 static int add_resource_record(HEADER *header, char *limit, int *truncp, unsigned int nameoffset, unsigned char **pp,
984 unsigned long ttl, unsigned int *offset, unsigned short type, unsigned short class, char *format, ...)
985 {
986 va_list ap;
987 unsigned char *sav, *p = *pp;
988 int j;
989 unsigned short usval;
990 long lval;
991 char *sval;
992
993 if (truncp && *truncp)
994 return 0;
995
996 PUTSHORT(nameoffset | 0xc000, p);
997 PUTSHORT(type, p);
998 PUTSHORT(class, p);
999 PUTLONG(ttl, p); /* TTL */
1000
1001 sav = p; /* Save pointer to RDLength field */
1002 PUTSHORT(0, p); /* Placeholder RDLength */
1003
1004 va_start(ap, format); /* make ap point to 1st unamed argument */
1005
1006 for (; *format; format++)
1007 switch (*format)
1008 {
1009 #ifdef HAVE_IPV6
1010 case '6':
1011 sval = va_arg(ap, char *);
1012 memcpy(p, sval, IN6ADDRSZ);
1013 p += IN6ADDRSZ;
1014 break;
1015 #endif
1016
1017 case '4':
1018 sval = va_arg(ap, char *);
1019 memcpy(p, sval, INADDRSZ);
1020 p += INADDRSZ;
1021 break;
1022
1023 case 's':
1024 usval = va_arg(ap, int);
1025 PUTSHORT(usval, p);
1026 break;
1027
1028 case 'l':
1029 lval = va_arg(ap, long);
1030 PUTLONG(lval, p);
1031 break;
1032
1033 case 'd':
1034 /* get domain-name answer arg and store it in RDATA field */
1035 if (offset)
1036 *offset = p - (unsigned char *)header;
1037 p = do_rfc1035_name(p, va_arg(ap, char *));
1038 *p++ = 0;
1039 break;
1040
1041 case 't':
1042 usval = va_arg(ap, int);
1043 sval = va_arg(ap, char *);
1044 memcpy(p, sval, usval);
1045 p += usval;
1046 break;
1047 }
1048
1049 va_end(ap); /* clean up variable argument pointer */
1050
1051 j = p - sav - 2;
1052 PUTSHORT(j, sav); /* Now, store real RDLength */
1053
1054 /* check for overflow of buffer */
1055 if (limit && ((unsigned char *)limit - p) < 0)
1056 {
1057 if (truncp)
1058 *truncp = 1;
1059 return 0;
1060 }
1061
1062 *pp = p;
1063 return 1;
1064 }
1065
1066 /* return zero if we can't answer from cache, or packet size if we can */
1067 size_t answer_request(HEADER *header, char *limit, size_t qlen,
1068 struct in_addr local_addr, struct in_addr local_netmask, time_t now)
1069 {
1070 char *name = daemon->namebuff;
1071 unsigned char *p, *ansp, *pheader;
1072 int qtype, qclass;
1073 struct all_addr addr;
1074 unsigned int nameoffset;
1075 unsigned short flag;
1076 int q, ans, anscount = 0, addncount = 0;
1077 int dryrun = 0, sec_reqd = 0;
1078 int is_sign;
1079 struct crec *crecp;
1080 int nxdomain = 0, auth = 1, trunc = 0;
1081 struct mx_srv_record *rec;
1082
1083 /* If there is an RFC2671 pseudoheader then it will be overwritten by
1084 partial replies, so we have to do a dry run to see if we can answer
1085 the query. We check to see if the do bit is set, if so we always
1086 forward rather than answering from the cache, which doesn't include
1087 security information. */
1088
1089 if (find_pseudoheader(header, qlen, NULL, &pheader, &is_sign))
1090 {
1091 unsigned short udpsz, ext_rcode, flags;
1092 unsigned char *psave = pheader;
1093
1094 GETSHORT(udpsz, pheader);
1095 GETSHORT(ext_rcode, pheader);
1096 GETSHORT(flags, pheader);
1097
1098 sec_reqd = flags & 0x8000; /* do bit */
1099
1100 /* If our client is advertising a larger UDP packet size
1101 than we allow, trim it so that we don't get an overlarge
1102 response from upstream */
1103
1104 if (!is_sign && (udpsz > daemon->edns_pktsz))
1105 PUTSHORT(daemon->edns_pktsz, psave);
1106
1107 dryrun = 1;
1108 }
1109
1110 if (ntohs(header->qdcount) == 0 || header->opcode != QUERY )
1111 return 0;
1112
1113 for (rec = daemon->mxnames; rec; rec = rec->next)
1114 rec->offset = 0;
1115
1116 rerun:
1117 /* determine end of question section (we put answers there) */
1118 if (!(ansp = skip_questions(header, qlen)))
1119 return 0; /* bad packet */
1120
1121 /* now process each question, answers go in RRs after the question */
1122 p = (unsigned char *)(header+1);
1123
1124 for (q = ntohs(header->qdcount); q != 0; q--)
1125 {
1126 /* save pointer to name for copying into answers */
1127 nameoffset = p - (unsigned char *)header;
1128
1129 /* now extract name as .-concatenated string into name */
1130 if (!extract_name(header, qlen, &p, name, 1))
1131 return 0; /* bad packet */
1132
1133 GETSHORT(qtype, p);
1134 GETSHORT(qclass, p);
1135
1136 ans = 0; /* have we answered this question */
1137
1138 if (qtype == T_TXT || qtype == T_ANY)
1139 {
1140 struct txt_record *t;
1141 for(t = daemon->txt; t ; t = t->next)
1142 {
1143 if (t->class == qclass && hostname_isequal(name, t->name))
1144 {
1145 ans = 1;
1146 if (!dryrun)
1147 {
1148 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, 0, NULL, 0);
1149 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1150 daemon->local_ttl, NULL,
1151 T_TXT, t->class, "t", t->len, t->txt))
1152 anscount++;
1153
1154 }
1155 }
1156 }
1157 }
1158
1159 if (qclass == C_IN)
1160 {
1161 if (qtype == T_PTR || qtype == T_ANY)
1162 {
1163 /* see if it's w.z.y.z.in-addr.arpa format */
1164 int is_arpa = in_arpa_name_2_addr(name, &addr);
1165 struct ptr_record *ptr;
1166 struct interface_name* intr = NULL;
1167
1168 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1169 if (hostname_isequal(name, ptr->name))
1170 break;
1171
1172 if (is_arpa == F_IPV4)
1173 for (intr = daemon->int_names; intr; intr = intr->next)
1174 {
1175 if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr)
1176 break;
1177 else
1178 while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1179 intr = intr->next;
1180 }
1181
1182 if (intr)
1183 {
1184 ans = 1;
1185 if (!dryrun)
1186 {
1187 log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, 0, NULL, 0);
1188 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1189 daemon->local_ttl, NULL,
1190 T_PTR, C_IN, "d", intr->name))
1191 anscount++;
1192 }
1193 }
1194 else if (ptr)
1195 {
1196 ans = 1;
1197 if (!dryrun)
1198 {
1199 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_BIGNAME, name, NULL, 0, NULL, 0);
1200 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1201 if (hostname_isequal(name, ptr->name) &&
1202 add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1203 daemon->local_ttl, NULL,
1204 T_PTR, C_IN, "d", ptr->ptr))
1205 anscount++;
1206
1207 }
1208 }
1209 else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
1210 do
1211 {
1212 /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
1213 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1214 continue;
1215
1216 if (crecp->flags & F_NEG)
1217 {
1218 ans = 1;
1219 auth = 0;
1220 if (crecp->flags & F_NXDOMAIN)
1221 nxdomain = 1;
1222 if (!dryrun)
1223 log_query(crecp->flags & ~F_FORWARD, name, &addr, 0, NULL, 0);
1224 }
1225 else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
1226 {
1227 ans = 1;
1228 if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1229 auth = 0;
1230 if (!dryrun)
1231 {
1232 unsigned long ttl;
1233 /* Return 0 ttl for DHCP entries, which might change
1234 before the lease expires. */
1235 if (crecp->flags & (F_IMMORTAL | F_DHCP))
1236 ttl = daemon->local_ttl;
1237 else
1238 ttl = crecp->ttd - now;
1239
1240 log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
1241 0, daemon->addn_hosts, crecp->uid);
1242
1243 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL,
1244 T_PTR, C_IN, "d", cache_get_name(crecp)))
1245 anscount++;
1246 }
1247 }
1248 } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
1249 else if (is_arpa == F_IPV4 &&
1250 (daemon->options & OPT_BOGUSPRIV) &&
1251 private_net(addr.addr.addr4))
1252 {
1253 /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
1254 ans = 1;
1255 nxdomain = 1;
1256 if (!dryrun)
1257 log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN,
1258 name, &addr, 0, NULL, 0);
1259 }
1260 }
1261
1262 for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
1263 {
1264 unsigned short type = T_A;
1265
1266 if (flag == F_IPV6)
1267 #ifdef HAVE_IPV6
1268 type = T_AAAA;
1269 #else
1270 break;
1271 #endif
1272
1273 if (qtype != type && qtype != T_ANY)
1274 continue;
1275
1276 /* Check for "A for A" queries */
1277 if (qtype == T_A && (addr.addr.addr4.s_addr = inet_addr(name)) != (in_addr_t) -1)
1278 {
1279 ans = 1;
1280 if (!dryrun)
1281 {
1282 log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, 0, NULL, 0);
1283 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1284 daemon->local_ttl, NULL, type, C_IN, "4", &addr))
1285 anscount++;
1286 }
1287 continue;
1288 }
1289
1290 /* interface name stuff */
1291 if (qtype == T_A)
1292 {
1293 struct interface_name *intr;
1294
1295 for (intr = daemon->int_names; intr; intr = intr->next)
1296 if (hostname_isequal(name, intr->name))
1297 break;
1298
1299 if (intr)
1300 {
1301 ans = 1;
1302 if (!dryrun)
1303 {
1304 if ((addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr == (in_addr_t) -1)
1305 log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, 0, NULL, 0);
1306 else
1307 {
1308 log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, 0, NULL, 0);
1309 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1310 daemon->local_ttl, NULL, type, C_IN, "4", &addr))
1311 anscount++;
1312 }
1313 }
1314 continue;
1315 }
1316 }
1317
1318 cname_restart:
1319 if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME)))
1320 {
1321 int localise = 0;
1322
1323 /* See if a putative address is on the network from which we recieved
1324 the query, is so we'll filter other answers. */
1325 if (local_addr.s_addr != 0 && (daemon->options & OPT_LOCALISE) && flag == F_IPV4)
1326 {
1327 struct crec *save = crecp;
1328 do {
1329 if ((crecp->flags & F_HOSTS) &&
1330 is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1331 {
1332 localise = 1;
1333 break;
1334 }
1335 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
1336 crecp = save;
1337 }
1338
1339 do
1340 {
1341 /* don't answer wildcard queries with data not from /etc/hosts
1342 or DHCP leases */
1343 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1344 break;
1345
1346 if (crecp->flags & F_CNAME)
1347 {
1348 if (!dryrun)
1349 {
1350 log_query(crecp->flags, name, NULL, 0, daemon->addn_hosts, crecp->uid);
1351 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, crecp->ttd - now, &nameoffset,
1352 T_CNAME, C_IN, "d", cache_get_name(crecp->addr.cname.cache)))
1353 anscount++;
1354 }
1355
1356 strcpy(name, cache_get_name(crecp->addr.cname.cache));
1357 goto cname_restart;
1358 }
1359
1360 if (crecp->flags & F_NEG)
1361 {
1362 ans = 1;
1363 auth = 0;
1364 if (crecp->flags & F_NXDOMAIN)
1365 nxdomain = 1;
1366 if (!dryrun)
1367 log_query(crecp->flags, name, NULL, 0, NULL, 0);
1368 }
1369 else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
1370 {
1371 /* If we are returning local answers depending on network,
1372 filter here. */
1373 if (localise &&
1374 (crecp->flags & F_HOSTS) &&
1375 !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1376 continue;
1377
1378 if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1379 auth = 0;
1380
1381 ans = 1;
1382 if (!dryrun)
1383 {
1384 unsigned long ttl;
1385
1386 if (crecp->flags & (F_IMMORTAL | F_DHCP))
1387 ttl = daemon->local_ttl;
1388 else
1389 ttl = crecp->ttd - now;
1390
1391 log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
1392 0, daemon->addn_hosts, crecp->uid);
1393
1394 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, ttl, NULL, type, C_IN,
1395 type == T_A ? "4" : "6", &crecp->addr))
1396 anscount++;
1397 }
1398 }
1399 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
1400 }
1401 }
1402
1403 if (qtype == T_MX || qtype == T_ANY)
1404 {
1405 int found = 0;
1406 for (rec = daemon->mxnames; rec; rec = rec->next)
1407 if (!rec->issrv && hostname_isequal(name, rec->name))
1408 {
1409 ans = found = 1;
1410 if (!dryrun)
1411 {
1412 unsigned int offset;
1413 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_IPV4, name, NULL, 0, NULL, 0);
1414 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1415 &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
1416 {
1417 anscount++;
1418 if (rec->target)
1419 rec->offset = offset;
1420 }
1421 }
1422 }
1423
1424 if (!found && (daemon->options & (OPT_SELFMX | OPT_LOCALMX)) &&
1425 cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP))
1426 {
1427 ans = 1;
1428 if (!dryrun)
1429 {
1430 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_IPV4, name, NULL, 0, NULL, 0);
1431 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
1432 T_MX, C_IN, "sd", 1,
1433 (daemon->options & OPT_SELFMX) ? name : daemon->mxtarget))
1434 anscount++;
1435 }
1436 }
1437 }
1438
1439 if (qtype == T_SRV || qtype == T_ANY)
1440 {
1441 int found = 0;
1442
1443 for (rec = daemon->mxnames; rec; rec = rec->next)
1444 if (rec->issrv && hostname_isequal(name, rec->name))
1445 {
1446 found = ans = 1;
1447 if (!dryrun)
1448 {
1449 unsigned int offset;
1450 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_IPV6, name, NULL, 0, NULL, 0);
1451 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1452 &offset, T_SRV, C_IN, "sssd",
1453 rec->priority, rec->weight, rec->srvport, rec->target))
1454 {
1455 anscount++;
1456 if (rec->target)
1457 rec->offset = offset;
1458 }
1459 }
1460 }
1461
1462 if (!found && (daemon->options & OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
1463 {
1464 ans = 1;
1465 if (!dryrun)
1466 log_query(F_CONFIG | F_NEG, name, NULL, 0, NULL, 0);
1467 }
1468 }
1469
1470 if (qtype == T_MAILB)
1471 ans = 1, nxdomain = 1;
1472
1473 if (qtype == T_SOA && (daemon->options & OPT_FILTER))
1474 {
1475 ans = 1;
1476 if (!dryrun)
1477 log_query(F_CONFIG | F_NEG, name, &addr, 0, NULL, 0);
1478 }
1479 }
1480
1481 if (!ans)
1482 return 0; /* failed to answer a question */
1483 }
1484
1485 if (dryrun)
1486 {
1487 dryrun = 0;
1488 goto rerun;
1489 }
1490
1491 /* create an additional data section, for stuff in SRV and MX record replies. */
1492 for (rec = daemon->mxnames; rec; rec = rec->next)
1493 if (rec->offset != 0)
1494 {
1495 /* squash dupes */
1496 struct mx_srv_record *tmp;
1497 for (tmp = rec->next; tmp; tmp = tmp->next)
1498 if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
1499 tmp->offset = 0;
1500
1501 crecp = NULL;
1502 while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
1503 {
1504 unsigned long ttl;
1505 #ifdef HAVE_IPV6
1506 int type = crecp->flags & F_IPV4 ? T_A : T_AAAA;
1507 #else
1508 int type = T_A;
1509 #endif
1510 if (crecp->flags & F_NEG)
1511 continue;
1512
1513 if (crecp->flags & (F_IMMORTAL | F_DHCP))
1514 ttl = daemon->local_ttl;
1515 else
1516 ttl = crecp->ttd - now;
1517
1518 if (add_resource_record(header, limit, NULL, rec->offset, &ansp, ttl, NULL, type, C_IN,
1519 crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
1520 addncount++;
1521 }
1522 }
1523
1524 /* done all questions, set up header and return length of result */
1525 header->qr = 1; /* response */
1526 header->aa = auth; /* authoritive - only hosts and DHCP derived names. */
1527 header->ra = 1; /* recursion if available */
1528 header->tc = trunc; /* truncation */
1529 if (anscount == 0 && nxdomain)
1530 header->rcode = NXDOMAIN;
1531 else
1532 header->rcode = NOERROR; /* no error */
1533 header->ancount = htons(anscount);
1534 header->nscount = htons(0);
1535 header->arcount = htons(addncount);
1536 return ansp - (unsigned char *)header;
1537 }
1538
1539
1540
1541
1542