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