Annotation of embedaddon/dnsmasq/src/rfc1035.c, revision 1.1.1.3
1.1.1.3 ! misho 1: /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
1.1 misho 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;
1.1.1.3 ! misho 23: unsigned int j, l, namelen = 0, hops = 0;
1.1 misho 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, 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: }
1.1.1.3 ! misho 80: else if (label_type == 0x00)
1.1 misho 81: { /* label_type = 0 -> label. */
1.1.1.3 ! misho 82: namelen += l + 1; /* include period */
! 83: if (namelen >= MAXDNAME)
1.1 misho 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;
1.1.1.3 ! misho 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;
1.1 misho 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';
1.1.1.3 ! misho 121: #ifdef HAVE_DNSSEC
! 122: if (option_bool(OPT_DNSSEC_VALID) && c1 == NAME_ESCAPE)
! 123: c1 = (*cp++)-1;
! 124: #endif
! 125:
1.1 misho 126: if (c2 >= 'A' && c2 <= 'Z')
127: c2 += 'a' - 'A';
1.1.1.3 ! misho 128:
1.1 misho 129: if (c1 != c2)
130: retvalue = 2;
131: }
132: }
1.1.1.3 ! misho 133:
1.1 misho 134: if (isExtract)
135: *cp++ = '.';
136: else if (*cp != 0 && *cp++ != '.')
137: retvalue = 2;
138: }
1.1.1.3 ! misho 139: else
! 140: return 0; /* label types 0x40 and 0x80 not supported */
1.1 misho 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, struct 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(struct 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 arives 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: #ifdef HAVE_IPV6
202: else if (hostname_isequal(penchunk, "ip6") &&
203: (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa")))
204: {
205: /* IP v6:
206: Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
207: or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]
208:
209: Note that most of these the various reprentations are obsolete and
210: left-over from the many DNS-for-IPv6 wars. We support all the formats
211: that we can since there is no reason not to.
212: */
213:
214: if (*name == '\\' && *(name+1) == '[' &&
215: (*(name+2) == 'x' || *(name+2) == 'X'))
216: {
217: for (j = 0, cp1 = name+3; *cp1 && isxdigit((unsigned char) *cp1) && j < 32; cp1++, j++)
218: {
219: char xdig[2];
220: xdig[0] = *cp1;
221: xdig[1] = 0;
222: if (j%2)
223: addr[j/2] |= strtol(xdig, NULL, 16);
224: else
225: addr[j/2] = strtol(xdig, NULL, 16) << 4;
226: }
227:
228: if (*cp1 == '/' && j == 32)
229: return F_IPV6;
230: }
231: else
232: {
233: for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
234: {
235: if (*(cp1+1) || !isxdigit((unsigned char)*cp1))
236: return 0;
237:
238: for (j = sizeof(struct all_addr)-1; j>0; j--)
239: addr[j] = (addr[j] >> 4) | (addr[j-1] << 4);
240: addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
241: }
242:
243: return F_IPV6;
244: }
245: }
246: #endif
247:
248: return 0;
249: }
250:
1.1.1.2 misho 251: unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes)
1.1 misho 252: {
253: while(1)
254: {
255: unsigned int label_type;
256:
257: if (!CHECK_LEN(header, ansp, plen, 1))
258: return NULL;
259:
260: label_type = (*ansp) & 0xc0;
261:
262: if (label_type == 0xc0)
263: {
264: /* pointer for compression. */
265: ansp += 2;
266: break;
267: }
268: else if (label_type == 0x80)
269: return NULL; /* reserved */
270: else if (label_type == 0x40)
271: {
272: /* Extended label type */
273: unsigned int count;
274:
275: if (!CHECK_LEN(header, ansp, plen, 2))
276: return NULL;
277:
278: if (((*ansp++) & 0x3f) != 1)
279: return NULL; /* we only understand bitstrings */
280:
281: count = *(ansp++); /* Bits in bitstring */
282:
283: if (count == 0) /* count == 0 means 256 bits */
284: ansp += 32;
285: else
286: ansp += ((count-1)>>3)+1;
287: }
288: else
289: { /* label type == 0 Bottom six bits is length */
290: unsigned int len = (*ansp++) & 0x3f;
291:
292: if (!ADD_RDLEN(header, ansp, plen, len))
293: return NULL;
294:
295: if (len == 0)
296: break; /* zero length label marks the end. */
297: }
298: }
299:
300: if (!CHECK_LEN(header, ansp, plen, extrabytes))
301: return NULL;
302:
303: return ansp;
304: }
305:
306: unsigned char *skip_questions(struct dns_header *header, size_t plen)
307: {
308: int q;
309: unsigned char *ansp = (unsigned char *)(header+1);
310:
311: for (q = ntohs(header->qdcount); q != 0; q--)
312: {
313: if (!(ansp = skip_name(ansp, header, plen, 4)))
314: return NULL;
315: ansp += 4; /* class and type */
316: }
317:
318: return ansp;
319: }
320:
1.1.1.2 misho 321: unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen)
1.1 misho 322: {
323: int i, rdlen;
324:
325: for (i = 0; i < count; i++)
326: {
327: if (!(ansp = skip_name(ansp, header, plen, 10)))
328: return NULL;
329: ansp += 8; /* type, class, TTL */
330: GETSHORT(rdlen, ansp);
331: if (!ADD_RDLEN(header, ansp, plen, rdlen))
332: return NULL;
333: }
334:
335: return ansp;
336: }
337:
338: /* CRC the question section. This is used to safely detect query
339: retransmision and to detect answers to questions we didn't ask, which
340: might be poisoning attacks. Note that we decode the name rather
341: than CRC the raw bytes, since replies might be compressed differently.
342: We ignore case in the names for the same reason. Return all-ones
343: if there is not question section. */
1.1.1.2 misho 344: #ifndef HAVE_DNSSEC
1.1 misho 345: unsigned int questions_crc(struct dns_header *header, size_t plen, char *name)
346: {
347: int q;
348: unsigned int crc = 0xffffffff;
349: unsigned char *p1, *p = (unsigned char *)(header+1);
350:
351: for (q = ntohs(header->qdcount); q != 0; q--)
352: {
353: if (!extract_name(header, plen, &p, name, 1, 4))
354: return crc; /* bad packet */
355:
356: for (p1 = (unsigned char *)name; *p1; p1++)
357: {
358: int i = 8;
359: char c = *p1;
360:
361: if (c >= 'A' && c <= 'Z')
362: c += 'a' - 'A';
363:
364: crc ^= c << 24;
365: while (i--)
366: crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
367: }
368:
369: /* CRC the class and type as well */
370: for (p1 = p; p1 < p+4; p1++)
371: {
372: int i = 8;
373: crc ^= *p1 << 24;
374: while (i--)
375: crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
376: }
377:
378: p += 4;
379: if (!CHECK_LEN(header, p, plen, 0))
380: return crc; /* bad packet */
381: }
382:
383: return crc;
384: }
1.1.1.2 misho 385: #endif
1.1 misho 386:
387: size_t resize_packet(struct dns_header *header, size_t plen, unsigned char *pheader, size_t hlen)
388: {
389: unsigned char *ansp = skip_questions(header, plen);
390:
391: /* if packet is malformed, just return as-is. */
392: if (!ansp)
393: return plen;
394:
395: if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
396: header, plen)))
397: return plen;
398:
399: /* restore pseudoheader */
400: if (pheader && ntohs(header->arcount) == 0)
401: {
402: /* must use memmove, may overlap */
403: memmove(ansp, pheader, hlen);
404: header->arcount = htons(1);
405: ansp += hlen;
406: }
407:
408: return ansp - (unsigned char *)header;
409: }
410:
411: /* is addr in the non-globally-routed IP space? */
1.1.1.2 misho 412: int private_net(struct in_addr addr, int ban_localhost)
1.1 misho 413: {
414: in_addr_t ip_addr = ntohl(addr.s_addr);
415:
416: return
1.1.1.3 ! misho 417: (((ip_addr & 0xFF000000) == 0x7F000000) && ban_localhost) /* 127.0.0.0/8 (loopback) */ ||
! 418: ((ip_addr & 0xFF000000) == 0x00000000) /* RFC 5735 section 3. "here" network */ ||
1.1 misho 419: ((ip_addr & 0xFF000000) == 0x0A000000) /* 10.0.0.0/8 (private) */ ||
420: ((ip_addr & 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12 (private) */ ||
1.1.1.3 ! misho 421: ((ip_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168.0.0/16 (private) */ ||
! 422: ((ip_addr & 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */ ||
! 423: ((ip_addr & 0xFFFFFF00) == 0xC0000200) /* 192.0.2.0/24 (test-net) */ ||
! 424: ((ip_addr & 0xFFFFFF00) == 0xC6336400) /* 198.51.100.0/24(test-net) */ ||
! 425: ((ip_addr & 0xFFFFFF00) == 0xCB007100) /* 203.0.113.0/24 (test-net) */ ||
! 426: ((ip_addr & 0xFFFFFFFF) == 0xFFFFFFFF) /* 255.255.255.255/32 (broadcast)*/ ;
1.1 misho 427: }
428:
1.1.1.2 misho 429: static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *header, size_t qlen, char *name, int *doctored)
1.1 misho 430: {
431: int i, qtype, qclass, rdlen;
432:
433: for (i = count; i != 0; i--)
434: {
435: if (name && option_bool(OPT_LOG))
436: {
437: if (!extract_name(header, qlen, &p, name, 1, 10))
438: return 0;
439: }
440: else if (!(p = skip_name(p, header, qlen, 10)))
441: return 0; /* bad packet */
442:
443: GETSHORT(qtype, p);
444: GETSHORT(qclass, p);
445: p += 4; /* ttl */
446: GETSHORT(rdlen, p);
447:
448: if (qclass == C_IN && qtype == T_A)
449: {
450: struct doctor *doctor;
451: struct in_addr addr;
452:
453: if (!CHECK_LEN(header, p, qlen, INADDRSZ))
454: return 0;
455:
456: /* alignment */
457: memcpy(&addr, p, INADDRSZ);
458:
459: for (doctor = daemon->doctors; doctor; doctor = doctor->next)
460: {
461: if (doctor->end.s_addr == 0)
462: {
463: if (!is_same_net(doctor->in, addr, doctor->mask))
464: continue;
465: }
466: else if (ntohl(doctor->in.s_addr) > ntohl(addr.s_addr) ||
467: ntohl(doctor->end.s_addr) < ntohl(addr.s_addr))
468: continue;
469:
470: addr.s_addr &= ~doctor->mask.s_addr;
471: addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
472: /* Since we munged the data, the server it came from is no longer authoritative */
473: header->hb3 &= ~HB3_AA;
1.1.1.2 misho 474: *doctored = 1;
1.1 misho 475: memcpy(p, &addr, INADDRSZ);
476: break;
477: }
478: }
479: else if (qtype == T_TXT && name && option_bool(OPT_LOG))
480: {
481: unsigned char *p1 = p;
482: if (!CHECK_LEN(header, p1, qlen, rdlen))
483: return 0;
484: while ((p1 - p) < rdlen)
485: {
486: unsigned int i, len = *p1;
487: unsigned char *p2 = p1;
488: /* make counted string zero-term and sanitise */
489: for (i = 0; i < len; i++)
490: {
491: if (!isprint((int)*(p2+1)))
492: break;
493:
494: *p2 = *(p2+1);
495: p2++;
496: }
497: *p2 = 0;
498: my_syslog(LOG_INFO, "reply %s is %s", name, p1);
499: /* restore */
500: memmove(p1 + 1, p1, i);
501: *p1 = len;
502: p1 += len+1;
503: }
504: }
505:
506: if (!ADD_RDLEN(header, p, qlen, rdlen))
507: return 0; /* bad packet */
508: }
509:
510: return p;
511: }
512:
1.1.1.2 misho 513: static int find_soa(struct dns_header *header, size_t qlen, char *name, int *doctored)
1.1 misho 514: {
515: unsigned char *p;
516: int qtype, qclass, rdlen;
517: unsigned long ttl, minttl = ULONG_MAX;
518: int i, found_soa = 0;
519:
520: /* first move to NS section and find TTL from any SOA section */
521: if (!(p = skip_questions(header, qlen)) ||
1.1.1.2 misho 522: !(p = do_doctor(p, ntohs(header->ancount), header, qlen, name, doctored)))
1.1 misho 523: return 0; /* bad packet */
524:
525: for (i = ntohs(header->nscount); i != 0; i--)
526: {
527: if (!(p = skip_name(p, header, qlen, 10)))
528: return 0; /* bad packet */
529:
530: GETSHORT(qtype, p);
531: GETSHORT(qclass, p);
532: GETLONG(ttl, p);
533: GETSHORT(rdlen, p);
534:
535: if ((qclass == C_IN) && (qtype == T_SOA))
536: {
537: found_soa = 1;
538: if (ttl < minttl)
539: minttl = ttl;
540:
541: /* MNAME */
542: if (!(p = skip_name(p, header, qlen, 0)))
543: return 0;
544: /* RNAME */
545: if (!(p = skip_name(p, header, qlen, 20)))
546: return 0;
547: p += 16; /* SERIAL REFRESH RETRY EXPIRE */
548:
549: GETLONG(ttl, p); /* minTTL */
550: if (ttl < minttl)
551: minttl = ttl;
552: }
553: else if (!ADD_RDLEN(header, p, qlen, rdlen))
554: return 0; /* bad packet */
555: }
556:
1.1.1.2 misho 557: /* rewrite addresses in additional section too */
558: if (!do_doctor(p, ntohs(header->arcount), header, qlen, NULL, doctored))
1.1 misho 559: return 0;
560:
561: if (!found_soa)
562: minttl = daemon->neg_ttl;
563:
564: return minttl;
565: }
566:
567: /* Note that the following code can create CNAME chains that don't point to a real record,
568: either because of lack of memory, or lack of SOA records. These are treated by the cache code as
569: expired and cleaned out that way.
570: Return 1 if we reject an address because it look like part of dns-rebinding attack. */
571: int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t now,
1.1.1.2 misho 572: char **ipsets, int is_sign, int check_rebind, int no_cache_dnssec, int secure, int *doctored)
1.1 misho 573: {
574: unsigned char *p, *p1, *endrr, *namep;
575: int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
576: unsigned long ttl = 0;
577: struct all_addr addr;
578: #ifdef HAVE_IPSET
579: char **ipsets_cur;
580: #else
581: (void)ipsets; /* unused */
582: #endif
583:
584: cache_start_insert();
585:
586: /* find_soa is needed for dns_doctor and logging side-effects, so don't call it lazily if there are any. */
1.1.1.2 misho 587: if (daemon->doctors || option_bool(OPT_LOG) || option_bool(OPT_DNSSEC_VALID))
1.1 misho 588: {
589: searched_soa = 1;
1.1.1.2 misho 590: ttl = find_soa(header, qlen, name, doctored);
591: #ifdef HAVE_DNSSEC
592: if (*doctored && secure)
593: return 0;
594: #endif
1.1 misho 595: }
596:
597: /* go through the questions. */
598: p = (unsigned char *)(header+1);
599:
600: for (i = ntohs(header->qdcount); i != 0; i--)
601: {
1.1.1.2 misho 602: int found = 0, cname_count = CNAME_CHAIN;
1.1 misho 603: struct crec *cpp = NULL;
604: int flags = RCODE(header) == NXDOMAIN ? F_NXDOMAIN : 0;
1.1.1.2 misho 605: int secflag = secure ? F_DNSSECOK : 0;
1.1 misho 606: unsigned long cttl = ULONG_MAX, attl;
1.1.1.2 misho 607:
1.1 misho 608: namep = p;
609: if (!extract_name(header, qlen, &p, name, 1, 4))
610: return 0; /* bad packet */
611:
612: GETSHORT(qtype, p);
613: GETSHORT(qclass, p);
614:
615: if (qclass != C_IN)
616: continue;
617:
618: /* PTRs: we chase CNAMEs here, since we have no way to
619: represent them in the cache. */
620: if (qtype == T_PTR)
621: {
622: int name_encoding = in_arpa_name_2_addr(name, &addr);
623:
624: if (!name_encoding)
625: continue;
626:
627: if (!(flags & F_NXDOMAIN))
628: {
629: cname_loop:
630: if (!(p1 = skip_questions(header, qlen)))
631: return 0;
632:
633: for (j = ntohs(header->ancount); j != 0; j--)
634: {
635: unsigned char *tmp = namep;
636: /* the loop body overwrites the original name, so get it back here. */
637: if (!extract_name(header, qlen, &tmp, name, 1, 0) ||
638: !(res = extract_name(header, qlen, &p1, name, 0, 10)))
639: return 0; /* bad packet */
640:
641: GETSHORT(aqtype, p1);
642: GETSHORT(aqclass, p1);
643: GETLONG(attl, p1);
644: if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
645: {
646: (p1) -= 4;
647: PUTLONG(daemon->max_ttl, p1);
648: }
649: GETSHORT(ardlen, p1);
650: endrr = p1+ardlen;
651:
652: /* TTL of record is minimum of CNAMES and PTR */
653: if (attl < cttl)
654: cttl = attl;
655:
656: if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
657: {
658: if (!extract_name(header, qlen, &p1, name, 1, 0))
659: return 0;
660:
661: if (aqtype == T_CNAME)
662: {
1.1.1.2 misho 663: if (!cname_count-- || secure)
664: return 0; /* looped CNAMES, or DNSSEC, which we can't cache. */
1.1 misho 665: goto cname_loop;
666: }
667:
1.1.1.2 misho 668: cache_insert(name, &addr, now, cttl, name_encoding | secflag | F_REVERSE);
1.1 misho 669: found = 1;
670: }
671:
672: p1 = endrr;
673: if (!CHECK_LEN(header, p1, qlen, 0))
674: return 0; /* bad packet */
675: }
676: }
677:
678: if (!found && !option_bool(OPT_NO_NEG))
679: {
680: if (!searched_soa)
681: {
682: searched_soa = 1;
1.1.1.2 misho 683: ttl = find_soa(header, qlen, NULL, doctored);
1.1 misho 684: }
685: if (ttl)
1.1.1.2 misho 686: cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags | secflag);
1.1 misho 687: }
688: }
689: else
690: {
691: /* everything other than PTR */
692: struct crec *newc;
693: int addrlen;
694:
695: if (qtype == T_A)
696: {
697: addrlen = INADDRSZ;
698: flags |= F_IPV4;
699: }
700: #ifdef HAVE_IPV6
701: else if (qtype == T_AAAA)
702: {
703: addrlen = IN6ADDRSZ;
704: flags |= F_IPV6;
705: }
706: #endif
707: else
708: continue;
709:
1.1.1.2 misho 710: cname_loop1:
711: if (!(p1 = skip_questions(header, qlen)))
712: return 0;
713:
714: for (j = ntohs(header->ancount); j != 0; j--)
1.1 misho 715: {
1.1.1.2 misho 716: if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
717: return 0; /* bad packet */
1.1 misho 718:
1.1.1.2 misho 719: GETSHORT(aqtype, p1);
720: GETSHORT(aqclass, p1);
721: GETLONG(attl, p1);
722: if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
1.1 misho 723: {
1.1.1.2 misho 724: (p1) -= 4;
725: PUTLONG(daemon->max_ttl, p1);
726: }
727: GETSHORT(ardlen, p1);
728: endrr = p1+ardlen;
729:
730: if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
731: {
732: if (aqtype == T_CNAME)
1.1 misho 733: {
1.1.1.2 misho 734: if (!cname_count--)
735: return 0; /* looped CNAMES */
736: newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD | secflag);
737: if (newc)
1.1 misho 738: {
1.1.1.2 misho 739: newc->addr.cname.target.cache = NULL;
740: /* anything other than zero, to avoid being mistaken for CNAME to interface-name */
741: newc->addr.cname.uid = 1;
742: if (cpp)
1.1 misho 743: {
1.1.1.2 misho 744: cpp->addr.cname.target.cache = newc;
745: cpp->addr.cname.uid = newc->uid;
1.1 misho 746: }
747: }
1.1.1.2 misho 748:
749: cpp = newc;
750: if (attl < cttl)
751: cttl = attl;
752:
753: if (!extract_name(header, qlen, &p1, name, 1, 0))
754: return 0;
755: goto cname_loop1;
756: }
757: else if (!(flags & F_NXDOMAIN))
758: {
759: found = 1;
760:
761: /* copy address into aligned storage */
762: if (!CHECK_LEN(header, p1, qlen, addrlen))
763: return 0; /* bad packet */
764: memcpy(&addr, p1, addrlen);
765:
766: /* check for returned address in private space */
1.1.1.3 ! misho 767: if (check_rebind)
! 768: {
! 769: if ((flags & F_IPV4) &&
! 770: private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
! 771: return 1;
! 772:
! 773: #ifdef HAVE_IPV6
! 774: if ((flags & F_IPV6) &&
! 775: IN6_IS_ADDR_V4MAPPED(&addr.addr.addr6))
! 776: {
! 777: struct in_addr v4;
! 778: v4.s_addr = ((const uint32_t *) (&addr.addr.addr6))[3];
! 779: if (private_net(v4, !option_bool(OPT_LOCAL_REBIND)))
! 780: return 1;
! 781: }
! 782: #endif
! 783: }
1.1.1.2 misho 784:
1.1 misho 785: #ifdef HAVE_IPSET
1.1.1.2 misho 786: if (ipsets && (flags & (F_IPV4 | F_IPV6)))
787: {
788: ipsets_cur = ipsets;
789: while (*ipsets_cur)
1.1 misho 790: {
1.1.1.2 misho 791: log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur);
792: add_to_ipset(*ipsets_cur++, &addr, flags, 0);
1.1 misho 793: }
1.1.1.2 misho 794: }
1.1 misho 795: #endif
1.1.1.2 misho 796:
797: newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD | secflag);
798: if (newc && cpp)
799: {
800: cpp->addr.cname.target.cache = newc;
801: cpp->addr.cname.uid = newc->uid;
1.1 misho 802: }
1.1.1.2 misho 803: cpp = NULL;
1.1 misho 804: }
805: }
1.1.1.2 misho 806:
807: p1 = endrr;
808: if (!CHECK_LEN(header, p1, qlen, 0))
809: return 0; /* bad packet */
1.1 misho 810: }
811:
812: if (!found && !option_bool(OPT_NO_NEG))
813: {
814: if (!searched_soa)
815: {
816: searched_soa = 1;
1.1.1.2 misho 817: ttl = find_soa(header, qlen, NULL, doctored);
1.1 misho 818: }
819: /* If there's no SOA to get the TTL from, but there is a CNAME
820: pointing at this, inherit its TTL */
821: if (ttl || cpp)
822: {
1.1.1.2 misho 823: newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | secflag);
1.1 misho 824: if (newc && cpp)
825: {
1.1.1.2 misho 826: cpp->addr.cname.target.cache = newc;
1.1 misho 827: cpp->addr.cname.uid = newc->uid;
828: }
829: }
830: }
831: }
832: }
833:
834: /* Don't put stuff from a truncated packet into the cache.
835: Don't cache replies from non-recursive nameservers, since we may get a
836: reply containing a CNAME but not its target, even though the target
837: does exist. */
838: if (!(header->hb3 & HB3_TC) &&
839: !(header->hb4 & HB4_CD) &&
840: (header->hb4 & HB4_RA) &&
1.1.1.2 misho 841: !no_cache_dnssec)
1.1 misho 842: cache_end_insert();
843:
844: return 0;
845: }
846:
847: /* If the packet holds exactly one query
848: return F_IPV4 or F_IPV6 and leave the name from the query in name */
849: unsigned int extract_request(struct dns_header *header, size_t qlen, char *name, unsigned short *typep)
850: {
851: unsigned char *p = (unsigned char *)(header+1);
852: int qtype, qclass;
853:
854: if (typep)
855: *typep = 0;
856:
857: if (ntohs(header->qdcount) != 1 || OPCODE(header) != QUERY)
858: return 0; /* must be exactly one query. */
859:
860: if (!extract_name(header, qlen, &p, name, 1, 4))
861: return 0; /* bad packet */
862:
863: GETSHORT(qtype, p);
864: GETSHORT(qclass, p);
865:
866: if (typep)
867: *typep = qtype;
868:
869: if (qclass == C_IN)
870: {
871: if (qtype == T_A)
872: return F_IPV4;
873: if (qtype == T_AAAA)
874: return F_IPV6;
875: if (qtype == T_ANY)
876: return F_IPV4 | F_IPV6;
877: }
878:
879: return F_QUERY;
880: }
881:
882:
883: size_t setup_reply(struct dns_header *header, size_t qlen,
884: struct all_addr *addrp, unsigned int flags, unsigned long ttl)
885: {
1.1.1.3 ! misho 886: unsigned char *p;
! 887:
! 888: if (!(p = skip_questions(header, qlen)))
! 889: return 0;
1.1 misho 890:
891: /* clear authoritative and truncated flags, set QR flag */
892: header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
893: /* set RA flag */
894: header->hb4 |= HB4_RA;
895:
896: header->nscount = htons(0);
897: header->arcount = htons(0);
898: header->ancount = htons(0); /* no answers unless changed below */
1.1.1.3 ! misho 899: if (flags == F_NOERR)
1.1 misho 900: SET_RCODE(header, NOERROR); /* empty domain */
901: else if (flags == F_NXDOMAIN)
902: SET_RCODE(header, NXDOMAIN);
1.1.1.3 ! misho 903: else if (flags == F_IPV4)
1.1 misho 904: { /* we know the address */
905: SET_RCODE(header, NOERROR);
906: header->ancount = htons(1);
907: header->hb3 |= HB3_AA;
908: add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_A, C_IN, "4", addrp);
909: }
910: #ifdef HAVE_IPV6
1.1.1.3 ! misho 911: else if (flags == F_IPV6)
1.1 misho 912: {
913: SET_RCODE(header, NOERROR);
914: header->ancount = htons(1);
915: header->hb3 |= HB3_AA;
916: add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
917: }
918: #endif
919: else /* nowhere to forward to */
920: SET_RCODE(header, REFUSED);
921:
922: return p - (unsigned char *)header;
923: }
924:
925: /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
926: int check_for_local_domain(char *name, time_t now)
927: {
928: struct crec *crecp;
929: struct mx_srv_record *mx;
930: struct txt_record *txt;
931: struct interface_name *intr;
932: struct ptr_record *ptr;
933: struct naptr *naptr;
934:
1.1.1.3 ! misho 935: /* Note: the call to cache_find_by_name is intended to find any record which matches
! 936: ie A, AAAA, CNAME. */
! 937:
! 938: if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME |F_NO_RR)) &&
1.1.1.2 misho 939: (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
1.1 misho 940: return 1;
941:
942: for (naptr = daemon->naptr; naptr; naptr = naptr->next)
943: if (hostname_isequal(name, naptr->name))
944: return 1;
945:
946: for (mx = daemon->mxnames; mx; mx = mx->next)
947: if (hostname_isequal(name, mx->name))
948: return 1;
949:
950: for (txt = daemon->txt; txt; txt = txt->next)
951: if (hostname_isequal(name, txt->name))
952: return 1;
953:
954: for (intr = daemon->int_names; intr; intr = intr->next)
955: if (hostname_isequal(name, intr->name))
956: return 1;
957:
958: for (ptr = daemon->ptr; ptr; ptr = ptr->next)
959: if (hostname_isequal(name, ptr->name))
960: return 1;
961:
962: return 0;
963: }
964:
965: /* Is the packet a reply with the answer address equal to addr?
966: If so mung is into an NXDOMAIN reply and also put that information
967: in the cache. */
968: int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
969: struct bogus_addr *baddr, time_t now)
970: {
971: unsigned char *p;
972: int i, qtype, qclass, rdlen;
973: unsigned long ttl;
974: struct bogus_addr *baddrp;
975:
976: /* skip over questions */
977: if (!(p = skip_questions(header, qlen)))
978: return 0; /* bad packet */
979:
980: for (i = ntohs(header->ancount); i != 0; i--)
981: {
982: if (!extract_name(header, qlen, &p, name, 1, 10))
983: return 0; /* bad packet */
984:
985: GETSHORT(qtype, p);
986: GETSHORT(qclass, p);
987: GETLONG(ttl, p);
988: GETSHORT(rdlen, p);
989:
990: if (qclass == C_IN && qtype == T_A)
991: {
992: if (!CHECK_LEN(header, p, qlen, INADDRSZ))
993: return 0;
994:
995: for (baddrp = baddr; baddrp; baddrp = baddrp->next)
996: if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
997: {
998: /* Found a bogus address. Insert that info here, since there no SOA record
999: to get the ttl from in the normal processing */
1000: cache_start_insert();
1.1.1.2 misho 1001: cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
1.1 misho 1002: cache_end_insert();
1003:
1004: return 1;
1005: }
1006: }
1007:
1008: if (!ADD_RDLEN(header, p, qlen, rdlen))
1009: return 0;
1010: }
1011:
1012: return 0;
1013: }
1014:
1.1.1.3 ! misho 1015: int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr)
! 1016: {
! 1017: unsigned char *p;
! 1018: int i, qtype, qclass, rdlen;
! 1019: struct bogus_addr *baddrp;
! 1020:
! 1021: /* skip over questions */
! 1022: if (!(p = skip_questions(header, qlen)))
! 1023: return 0; /* bad packet */
! 1024:
! 1025: for (i = ntohs(header->ancount); i != 0; i--)
! 1026: {
! 1027: if (!(p = skip_name(p, header, qlen, 10)))
! 1028: return 0; /* bad packet */
! 1029:
! 1030: GETSHORT(qtype, p);
! 1031: GETSHORT(qclass, p);
! 1032: p += 4; /* TTL */
! 1033: GETSHORT(rdlen, p);
! 1034:
! 1035: if (qclass == C_IN && qtype == T_A)
! 1036: {
! 1037: if (!CHECK_LEN(header, p, qlen, INADDRSZ))
! 1038: return 0;
! 1039:
! 1040: for (baddrp = baddr; baddrp; baddrp = baddrp->next)
! 1041: if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
! 1042: return 1;
! 1043: }
! 1044:
! 1045: if (!ADD_RDLEN(header, p, qlen, rdlen))
! 1046: return 0;
! 1047: }
! 1048:
! 1049: return 0;
! 1050: }
! 1051:
1.1 misho 1052: int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp,
1053: unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
1054: {
1055: va_list ap;
1056: unsigned char *sav, *p = *pp;
1057: int j;
1058: unsigned short usval;
1059: long lval;
1060: char *sval;
1061:
1062: if (truncp && *truncp)
1063: return 0;
1064:
1065: va_start(ap, format); /* make ap point to 1st unamed argument */
1066:
1067: if (nameoffset > 0)
1068: {
1069: PUTSHORT(nameoffset | 0xc000, p);
1070: }
1071: else
1072: {
1073: char *name = va_arg(ap, char *);
1074: if (name)
1075: p = do_rfc1035_name(p, name);
1076: if (nameoffset < 0)
1077: {
1078: PUTSHORT(-nameoffset | 0xc000, p);
1079: }
1080: else
1081: *p++ = 0;
1082: }
1083:
1084: PUTSHORT(type, p);
1085: PUTSHORT(class, p);
1086: PUTLONG(ttl, p); /* TTL */
1087:
1088: sav = p; /* Save pointer to RDLength field */
1089: PUTSHORT(0, p); /* Placeholder RDLength */
1090:
1091: for (; *format; format++)
1092: switch (*format)
1093: {
1094: #ifdef HAVE_IPV6
1095: case '6':
1096: sval = va_arg(ap, char *);
1097: memcpy(p, sval, IN6ADDRSZ);
1098: p += IN6ADDRSZ;
1099: break;
1100: #endif
1101:
1102: case '4':
1103: sval = va_arg(ap, char *);
1104: memcpy(p, sval, INADDRSZ);
1105: p += INADDRSZ;
1106: break;
1107:
1.1.1.2 misho 1108: case 'b':
1109: usval = va_arg(ap, int);
1110: *p++ = usval;
1111: break;
1112:
1.1 misho 1113: case 's':
1114: usval = va_arg(ap, int);
1115: PUTSHORT(usval, p);
1116: break;
1117:
1118: case 'l':
1119: lval = va_arg(ap, long);
1120: PUTLONG(lval, p);
1121: break;
1122:
1123: case 'd':
1124: /* get domain-name answer arg and store it in RDATA field */
1125: if (offset)
1126: *offset = p - (unsigned char *)header;
1127: p = do_rfc1035_name(p, va_arg(ap, char *));
1128: *p++ = 0;
1129: break;
1130:
1131: case 't':
1132: usval = va_arg(ap, int);
1133: sval = va_arg(ap, char *);
1134: if (usval != 0)
1135: memcpy(p, sval, usval);
1136: p += usval;
1137: break;
1138:
1139: case 'z':
1140: sval = va_arg(ap, char *);
1141: usval = sval ? strlen(sval) : 0;
1142: if (usval > 255)
1143: usval = 255;
1144: *p++ = (unsigned char)usval;
1145: memcpy(p, sval, usval);
1146: p += usval;
1147: break;
1148: }
1149:
1150: va_end(ap); /* clean up variable argument pointer */
1151:
1152: j = p - sav - 2;
1153: PUTSHORT(j, sav); /* Now, store real RDLength */
1154:
1155: /* check for overflow of buffer */
1156: if (limit && ((unsigned char *)limit - p) < 0)
1157: {
1158: if (truncp)
1159: *truncp = 1;
1160: return 0;
1161: }
1162:
1163: *pp = p;
1164: return 1;
1165: }
1166:
1167: static unsigned long crec_ttl(struct crec *crecp, time_t now)
1168: {
1169: /* Return 0 ttl for DHCP entries, which might change
1.1.1.3 ! misho 1170: before the lease expires, unless configured otherwise. */
1.1 misho 1171:
1.1.1.3 ! misho 1172: if (crecp->flags & F_DHCP)
! 1173: {
! 1174: int conf_ttl = daemon->use_dhcp_ttl ? daemon->dhcp_ttl : daemon->local_ttl;
! 1175:
! 1176: /* Apply ceiling of actual lease length to configured TTL. */
! 1177: if (!(crecp->flags & F_IMMORTAL) && (crecp->ttd - now) < conf_ttl)
! 1178: return crecp->ttd - now;
! 1179:
! 1180: return conf_ttl;
! 1181: }
1.1 misho 1182:
1.1.1.3 ! misho 1183: /* Immortal entries other than DHCP are local, and hold TTL in TTD field. */
! 1184: if (crecp->flags & F_IMMORTAL)
! 1185: return crecp->ttd;
! 1186:
1.1 misho 1187: /* Return the Max TTL value if it is lower then the actual TTL */
1188: if (daemon->max_ttl == 0 || ((unsigned)(crecp->ttd - now) < daemon->max_ttl))
1189: return crecp->ttd - now;
1190: else
1191: return daemon->max_ttl;
1192: }
1193:
1194:
1195: /* return zero if we can't answer from cache, or packet size if we can */
1196: size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
1.1.1.2 misho 1197: struct in_addr local_addr, struct in_addr local_netmask,
1.1.1.3 ! misho 1198: time_t now, int ad_reqd, int do_bit, int have_pseudoheader)
1.1 misho 1199: {
1200: char *name = daemon->namebuff;
1.1.1.3 ! misho 1201: unsigned char *p, *ansp;
1.1.1.2 misho 1202: unsigned int qtype, qclass;
1.1 misho 1203: struct all_addr addr;
1204: int nameoffset;
1205: unsigned short flag;
1206: int q, ans, anscount = 0, addncount = 0;
1.1.1.3 ! misho 1207: int dryrun = 0;
1.1 misho 1208: struct crec *crecp;
1.1.1.2 misho 1209: int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1;
1.1 misho 1210: struct mx_srv_record *rec;
1.1.1.2 misho 1211: size_t len;
1.1.1.3 ! misho 1212:
! 1213: if (ntohs(header->ancount) != 0 ||
! 1214: ntohs(header->nscount) != 0 ||
! 1215: ntohs(header->qdcount) == 0 ||
! 1216: OPCODE(header) != QUERY )
! 1217: return 0;
! 1218:
1.1.1.2 misho 1219: /* Don't return AD set if checking disabled. */
1220: if (header->hb4 & HB4_CD)
1221: sec_data = 0;
1222:
1.1.1.3 ! misho 1223: /* If there is an additional data section then it will be overwritten by
1.1 misho 1224: partial replies, so we have to do a dry run to see if we can answer
1.1.1.3 ! misho 1225: the query. */
! 1226: if (ntohs(header->arcount) != 0)
! 1227: dryrun = 1;
1.1 misho 1228:
1229: for (rec = daemon->mxnames; rec; rec = rec->next)
1230: rec->offset = 0;
1231:
1232: rerun:
1233: /* determine end of question section (we put answers there) */
1234: if (!(ansp = skip_questions(header, qlen)))
1235: return 0; /* bad packet */
1236:
1237: /* now process each question, answers go in RRs after the question */
1238: p = (unsigned char *)(header+1);
1239:
1240: for (q = ntohs(header->qdcount); q != 0; q--)
1241: {
1242: /* save pointer to name for copying into answers */
1243: nameoffset = p - (unsigned char *)header;
1244:
1245: /* now extract name as .-concatenated string into name */
1246: if (!extract_name(header, qlen, &p, name, 1, 4))
1247: return 0; /* bad packet */
1248:
1249: GETSHORT(qtype, p);
1250: GETSHORT(qclass, p);
1251:
1252: ans = 0; /* have we answered this question */
1253:
1254: if (qtype == T_TXT || qtype == T_ANY)
1255: {
1256: struct txt_record *t;
1257: for(t = daemon->txt; t ; t = t->next)
1258: {
1259: if (t->class == qclass && hostname_isequal(name, t->name))
1260: {
1261: ans = 1;
1262: if (!dryrun)
1263: {
1.1.1.2 misho 1264: unsigned long ttl = daemon->local_ttl;
1265: int ok = 1;
1.1 misho 1266: log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
1.1.1.2 misho 1267: /* Dynamically generate stat record */
1268: if (t->stat != 0)
1269: {
1270: ttl = 0;
1271: if (!cache_make_stat(t))
1272: ok = 0;
1273: }
1274:
1275: if (ok && add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1276: ttl, NULL,
1277: T_TXT, t->class, "t", t->len, t->txt))
1.1 misho 1278: anscount++;
1279:
1280: }
1281: }
1282: }
1283: }
1284:
1285: if (qclass == C_IN)
1286: {
1287: struct txt_record *t;
1288:
1289: for (t = daemon->rr; t; t = t->next)
1290: if ((t->class == qtype || qtype == T_ANY) && hostname_isequal(name, t->name))
1291: {
1292: ans = 1;
1.1.1.3 ! misho 1293: sec_data = 0;
1.1 misho 1294: if (!dryrun)
1295: {
1296: log_query(F_CONFIG | F_RRNAME, name, NULL, "<RR>");
1297: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1298: daemon->local_ttl, NULL,
1299: t->class, C_IN, "t", t->len, t->txt))
1300: anscount ++;
1301: }
1302: }
1303:
1304: if (qtype == T_PTR || qtype == T_ANY)
1305: {
1306: /* see if it's w.z.y.z.in-addr.arpa format */
1307: int is_arpa = in_arpa_name_2_addr(name, &addr);
1308: struct ptr_record *ptr;
1309: struct interface_name* intr = NULL;
1310:
1311: for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1312: if (hostname_isequal(name, ptr->name))
1313: break;
1314:
1315: if (is_arpa == F_IPV4)
1316: for (intr = daemon->int_names; intr; intr = intr->next)
1317: {
1.1.1.2 misho 1318: struct addrlist *addrlist;
1319:
1320: for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1321: if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
1322: break;
1323:
1324: if (addrlist)
1.1 misho 1325: break;
1326: else
1327: while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1328: intr = intr->next;
1329: }
1.1.1.2 misho 1330: #ifdef HAVE_IPV6
1331: else if (is_arpa == F_IPV6)
1332: for (intr = daemon->int_names; intr; intr = intr->next)
1333: {
1334: struct addrlist *addrlist;
1335:
1336: for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1337: if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
1338: break;
1339:
1340: if (addrlist)
1341: break;
1342: else
1343: while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1344: intr = intr->next;
1345: }
1346: #endif
1.1 misho 1347:
1348: if (intr)
1349: {
1.1.1.3 ! misho 1350: sec_data = 0;
1.1 misho 1351: ans = 1;
1352: if (!dryrun)
1353: {
1.1.1.2 misho 1354: log_query(is_arpa | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
1.1 misho 1355: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1356: daemon->local_ttl, NULL,
1357: T_PTR, C_IN, "d", intr->name))
1358: anscount++;
1359: }
1360: }
1361: else if (ptr)
1362: {
1363: ans = 1;
1.1.1.3 ! misho 1364: sec_data = 0;
1.1 misho 1365: if (!dryrun)
1366: {
1367: log_query(F_CONFIG | F_RRNAME, name, NULL, "<PTR>");
1368: for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1369: if (hostname_isequal(name, ptr->name) &&
1370: add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1371: daemon->local_ttl, NULL,
1372: T_PTR, C_IN, "d", ptr->ptr))
1373: anscount++;
1374:
1375: }
1376: }
1377: else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
1.1.1.2 misho 1378: {
1.1.1.3 ! misho 1379: /* Don't use cache when DNSSEC data required, unless we know that
! 1380: the zone is unsigned, which implies that we're doing
! 1381: validation. */
! 1382: if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
! 1383: !do_bit ||
! 1384: (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))
1.1.1.2 misho 1385: {
1386: do
1387: {
1388: /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
1389: if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1390: continue;
1391:
1392: if (!(crecp->flags & F_DNSSECOK))
1393: sec_data = 0;
1.1.1.3 ! misho 1394:
! 1395: ans = 1;
! 1396:
1.1.1.2 misho 1397: if (crecp->flags & F_NEG)
1398: {
1399: auth = 0;
1400: if (crecp->flags & F_NXDOMAIN)
1401: nxdomain = 1;
1402: if (!dryrun)
1403: log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
1404: }
1.1.1.3 ! misho 1405: else
1.1.1.2 misho 1406: {
1407: if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1408: auth = 0;
1409: if (!dryrun)
1410: {
1411: log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
1412: record_source(crecp->uid));
1413:
1414: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1415: crec_ttl(crecp, now), NULL,
1416: T_PTR, C_IN, "d", cache_get_name(crecp)))
1417: anscount++;
1418: }
1419: }
1420: } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
1421: }
1422: }
1423: else if (is_rev_synth(is_arpa, &addr, name))
1424: {
1425: ans = 1;
1.1.1.3 ! misho 1426: sec_data = 0;
1.1.1.2 misho 1427: if (!dryrun)
1428: {
1429: log_query(F_CONFIG | F_REVERSE | is_arpa, name, &addr, NULL);
1430:
1431: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1432: daemon->local_ttl, NULL,
1433: T_PTR, C_IN, "d", name))
1.1 misho 1434: anscount++;
1.1.1.2 misho 1435: }
1436: }
1.1 misho 1437: else if (is_arpa == F_IPV4 &&
1438: option_bool(OPT_BOGUSPRIV) &&
1439: private_net(addr.addr.addr4, 1))
1440: {
1441: /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
1442: ans = 1;
1.1.1.3 ! misho 1443: sec_data = 0;
1.1 misho 1444: nxdomain = 1;
1445: if (!dryrun)
1446: log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN,
1447: name, &addr, NULL);
1448: }
1449: }
1450:
1451: for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
1452: {
1453: unsigned short type = T_A;
1.1.1.2 misho 1454: struct interface_name *intr;
1455:
1.1 misho 1456: if (flag == F_IPV6)
1457: #ifdef HAVE_IPV6
1458: type = T_AAAA;
1459: #else
1460: break;
1461: #endif
1462:
1463: if (qtype != type && qtype != T_ANY)
1464: continue;
1465:
1466: /* Check for "A for A" queries; be rather conservative
1467: about what looks like dotted-quad. */
1468: if (qtype == T_A)
1469: {
1470: char *cp;
1471: unsigned int i, a;
1472: int x;
1473:
1474: for (cp = name, i = 0, a = 0; *cp; i++)
1475: {
1476: if (!isdigit((unsigned char)*cp) || (x = strtol(cp, &cp, 10)) > 255)
1477: {
1478: i = 5;
1479: break;
1480: }
1481:
1482: a = (a << 8) + x;
1483:
1484: if (*cp == '.')
1485: cp++;
1486: }
1487:
1488: if (i == 4)
1489: {
1490: ans = 1;
1.1.1.3 ! misho 1491: sec_data = 0;
1.1 misho 1492: if (!dryrun)
1493: {
1494: addr.addr.addr4.s_addr = htonl(a);
1495: log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
1496: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1497: daemon->local_ttl, NULL, type, C_IN, "4", &addr))
1498: anscount++;
1499: }
1500: continue;
1501: }
1502: }
1503:
1504: /* interface name stuff */
1.1.1.2 misho 1505: intname_restart:
1506: for (intr = daemon->int_names; intr; intr = intr->next)
1507: if (hostname_isequal(name, intr->name))
1508: break;
1509:
1510: if (intr)
1.1 misho 1511: {
1.1.1.2 misho 1512: struct addrlist *addrlist;
1513: int gotit = 0;
1.1 misho 1514:
1.1.1.2 misho 1515: enumerate_interfaces(0);
1516:
1.1 misho 1517: for (intr = daemon->int_names; intr; intr = intr->next)
1518: if (hostname_isequal(name, intr->name))
1.1.1.2 misho 1519: {
1.1.1.3 ! misho 1520: for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1.1.1.2 misho 1521: #ifdef HAVE_IPV6
1.1.1.3 ! misho 1522: if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
1.1.1.2 misho 1523: #endif
1.1.1.3 ! misho 1524: {
! 1525: #ifdef HAVE_IPV6
! 1526: if (addrlist->flags & ADDRLIST_REVONLY)
! 1527: continue;
! 1528: #endif
! 1529: ans = 1;
! 1530: sec_data = 0;
! 1531: if (!dryrun)
1.1.1.2 misho 1532: {
1533: gotit = 1;
1534: log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
1535: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1536: daemon->local_ttl, NULL, type, C_IN,
1537: type == T_A ? "4" : "6", &addrlist->addr))
1538: anscount++;
1539: }
1.1.1.3 ! misho 1540: }
1.1.1.2 misho 1541: }
1.1 misho 1542:
1.1.1.2 misho 1543: if (!dryrun && !gotit)
1544: log_query(F_FORWARD | F_CONFIG | flag | F_NEG, name, NULL, NULL);
1545:
1546: continue;
1.1 misho 1547: }
1548:
1549: cname_restart:
1.1.1.2 misho 1550: if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME | (dryrun ? F_NO_RR : 0))))
1.1 misho 1551: {
1552: int localise = 0;
1553:
1554: /* See if a putative address is on the network from which we recieved
1555: the query, is so we'll filter other answers. */
1556: if (local_addr.s_addr != 0 && option_bool(OPT_LOCALISE) && flag == F_IPV4)
1557: {
1558: struct crec *save = crecp;
1559: do {
1560: if ((crecp->flags & F_HOSTS) &&
1561: is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1562: {
1563: localise = 1;
1564: break;
1565: }
1566: } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
1567: crecp = save;
1568: }
1.1.1.2 misho 1569:
1.1.1.3 ! misho 1570: /* If the client asked for DNSSEC don't use cached data. */
! 1571: if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !do_bit || !(crecp->flags & F_DNSSECOK))
1.1.1.2 misho 1572: do
1573: {
1574: /* don't answer wildcard queries with data not from /etc/hosts
1575: or DHCP leases */
1576: if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
1577: break;
1578:
1579: if (!(crecp->flags & F_DNSSECOK))
1580: sec_data = 0;
1581:
1582: if (crecp->flags & F_CNAME)
1583: {
1584: char *cname_target = cache_get_cname_target(crecp);
1585:
1586: if (!dryrun)
1587: {
1588: log_query(crecp->flags, name, NULL, record_source(crecp->uid));
1589: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1590: crec_ttl(crecp, now), &nameoffset,
1591: T_CNAME, C_IN, "d", cname_target))
1592: anscount++;
1593: }
1594:
1595: strcpy(name, cname_target);
1596: /* check if target interface_name */
1597: if (crecp->addr.cname.uid == SRC_INTERFACE)
1598: goto intname_restart;
1599: else
1600: goto cname_restart;
1601: }
1602:
1603: if (crecp->flags & F_NEG)
1604: {
1.1.1.3 ! misho 1605: ans = 1;
! 1606: auth = 0;
! 1607: if (crecp->flags & F_NXDOMAIN)
! 1608: nxdomain = 1;
! 1609: if (!dryrun)
! 1610: log_query(crecp->flags, name, NULL, NULL);
1.1.1.2 misho 1611: }
1612: else
1613: {
1614: /* If we are returning local answers depending on network,
1615: filter here. */
1616: if (localise &&
1617: (crecp->flags & F_HOSTS) &&
1618: !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1619: continue;
1620:
1621: if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1622: auth = 0;
1623:
1624: ans = 1;
1625: if (!dryrun)
1626: {
1627: log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
1628: record_source(crecp->uid));
1629:
1630: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1631: crec_ttl(crecp, now), NULL, type, C_IN,
1632: type == T_A ? "4" : "6", &crecp->addr))
1633: anscount++;
1634: }
1635: }
1636: } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
1637: }
1638: else if (is_name_synthetic(flag, name, &addr))
1639: {
1640: ans = 1;
1641: if (!dryrun)
1642: {
1643: log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
1644: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1645: daemon->local_ttl, NULL, type, C_IN, type == T_A ? "4" : "6", &addr))
1646: anscount++;
1647: }
1.1 misho 1648: }
1649: }
1650:
1651: if (qtype == T_CNAME || qtype == T_ANY)
1652: {
1653: if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME)) &&
1.1.1.2 misho 1654: (qtype == T_CNAME || (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG | (dryrun ? F_NO_RR : 0)))))
1.1 misho 1655: {
1.1.1.2 misho 1656: if (!(crecp->flags & F_DNSSECOK))
1657: sec_data = 0;
1658:
1.1 misho 1659: ans = 1;
1660: if (!dryrun)
1661: {
1662: log_query(crecp->flags, name, NULL, record_source(crecp->uid));
1663: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1664: crec_ttl(crecp, now), &nameoffset,
1.1.1.2 misho 1665: T_CNAME, C_IN, "d", cache_get_cname_target(crecp)))
1.1 misho 1666: anscount++;
1667: }
1668: }
1669: }
1.1.1.2 misho 1670:
1.1 misho 1671: if (qtype == T_MX || qtype == T_ANY)
1672: {
1673: int found = 0;
1674: for (rec = daemon->mxnames; rec; rec = rec->next)
1675: if (!rec->issrv && hostname_isequal(name, rec->name))
1676: {
1677: ans = found = 1;
1678: if (!dryrun)
1679: {
1680: int offset;
1681: log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
1682: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1683: &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
1684: {
1685: anscount++;
1686: if (rec->target)
1687: rec->offset = offset;
1688: }
1689: }
1690: }
1691:
1692: if (!found && (option_bool(OPT_SELFMX) || option_bool(OPT_LOCALMX)) &&
1.1.1.2 misho 1693: cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP | F_NO_RR))
1.1 misho 1694: {
1695: ans = 1;
1696: if (!dryrun)
1697: {
1698: log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
1699: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
1700: T_MX, C_IN, "sd", 1,
1701: option_bool(OPT_SELFMX) ? name : daemon->mxtarget))
1702: anscount++;
1703: }
1704: }
1705: }
1706:
1707: if (qtype == T_SRV || qtype == T_ANY)
1708: {
1709: int found = 0;
1710: struct mx_srv_record *move = NULL, **up = &daemon->mxnames;
1711:
1712: for (rec = daemon->mxnames; rec; rec = rec->next)
1713: if (rec->issrv && hostname_isequal(name, rec->name))
1714: {
1715: found = ans = 1;
1716: if (!dryrun)
1717: {
1718: int offset;
1719: log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>");
1720: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1721: &offset, T_SRV, C_IN, "sssd",
1722: rec->priority, rec->weight, rec->srvport, rec->target))
1723: {
1724: anscount++;
1725: if (rec->target)
1726: rec->offset = offset;
1727: }
1728: }
1729:
1730: /* unlink first SRV record found */
1731: if (!move)
1732: {
1733: move = rec;
1734: *up = rec->next;
1735: }
1736: else
1737: up = &rec->next;
1738: }
1739: else
1740: up = &rec->next;
1741:
1742: /* put first SRV record back at the end. */
1743: if (move)
1744: {
1745: *up = move;
1746: move->next = NULL;
1747: }
1748:
1749: if (!found && option_bool(OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
1750: {
1751: ans = 1;
1752: if (!dryrun)
1753: log_query(F_CONFIG | F_NEG, name, NULL, NULL);
1754: }
1755: }
1756:
1757: if (qtype == T_NAPTR || qtype == T_ANY)
1758: {
1759: struct naptr *na;
1760: for (na = daemon->naptr; na; na = na->next)
1761: if (hostname_isequal(name, na->name))
1762: {
1763: ans = 1;
1764: if (!dryrun)
1765: {
1766: log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>");
1767: if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1768: NULL, T_NAPTR, C_IN, "sszzzd",
1769: na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
1770: anscount++;
1771: }
1772: }
1773: }
1774:
1775: if (qtype == T_MAILB)
1776: ans = 1, nxdomain = 1;
1777:
1778: if (qtype == T_SOA && option_bool(OPT_FILTER))
1779: {
1780: ans = 1;
1781: if (!dryrun)
1782: log_query(F_CONFIG | F_NEG, name, &addr, NULL);
1783: }
1784: }
1785:
1786: if (!ans)
1787: return 0; /* failed to answer a question */
1788: }
1789:
1790: if (dryrun)
1791: {
1792: dryrun = 0;
1793: goto rerun;
1794: }
1795:
1796: /* create an additional data section, for stuff in SRV and MX record replies. */
1797: for (rec = daemon->mxnames; rec; rec = rec->next)
1798: if (rec->offset != 0)
1799: {
1800: /* squash dupes */
1801: struct mx_srv_record *tmp;
1802: for (tmp = rec->next; tmp; tmp = tmp->next)
1803: if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
1804: tmp->offset = 0;
1805:
1806: crecp = NULL;
1807: while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
1808: {
1809: #ifdef HAVE_IPV6
1810: int type = crecp->flags & F_IPV4 ? T_A : T_AAAA;
1811: #else
1812: int type = T_A;
1813: #endif
1814: if (crecp->flags & F_NEG)
1815: continue;
1816:
1817: if (add_resource_record(header, limit, NULL, rec->offset, &ansp,
1818: crec_ttl(crecp, now), NULL, type, C_IN,
1819: crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
1820: addncount++;
1821: }
1822: }
1823:
1824: /* done all questions, set up header and return length of result */
1825: /* clear authoritative and truncated flags, set QR flag */
1826: header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
1827: /* set RA flag */
1828: header->hb4 |= HB4_RA;
1829:
1830: /* authoritive - only hosts and DHCP derived names. */
1831: if (auth)
1832: header->hb3 |= HB3_AA;
1833:
1834: /* truncation */
1835: if (trunc)
1836: header->hb3 |= HB3_TC;
1.1.1.2 misho 1837:
1838: if (nxdomain)
1.1 misho 1839: SET_RCODE(header, NXDOMAIN);
1840: else
1841: SET_RCODE(header, NOERROR); /* no error */
1842: header->ancount = htons(anscount);
1843: header->nscount = htons(0);
1844: header->arcount = htons(addncount);
1.1.1.2 misho 1845:
1846: len = ansp - (unsigned char *)header;
1847:
1.1.1.3 ! misho 1848: /* Advertise our packet size limit in our reply */
1.1.1.2 misho 1849: if (have_pseudoheader)
1.1.1.3 ! misho 1850: len = add_pseudoheader(header, len, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
1.1.1.2 misho 1851:
1.1.1.3 ! misho 1852: if (ad_reqd && sec_data)
1.1.1.2 misho 1853: header->hb4 |= HB4_AD;
1854: else
1855: header->hb4 &= ~HB4_AD;
1856:
1857: return len;
1.1 misho 1858: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>