]> git.ipfire.org Git - people/ms/dnsmasq.git/blame - src/rfc1035.c
Check IPv4-mapped IPv6 addresses with --stop-rebind.
[people/ms/dnsmasq.git] / src / rfc1035.c
CommitLineData
aff33962 1/* dnsmasq is Copyright (c) 2000-2015 Simon Kelley
9e4abcb5
SK
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
824af85b
SK
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
7
9e4abcb5
SK
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.
824af85b 12
73a08a24
SK
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/>.
9e4abcb5
SK
15*/
16
17#include "dnsmasq.h"
18
4f7b304f
SK
19int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
20 char *name, int isExtract, int extrabytes)
9e4abcb5 21{
3d8df260 22 unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL;
b8f16556 23 unsigned int j, l, namelen = 0, hops = 0;
9e4abcb5
SK
24 int retvalue = 1;
25
f6b7dc47
SK
26 if (isExtract)
27 *cp = 0;
28
9009d746
SK
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
9e4abcb5
SK
62 if (label_type == 0xc0) /* pointer */
63 {
9009d746 64 if (!CHECK_LEN(header, p, plen, 1))
9e4abcb5
SK
65 return 0;
66
67 /* get offset */
68 l = (l&0x3f) << 8;
69 l |= *p++;
9e4abcb5
SK
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 == 0x80)
81 return 0; /* reserved */
82 else if (label_type == 0x40)
83 { /* ELT */
84 unsigned int count, digs;
85
86 if ((l & 0x3f) != 1)
87 return 0; /* we only understand bitstrings */
88
394ff492 89 if (!isExtract)
9e4abcb5
SK
90 return 0; /* Cannot compare bitsrings */
91
92 count = *p++;
93 if (count == 0)
94 count = 256;
95 digs = ((count-1)>>2)+1;
96
b8f16556
SK
97 /* output is \[x<hex>/siz]. which is digs+6/7/8 chars */
98 namelen += digs+6;
99 if (count > 9)
100 namelen++;
101 if (count > 99)
102 namelen++;
103 if (namelen+1 >= MAXDNAME)
9e4abcb5 104 return 0;
b8f16556 105
9009d746 106 if (!CHECK_LEN(header, p, plen, (count-1)>>3))
9e4abcb5
SK
107 return 0;
108
109 *cp++ = '\\';
110 *cp++ = '[';
111 *cp++ = 'x';
112 for (j=0; j<digs; j++)
113 {
114 unsigned int dig;
115 if (j%2 == 0)
116 dig = *p >> 4;
117 else
118 dig = *p++ & 0x0f;
119
120 *cp++ = dig < 10 ? dig + '0' : dig + 'A' - 10;
121 }
3d8df260 122 cp += sprintf((char *)cp, "/%d]", count);
9e4abcb5
SK
123 /* do this here to overwrite the zero char from sprintf */
124 *cp++ = '.';
125 }
126 else
127 { /* label_type = 0 -> label. */
b8f16556
SK
128 namelen += l;
129 if (namelen+1 >= MAXDNAME)
9e4abcb5 130 return 0;
9009d746 131 if (!CHECK_LEN(header, p, plen, l))
9e4abcb5 132 return 0;
9009d746 133
9e4abcb5
SK
134 for(j=0; j<l; j++, p++)
135 if (isExtract)
136 {
1f15b81d 137 unsigned char c = *p;
cbe379ad
SK
138#ifdef HAVE_DNSSEC
139 if (option_bool(OPT_DNSSEC_VALID))
140 {
141 if (c == 0 || c == '.' || c == NAME_ESCAPE)
b8f16556
SK
142 {
143 *cp++ = NAME_ESCAPE;
144 *cp++ = c+1;
145 }
146 else
147 *cp++ = c;
cbe379ad
SK
148 }
149 else
150#endif
394ff492
SK
151 if (c != 0 && c != '.')
152 *cp++ = c;
9e4abcb5
SK
153 else
154 return 0;
155 }
156 else
157 {
158 unsigned char c1 = *cp, c2 = *p;
159
160 if (c1 == 0)
161 retvalue = 2;
162 else
163 {
164 cp++;
165 if (c1 >= 'A' && c1 <= 'Z')
166 c1 += 'a' - 'A';
cbe379ad
SK
167#ifdef HAVE_DNSSEC
168 if (option_bool(OPT_DNSSEC_VALID) && c1 == NAME_ESCAPE)
b8f16556 169 c1 = (*cp++)-1;
cbe379ad
SK
170#endif
171
9e4abcb5
SK
172 if (c2 >= 'A' && c2 <= 'Z')
173 c2 += 'a' - 'A';
cbe379ad 174
9e4abcb5
SK
175 if (c1 != c2)
176 retvalue = 2;
177 }
178 }
179
180 if (isExtract)
181 *cp++ = '.';
f6b7dc47
SK
182 else if (*cp != 0 && *cp++ != '.')
183 retvalue = 2;
9e4abcb5 184 }
309331f5 185 }
9e4abcb5
SK
186}
187
188/* Max size of input string (for IPv6) is 75 chars.) */
189#define MAXARPANAME 75
4f7b304f 190int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
9e4abcb5
SK
191{
192 int j;
193 char name[MAXARPANAME+1], *cp1;
194 unsigned char *addr = (unsigned char *)addrp;
195 char *lastchunk = NULL, *penchunk = NULL;
196
197 if (strlen(namein) > MAXARPANAME)
198 return 0;
199
200 memset(addrp, 0, sizeof(struct all_addr));
201
202 /* turn name into a series of asciiz strings */
203 /* j counts no of labels */
204 for(j = 1,cp1 = name; *namein; cp1++, namein++)
205 if (*namein == '.')
206 {
207 penchunk = lastchunk;
208 lastchunk = cp1 + 1;
209 *cp1 = 0;
210 j++;
211 }
212 else
213 *cp1 = *namein;
214
215 *cp1 = 0;
216
217 if (j<3)
218 return 0;
219
220 if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr"))
221 {
222 /* IP v4 */
223 /* address arives as a name of the form
224 www.xxx.yyy.zzz.in-addr.arpa
225 some of the low order address octets might be missing
226 and should be set to zero. */
227 for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
228 {
229 /* check for digits only (weeds out things like
230 50.0/24.67.28.64.in-addr.arpa which are used
231 as CNAME targets according to RFC 2317 */
232 char *cp;
233 for (cp = cp1; *cp; cp++)
572b41eb 234 if (!isdigit((unsigned char)*cp))
9e4abcb5
SK
235 return 0;
236
237 addr[3] = addr[2];
238 addr[2] = addr[1];
239 addr[1] = addr[0];
240 addr[0] = atoi(cp1);
241 }
242
243 return F_IPV4;
244 }
245#ifdef HAVE_IPV6
246 else if (hostname_isequal(penchunk, "ip6") &&
247 (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa")))
248 {
249 /* IP v6:
250 Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
251 or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]
252
253 Note that most of these the various reprentations are obsolete and
254 left-over from the many DNS-for-IPv6 wars. We support all the formats
255 that we can since there is no reason not to.
256 */
257
258 if (*name == '\\' && *(name+1) == '[' &&
259 (*(name+2) == 'x' || *(name+2) == 'X'))
260 {
572b41eb 261 for (j = 0, cp1 = name+3; *cp1 && isxdigit((unsigned char) *cp1) && j < 32; cp1++, j++)
9e4abcb5
SK
262 {
263 char xdig[2];
264 xdig[0] = *cp1;
265 xdig[1] = 0;
266 if (j%2)
267 addr[j/2] |= strtol(xdig, NULL, 16);
268 else
269 addr[j/2] = strtol(xdig, NULL, 16) << 4;
270 }
271
272 if (*cp1 == '/' && j == 32)
273 return F_IPV6;
274 }
275 else
276 {
277 for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
278 {
572b41eb 279 if (*(cp1+1) || !isxdigit((unsigned char)*cp1))
9e4abcb5
SK
280 return 0;
281
282 for (j = sizeof(struct all_addr)-1; j>0; j--)
283 addr[j] = (addr[j] >> 4) | (addr[j-1] << 4);
284 addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
285 }
286
287 return F_IPV6;
288 }
289 }
290#endif
291
292 return 0;
293}
294
32f82c62 295unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes)
9e4abcb5 296{
feba5c1d 297 while(1)
9e4abcb5 298 {
9009d746 299 unsigned int label_type;
feba5c1d 300
9009d746 301 if (!CHECK_LEN(header, ansp, plen, 1))
feba5c1d
SK
302 return NULL;
303
9009d746
SK
304 label_type = (*ansp) & 0xc0;
305
feba5c1d 306 if (label_type == 0xc0)
9e4abcb5 307 {
feba5c1d
SK
308 /* pointer for compression. */
309 ansp += 2;
310 break;
311 }
312 else if (label_type == 0x80)
313 return NULL; /* reserved */
314 else if (label_type == 0x40)
315 {
316 /* Extended label type */
317 unsigned int count;
9e4abcb5 318
9009d746
SK
319 if (!CHECK_LEN(header, ansp, plen, 2))
320 return NULL;
321
feba5c1d
SK
322 if (((*ansp++) & 0x3f) != 1)
323 return NULL; /* we only understand bitstrings */
9e4abcb5 324
feba5c1d
SK
325 count = *(ansp++); /* Bits in bitstring */
326
327 if (count == 0) /* count == 0 means 256 bits */
328 ansp += 32;
9e4abcb5 329 else
feba5c1d
SK
330 ansp += ((count-1)>>3)+1;
331 }
332 else
333 { /* label type == 0 Bottom six bits is length */
334 unsigned int len = (*ansp++) & 0x3f;
9009d746
SK
335
336 if (!ADD_RDLEN(header, ansp, plen, len))
337 return NULL;
338
feba5c1d
SK
339 if (len == 0)
340 break; /* zero length label marks the end. */
9e4abcb5 341 }
feba5c1d 342 }
9009d746
SK
343
344 if (!CHECK_LEN(header, ansp, plen, extrabytes))
345 return NULL;
feba5c1d
SK
346
347 return ansp;
348}
349
4f7b304f 350unsigned char *skip_questions(struct dns_header *header, size_t plen)
feba5c1d 351{
5aabfc78 352 int q;
feba5c1d
SK
353 unsigned char *ansp = (unsigned char *)(header+1);
354
5aabfc78 355 for (q = ntohs(header->qdcount); q != 0; q--)
feba5c1d 356 {
9009d746 357 if (!(ansp = skip_name(ansp, header, plen, 4)))
feba5c1d 358 return NULL;
9e4abcb5
SK
359 ansp += 4; /* class and type */
360 }
9e4abcb5
SK
361
362 return ansp;
363}
364
5107ace1 365unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen)
feba5c1d 366{
fd9fa481 367 int i, rdlen;
36717eee 368
fd9fa481 369 for (i = 0; i < count; i++)
36717eee 370 {
9009d746 371 if (!(ansp = skip_name(ansp, header, plen, 10)))
fd9fa481 372 return NULL;
36717eee
SK
373 ansp += 8; /* type, class, TTL */
374 GETSHORT(rdlen, ansp);
9009d746 375 if (!ADD_RDLEN(header, ansp, plen, rdlen))
fd9fa481 376 return NULL;
36717eee
SK
377 }
378
fd9fa481
SK
379 return ansp;
380}
381
0a852541
SK
382/* CRC the question section. This is used to safely detect query
383 retransmision and to detect answers to questions we didn't ask, which
384 might be poisoning attacks. Note that we decode the name rather
385 than CRC the raw bytes, since replies might be compressed differently.
832af0ba
SK
386 We ignore case in the names for the same reason. Return all-ones
387 if there is not question section. */
17fb9ea7 388#ifndef HAVE_DNSSEC
572b41eb 389unsigned int questions_crc(struct dns_header *header, size_t plen, char *name)
fd9fa481 390{
91dccd09
SK
391 int q;
392 unsigned int crc = 0xffffffff;
0a852541
SK
393 unsigned char *p1, *p = (unsigned char *)(header+1);
394
5aabfc78 395 for (q = ntohs(header->qdcount); q != 0; q--)
0a852541 396 {
9009d746 397 if (!extract_name(header, plen, &p, name, 1, 4))
0a852541
SK
398 return crc; /* bad packet */
399
3d8df260 400 for (p1 = (unsigned char *)name; *p1; p1++)
0a852541
SK
401 {
402 int i = 8;
403 char c = *p1;
404
405 if (c >= 'A' && c <= 'Z')
406 c += 'a' - 'A';
407
408 crc ^= c << 24;
409 while (i--)
410 crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
411 }
412
413 /* CRC the class and type as well */
414 for (p1 = p; p1 < p+4; p1++)
415 {
416 int i = 8;
417 crc ^= *p1 << 24;
418 while (i--)
419 crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
420 }
421
422 p += 4;
9009d746 423 if (!CHECK_LEN(header, p, plen, 0))
0a852541
SK
424 return crc; /* bad packet */
425 }
fd9fa481 426
fd9fa481
SK
427 return crc;
428}
17fb9ea7 429#endif
fd9fa481 430
572b41eb 431size_t resize_packet(struct dns_header *header, size_t plen, unsigned char *pheader, size_t hlen)
fd9fa481
SK
432{
433 unsigned char *ansp = skip_questions(header, plen);
434
9009d746 435 /* if packet is malformed, just return as-is. */
fd9fa481 436 if (!ansp)
9009d746 437 return plen;
fd9fa481
SK
438
439 if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
440 header, plen)))
9009d746 441 return plen;
fd9fa481 442
36717eee
SK
443 /* restore pseudoheader */
444 if (pheader && ntohs(header->arcount) == 0)
445 {
446 /* must use memmove, may overlap */
447 memmove(ansp, pheader, hlen);
448 header->arcount = htons(1);
449 ansp += hlen;
450 }
451
452 return ansp - (unsigned char *)header;
453}
454
572b41eb 455unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, size_t *len, unsigned char **p, int *is_sign)
36717eee
SK
456{
457 /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
832af0ba
SK
458 also return length of pseudoheader in *len and pointer to the UDP size in *p
459 Finally, check to see if a packet is signed. If it is we cannot change a single bit before
460 forwarding. We look for SIG and TSIG in the addition section, and TKEY queries (for GSS-TSIG) */
feba5c1d
SK
461
462 int i, arcount = ntohs(header->arcount);
832af0ba
SK
463 unsigned char *ansp = (unsigned char *)(header+1);
464 unsigned short rdlen, type, class;
465 unsigned char *ret = NULL;
1b7ecd11
SK
466
467 if (is_sign)
832af0ba 468 {
1b7ecd11
SK
469 *is_sign = 0;
470
572b41eb 471 if (OPCODE(header) == QUERY)
832af0ba 472 {
5aabfc78 473 for (i = ntohs(header->qdcount); i != 0; i--)
1b7ecd11 474 {
9009d746 475 if (!(ansp = skip_name(ansp, header, plen, 4)))
1b7ecd11
SK
476 return NULL;
477
478 GETSHORT(type, ansp);
479 GETSHORT(class, ansp);
480
481 if (class == C_IN && type == T_TKEY)
482 *is_sign = 1;
483 }
832af0ba
SK
484 }
485 }
486 else
487 {
488 if (!(ansp = skip_questions(header, plen)))
489 return NULL;
490 }
491
492 if (arcount == 0)
feba5c1d
SK
493 return NULL;
494
fd9fa481
SK
495 if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount), header, plen)))
496 return NULL;
832af0ba 497
feba5c1d
SK
498 for (i = 0; i < arcount; i++)
499 {
36717eee 500 unsigned char *save, *start = ansp;
9009d746 501 if (!(ansp = skip_name(ansp, header, plen, 10)))
feba5c1d
SK
502 return NULL;
503
504 GETSHORT(type, ansp);
505 save = ansp;
832af0ba
SK
506 GETSHORT(class, ansp);
507 ansp += 4; /* TTL */
feba5c1d 508 GETSHORT(rdlen, ansp);
9009d746 509 if (!ADD_RDLEN(header, ansp, plen, rdlen))
feba5c1d 510 return NULL;
832af0ba 511 if (type == T_OPT)
36717eee
SK
512 {
513 if (len)
514 *len = ansp - start;
515 if (p)
516 *p = save;
832af0ba 517 ret = start;
36717eee 518 }
832af0ba
SK
519 else if (is_sign &&
520 i == arcount - 1 &&
521 class == C_ANY &&
5f8e58f4 522 type == T_TSIG)
832af0ba 523 *is_sign = 1;
feba5c1d
SK
524 }
525
832af0ba 526 return ret;
feba5c1d 527}
28866e95
SK
528
529struct macparm {
530 unsigned char *limit;
572b41eb 531 struct dns_header *header;
28866e95
SK
532 size_t plen;
533 union mysockaddr *l3;
534};
28866e95 535
ed4c0767 536static size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
3a237152 537 int optno, unsigned char *opt, size_t optlen, int set_do)
ed4c0767
SK
538{
539 unsigned char *lenp, *datap, *p;
a25720a3 540 int rdlen, is_sign;
28866e95 541
a25720a3 542 if (!(p = find_pseudoheader(header, plen, NULL, NULL, &is_sign)))
28866e95 543 {
a25720a3
SK
544 if (is_sign)
545 return plen;
546
28866e95 547 /* We are adding the pseudoheader */
ed4c0767 548 if (!(p = skip_questions(header, plen)) ||
28866e95 549 !(p = skip_section(p,
a25720a3 550 ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
ed4c0767
SK
551 header, plen)))
552 return plen;
28866e95
SK
553 *p++ = 0; /* empty name */
554 PUTSHORT(T_OPT, p);
a77cec8d 555 PUTSHORT(SAFE_PKTSZ, p); /* max packet length, this will be overwritten */
3a237152
SK
556 PUTSHORT(0, p); /* extended RCODE and version */
557 PUTSHORT(set_do ? 0x8000 : 0, p); /* DO flag */
28866e95
SK
558 lenp = p;
559 PUTSHORT(0, p); /* RDLEN */
560 rdlen = 0;
ed4c0767
SK
561 if (((ssize_t)optlen) > (limit - (p + 4)))
562 return plen; /* Too big */
a25720a3 563 header->arcount = htons(ntohs(header->arcount) + 1);
28866e95
SK
564 datap = p;
565 }
566 else
567 {
a25720a3 568 int i;
3a237152 569 unsigned short code, len, flags;
28866e95 570
a25720a3 571 /* Must be at the end, if exists */
28866e95 572 if (ntohs(header->arcount) != 1 ||
28866e95 573 is_sign ||
ed4c0767
SK
574 (!(p = skip_name(p, header, plen, 10))))
575 return plen;
28866e95 576
3a237152
SK
577 p += 6; /* skip UDP length and RCODE */
578 GETSHORT(flags, p);
579 if (set_do)
580 {
581 p -=2;
582 PUTSHORT(flags | 0x8000, p);
583 }
584
28866e95
SK
585 lenp = p;
586 GETSHORT(rdlen, p);
ed4c0767
SK
587 if (!CHECK_LEN(header, p, plen, rdlen))
588 return plen; /* bad packet */
28866e95
SK
589 datap = p;
590
3a237152
SK
591 /* no option to add */
592 if (optno == 0)
593 return plen;
594
28866e95
SK
595 /* check if option already there */
596 for (i = 0; i + 4 < rdlen; i += len + 4)
597 {
598 GETSHORT(code, p);
599 GETSHORT(len, p);
ed4c0767
SK
600 if (code == optno)
601 return plen;
28866e95
SK
602 p += len;
603 }
feba5c1d 604
ed4c0767
SK
605 if (((ssize_t)optlen) > (limit - (p + 4)))
606 return plen; /* Too big */
28866e95
SK
607 }
608
0fc2f313
SK
609 if (optno != 0)
610 {
611 PUTSHORT(optno, p);
612 PUTSHORT(optlen, p);
613 memcpy(p, opt, optlen);
614 p += optlen;
615 }
28866e95
SK
616
617 PUTSHORT(p - datap, lenp);
ed4c0767
SK
618 return p - (unsigned char *)header;
619
620}
621
622static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *parmv)
623{
624 struct macparm *parm = parmv;
625 int match = 0;
626
627 if (family == parm->l3->sa.sa_family)
628 {
613ad15d 629 if (family == AF_INET && memcmp(&parm->l3->in.sin_addr, addrp, INADDRSZ) == 0)
ed4c0767
SK
630 match = 1;
631#ifdef HAVE_IPV6
632 else
613ad15d 633 if (family == AF_INET6 && memcmp(&parm->l3->in6.sin6_addr, addrp, IN6ADDRSZ) == 0)
ed4c0767
SK
634 match = 1;
635#endif
636 }
637
638 if (!match)
639 return 1; /* continue */
640
3a237152 641 parm->plen = add_pseudoheader(parm->header, parm->plen, parm->limit, EDNS0_OPTION_MAC, (unsigned char *)mac, maclen, 0);
28866e95
SK
642
643 return 0; /* done */
644}
645
572b41eb 646size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysockaddr *l3)
28866e95
SK
647{
648 struct macparm parm;
649
650/* Must have an existing pseudoheader as the only ar-record,
651 or have no ar-records. Must also not be signed */
652
653 if (ntohs(header->arcount) > 1)
654 return plen;
655
656 parm.header = header;
657 parm.limit = (unsigned char *)limit;
658 parm.plen = plen;
659 parm.l3 = l3;
660
661 iface_enumerate(AF_UNSPEC, &parm, filter_mac);
feba5c1d 662
28866e95
SK
663 return parm.plen;
664}
665
ed4c0767
SK
666struct subnet_opt {
667 u16 family;
668 u8 source_netmask, scope_netmask;
669#ifdef HAVE_IPV6
670 u8 addr[IN6ADDRSZ];
671#else
672 u8 addr[INADDRSZ];
673#endif
674};
675
44de649e 676static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
ed4c0767
SK
677{
678 /* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
679
680 int len;
681 void *addrp;
682
ed4c0767 683#ifdef HAVE_IPV6
24b5a5d5 684 if (source->sa.sa_family == AF_INET6)
ed4c0767
SK
685 {
686 opt->family = htons(2);
687 opt->source_netmask = daemon->addr6_netmask;
688 addrp = &source->in6.sin6_addr;
689 }
24b5a5d5 690 else
ed4c0767 691#endif
24b5a5d5
SK
692 {
693 opt->family = htons(1);
694 opt->source_netmask = daemon->addr4_netmask;
695 addrp = &source->in.sin_addr;
696 }
ed4c0767
SK
697
698 opt->scope_netmask = 0;
699 len = 0;
700
701 if (opt->source_netmask != 0)
702 {
703 len = ((opt->source_netmask - 1) >> 3) + 1;
704 memcpy(opt->addr, addrp, len);
705 if (opt->source_netmask & 7)
706 opt->addr[len-1] &= 0xff << (8 - (opt->source_netmask & 7));
707 }
708
709 return len + 4;
710}
711
712size_t add_source_addr(struct dns_header *header, size_t plen, char *limit, union mysockaddr *source)
713{
714 /* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
715
716 int len;
717 struct subnet_opt opt;
718
719 len = calc_subnet_opt(&opt, source);
3a237152 720 return add_pseudoheader(header, plen, (unsigned char *)limit, EDNS0_OPTION_CLIENT_SUBNET, (unsigned char *)&opt, len, 0);
ed4c0767 721}
3a237152
SK
722
723#ifdef HAVE_DNSSEC
724size_t add_do_bit(struct dns_header *header, size_t plen, char *limit)
725{
726 return add_pseudoheader(header, plen, (unsigned char *)limit, 0, NULL, 0, 1);
727}
728#endif
729
ed4c0767
SK
730int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer)
731{
732 /* Section 9.2, Check that subnet option in reply matches. */
733
734
735 int len, calc_len;
736 struct subnet_opt opt;
737 unsigned char *p;
738 int code, i, rdlen;
739
740 calc_len = calc_subnet_opt(&opt, peer);
741
742 if (!(p = skip_name(pseudoheader, header, plen, 10)))
743 return 1;
744
745 p += 8; /* skip UDP length and RCODE */
746
747 GETSHORT(rdlen, p);
748 if (!CHECK_LEN(header, p, plen, rdlen))
749 return 1; /* bad packet */
750
751 /* check if option there */
752 for (i = 0; i + 4 < rdlen; i += len + 4)
753 {
754 GETSHORT(code, p);
755 GETSHORT(len, p);
756 if (code == EDNS0_OPTION_CLIENT_SUBNET)
757 {
758 /* make sure this doesn't mismatch. */
759 opt.scope_netmask = p[3];
760 if (len != calc_len || memcmp(p, &opt, len) != 0)
761 return 0;
762 }
763 p += len;
764 }
765
766 return 1;
767}
768
9e4abcb5 769/* is addr in the non-globally-routed IP space? */
dc27e148 770int private_net(struct in_addr addr, int ban_localhost)
9e4abcb5 771{
f2621c7f
SK
772 in_addr_t ip_addr = ntohl(addr.s_addr);
773
774 return
8ef5ada2 775 (((ip_addr & 0xFF000000) == 0x7F000000) && ban_localhost) /* 127.0.0.0/8 (loopback) */ ||
f2621c7f
SK
776 ((ip_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168.0.0/16 (private) */ ||
777 ((ip_addr & 0xFF000000) == 0x0A000000) /* 10.0.0.0/8 (private) */ ||
778 ((ip_addr & 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12 (private) */ ||
779 ((ip_addr & 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */ ;
9e4abcb5 780}
fd9fa481 781
6938f347 782static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *header, size_t qlen, char *name, int *doctored)
824af85b
SK
783{
784 int i, qtype, qclass, rdlen;
824af85b
SK
785
786 for (i = count; i != 0; i--)
787 {
28866e95 788 if (name && option_bool(OPT_LOG))
8ef5ada2
SK
789 {
790 if (!extract_name(header, qlen, &p, name, 1, 10))
791 return 0;
792 }
793 else if (!(p = skip_name(p, header, qlen, 10)))
824af85b
SK
794 return 0; /* bad packet */
795
796 GETSHORT(qtype, p);
797 GETSHORT(qclass, p);
7de060b0 798 p += 4; /* ttl */
824af85b
SK
799 GETSHORT(rdlen, p);
800
8ef5ada2 801 if (qclass == C_IN && qtype == T_A)
824af85b
SK
802 {
803 struct doctor *doctor;
804 struct in_addr addr;
805
9009d746
SK
806 if (!CHECK_LEN(header, p, qlen, INADDRSZ))
807 return 0;
8ef5ada2
SK
808
809 /* alignment */
824af85b
SK
810 memcpy(&addr, p, INADDRSZ);
811
812 for (doctor = daemon->doctors; doctor; doctor = doctor->next)
73a08a24
SK
813 {
814 if (doctor->end.s_addr == 0)
815 {
816 if (!is_same_net(doctor->in, addr, doctor->mask))
817 continue;
818 }
819 else if (ntohl(doctor->in.s_addr) > ntohl(addr.s_addr) ||
820 ntohl(doctor->end.s_addr) < ntohl(addr.s_addr))
821 continue;
8ef5ada2 822
73a08a24
SK
823 addr.s_addr &= ~doctor->mask.s_addr;
824 addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
825 /* Since we munged the data, the server it came from is no longer authoritative */
572b41eb 826 header->hb3 &= ~HB3_AA;
6938f347 827 *doctored = 1;
73a08a24
SK
828 memcpy(p, &addr, INADDRSZ);
829 break;
830 }
824af85b 831 }
28866e95 832 else if (qtype == T_TXT && name && option_bool(OPT_LOG))
8ef5ada2
SK
833 {
834 unsigned char *p1 = p;
835 if (!CHECK_LEN(header, p1, qlen, rdlen))
836 return 0;
837 while ((p1 - p) < rdlen)
838 {
839 unsigned int i, len = *p1;
840 unsigned char *p2 = p1;
841 /* make counted string zero-term and sanitise */
842 for (i = 0; i < len; i++)
231d061b
SK
843 {
844 if (!isprint((int)*(p2+1)))
845 break;
846
847 *p2 = *(p2+1);
848 p2++;
849 }
8ef5ada2 850 *p2 = 0;
28866e95 851 my_syslog(LOG_INFO, "reply %s is %s", name, p1);
8ef5ada2 852 /* restore */
231d061b 853 memmove(p1 + 1, p1, i);
8ef5ada2
SK
854 *p1 = len;
855 p1 += len+1;
856 }
857 }
824af85b 858
9009d746
SK
859 if (!ADD_RDLEN(header, p, qlen, rdlen))
860 return 0; /* bad packet */
824af85b
SK
861 }
862
863 return p;
864}
865
6938f347 866static int find_soa(struct dns_header *header, size_t qlen, char *name, int *doctored)
9e4abcb5
SK
867{
868 unsigned char *p;
9e4abcb5 869 int qtype, qclass, rdlen;
fd9fa481
SK
870 unsigned long ttl, minttl = ULONG_MAX;
871 int i, found_soa = 0;
9e4abcb5 872
fd9fa481
SK
873 /* first move to NS section and find TTL from any SOA section */
874 if (!(p = skip_questions(header, qlen)) ||
6938f347 875 !(p = do_doctor(p, ntohs(header->ancount), header, qlen, name, doctored)))
824af85b 876 return 0; /* bad packet */
9e4abcb5 877
5aabfc78 878 for (i = ntohs(header->nscount); i != 0; i--)
9e4abcb5 879 {
9009d746 880 if (!(p = skip_name(p, header, qlen, 10)))
fd9fa481
SK
881 return 0; /* bad packet */
882
9e4abcb5
SK
883 GETSHORT(qtype, p);
884 GETSHORT(qclass, p);
885 GETLONG(ttl, p);
886 GETSHORT(rdlen, p);
fd9fa481 887
9e4abcb5
SK
888 if ((qclass == C_IN) && (qtype == T_SOA))
889 {
fd9fa481
SK
890 found_soa = 1;
891 if (ttl < minttl)
892 minttl = ttl;
893
9e4abcb5 894 /* MNAME */
9009d746 895 if (!(p = skip_name(p, header, qlen, 0)))
fd9fa481 896 return 0;
9e4abcb5 897 /* RNAME */
9009d746 898 if (!(p = skip_name(p, header, qlen, 20)))
fd9fa481
SK
899 return 0;
900 p += 16; /* SERIAL REFRESH RETRY EXPIRE */
901
9e4abcb5
SK
902 GETLONG(ttl, p); /* minTTL */
903 if (ttl < minttl)
904 minttl = ttl;
905 }
9009d746 906 else if (!ADD_RDLEN(header, p, qlen, rdlen))
fd9fa481 907 return 0; /* bad packet */
9e4abcb5 908 }
9009d746 909
6938f347
SK
910 /* rewrite addresses in additional section too */
911 if (!do_doctor(p, ntohs(header->arcount), header, qlen, NULL, doctored))
824af85b
SK
912 return 0;
913
914 if (!found_soa)
915 minttl = daemon->neg_ttl;
916
917 return minttl;
1cff166d
SK
918}
919
fd9fa481
SK
920/* Note that the following code can create CNAME chains that don't point to a real record,
921 either because of lack of memory, or lack of SOA records. These are treated by the cache code as
824af85b 922 expired and cleaned out that way.
8ef5ada2 923 Return 1 if we reject an address because it look like part of dns-rebinding attack. */
572b41eb 924int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t now,
6938f347 925 char **ipsets, int is_sign, int check_rebind, int no_cache_dnssec, int secure, int *doctored)
9e4abcb5 926{
824af85b 927 unsigned char *p, *p1, *endrr, *namep;
fd9fa481 928 int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
0a852541 929 unsigned long ttl = 0;
5aabfc78 930 struct all_addr addr;
13d86c73
JD
931#ifdef HAVE_IPSET
932 char **ipsets_cur;
933#else
934 (void)ipsets; /* unused */
935#endif
936
9e4abcb5 937 cache_start_insert();
0a852541 938
8ef5ada2 939 /* find_soa is needed for dns_doctor and logging side-effects, so don't call it lazily if there are any. */
6938f347 940 if (daemon->doctors || option_bool(OPT_LOG) || option_bool(OPT_DNSSEC_VALID))
0a852541
SK
941 {
942 searched_soa = 1;
6938f347
SK
943 ttl = find_soa(header, qlen, name, doctored);
944#ifdef HAVE_DNSSEC
d1fbb77e
SK
945 if (*doctored && secure)
946 return 0;
6938f347 947#endif
0a852541 948 }
9e4abcb5 949
fd9fa481
SK
950 /* go through the questions. */
951 p = (unsigned char *)(header+1);
9e4abcb5 952
5aabfc78 953 for (i = ntohs(header->qdcount); i != 0; i--)
9e4abcb5 954 {
1fbe4d2f 955 int found = 0, cname_count = CNAME_CHAIN;
fd9fa481 956 struct crec *cpp = NULL;
572b41eb 957 int flags = RCODE(header) == NXDOMAIN ? F_NXDOMAIN : 0;
0435d041 958 int secflag = secure ? F_DNSSECOK : 0;
0a852541 959 unsigned long cttl = ULONG_MAX, attl;
0fc2f313 960
824af85b 961 namep = p;
9009d746 962 if (!extract_name(header, qlen, &p, name, 1, 4))
824af85b 963 return 0; /* bad packet */
fd9fa481 964
9e4abcb5
SK
965 GETSHORT(qtype, p);
966 GETSHORT(qclass, p);
9e4abcb5
SK
967
968 if (qclass != C_IN)
fd9fa481 969 continue;
9e4abcb5 970
fd9fa481
SK
971 /* PTRs: we chase CNAMEs here, since we have no way to
972 represent them in the cache. */
973 if (qtype == T_PTR)
974 {
9e4abcb5 975 int name_encoding = in_arpa_name_2_addr(name, &addr);
fd9fa481
SK
976
977 if (!name_encoding)
978 continue;
979
980 if (!(flags & F_NXDOMAIN))
9e4abcb5 981 {
fd9fa481
SK
982 cname_loop:
983 if (!(p1 = skip_questions(header, qlen)))
824af85b 984 return 0;
fd9fa481 985
5aabfc78 986 for (j = ntohs(header->ancount); j != 0; j--)
fd9fa481 987 {
824af85b
SK
988 unsigned char *tmp = namep;
989 /* the loop body overwrites the original name, so get it back here. */
9009d746
SK
990 if (!extract_name(header, qlen, &tmp, name, 1, 0) ||
991 !(res = extract_name(header, qlen, &p1, name, 0, 10)))
824af85b 992 return 0; /* bad packet */
fd9fa481
SK
993
994 GETSHORT(aqtype, p1);
995 GETSHORT(aqclass, p1);
996 GETLONG(attl, p1);
8ef5ada2
SK
997 if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
998 {
572b41eb 999 (p1) -= 4;
8ef5ada2
SK
1000 PUTLONG(daemon->max_ttl, p1);
1001 }
fd9fa481
SK
1002 GETSHORT(ardlen, p1);
1003 endrr = p1+ardlen;
1004
1005 /* TTL of record is minimum of CNAMES and PTR */
1006 if (attl < cttl)
1007 cttl = attl;
1008
1009 if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
1010 {
9009d746 1011 if (!extract_name(header, qlen, &p1, name, 1, 0))
824af85b 1012 return 0;
fd9fa481
SK
1013
1014 if (aqtype == T_CNAME)
1015 {
d1fbb77e
SK
1016 if (!cname_count-- || secure)
1017 return 0; /* looped CNAMES, or DNSSEC, which we can't cache. */
fd9fa481
SK
1018 goto cname_loop;
1019 }
1020
0435d041 1021 cache_insert(name, &addr, now, cttl, name_encoding | secflag | F_REVERSE);
fd9fa481
SK
1022 found = 1;
1023 }
1024
1025 p1 = endrr;
9009d746 1026 if (!CHECK_LEN(header, p1, qlen, 0))
824af85b 1027 return 0; /* bad packet */
fd9fa481
SK
1028 }
1029 }
1030
28866e95 1031 if (!found && !option_bool(OPT_NO_NEG))
fd9fa481
SK
1032 {
1033 if (!searched_soa)
1034 {
1035 searched_soa = 1;
6938f347 1036 ttl = find_soa(header, qlen, NULL, doctored);
fd9fa481
SK
1037 }
1038 if (ttl)
0435d041 1039 cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags | secflag);
9e4abcb5
SK
1040 }
1041 }
fd9fa481 1042 else
9e4abcb5 1043 {
fd9fa481
SK
1044 /* everything other than PTR */
1045 struct crec *newc;
5aabfc78
SK
1046 int addrlen;
1047
fd9fa481 1048 if (qtype == T_A)
5aabfc78
SK
1049 {
1050 addrlen = INADDRSZ;
1051 flags |= F_IPV4;
1052 }
fd9fa481
SK
1053#ifdef HAVE_IPV6
1054 else if (qtype == T_AAAA)
5aabfc78
SK
1055 {
1056 addrlen = IN6ADDRSZ;
1057 flags |= F_IPV6;
1058 }
fd9fa481
SK
1059#endif
1060 else
1061 continue;
1062
45cca585
SK
1063 cname_loop1:
1064 if (!(p1 = skip_questions(header, qlen)))
1065 return 0;
1066
1067 for (j = ntohs(header->ancount); j != 0; j--)
9e4abcb5 1068 {
45cca585
SK
1069 if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
1070 return 0; /* bad packet */
9e4abcb5 1071
45cca585
SK
1072 GETSHORT(aqtype, p1);
1073 GETSHORT(aqclass, p1);
1074 GETLONG(attl, p1);
1075 if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
9e4abcb5 1076 {
45cca585
SK
1077 (p1) -= 4;
1078 PUTLONG(daemon->max_ttl, p1);
1079 }
1080 GETSHORT(ardlen, p1);
1081 endrr = p1+ardlen;
1082
1083 if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
1084 {
1085 if (aqtype == T_CNAME)
fd9fa481 1086 {
45cca585
SK
1087 if (!cname_count--)
1088 return 0; /* looped CNAMES */
0435d041 1089 newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD | secflag);
45cca585 1090 if (newc)
fd9fa481 1091 {
45cca585 1092 newc->addr.cname.target.cache = NULL;
03431d63
SK
1093 /* anything other than zero, to avoid being mistaken for CNAME to interface-name */
1094 newc->addr.cname.uid = 1;
45cca585 1095 if (cpp)
fd9fa481 1096 {
45cca585
SK
1097 cpp->addr.cname.target.cache = newc;
1098 cpp->addr.cname.uid = newc->uid;
fd9fa481 1099 }
fd9fa481 1100 }
45cca585
SK
1101
1102 cpp = newc;
1103 if (attl < cttl)
1104 cttl = attl;
1105
1106 if (!extract_name(header, qlen, &p1, name, 1, 0))
1107 return 0;
1108 goto cname_loop1;
1109 }
1110 else if (!(flags & F_NXDOMAIN))
1111 {
1112 found = 1;
1113
1114 /* copy address into aligned storage */
1115 if (!CHECK_LEN(header, p1, qlen, addrlen))
1116 return 0; /* bad packet */
1117 memcpy(&addr, p1, addrlen);
1118
1119 /* check for returned address in private space */
b059c96d
SK
1120 if (check_rebind)
1121 {
1122 if ((flags & F_IPV4) &&
1123 private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
1124 return 1;
1125
1126#ifdef HAVE_IPV6
1127 if ((flags & F_IPV6) &&
1128 IN6_IS_ADDR_V4MAPPED(&addr.addr.addr6))
1129 {
1130 struct in_addr v4;
1131 v4.s_addr = ((const uint32_t *) (&addr.addr.addr6))[3];
1132 if (private_net(v4, !option_bool(OPT_LOCAL_REBIND)))
1133 return 1;
1134 }
1135#endif
1136 }
45cca585 1137
13d86c73 1138#ifdef HAVE_IPSET
45cca585
SK
1139 if (ipsets && (flags & (F_IPV4 | F_IPV6)))
1140 {
1141 ipsets_cur = ipsets;
1142 while (*ipsets_cur)
49752b90 1143 {
b7639d58 1144 log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur);
49752b90
WJ
1145 add_to_ipset(*ipsets_cur++, &addr, flags, 0);
1146 }
45cca585 1147 }
13d86c73 1148#endif
45cca585 1149
0435d041 1150 newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD | secflag);
45cca585
SK
1151 if (newc && cpp)
1152 {
1153 cpp->addr.cname.target.cache = newc;
1154 cpp->addr.cname.uid = newc->uid;
fd9fa481 1155 }
45cca585 1156 cpp = NULL;
fd9fa481 1157 }
fd9fa481 1158 }
45cca585
SK
1159
1160 p1 = endrr;
1161 if (!CHECK_LEN(header, p1, qlen, 0))
1162 return 0; /* bad packet */
fd9fa481
SK
1163 }
1164
28866e95 1165 if (!found && !option_bool(OPT_NO_NEG))
fd9fa481
SK
1166 {
1167 if (!searched_soa)
1cff166d 1168 {
fd9fa481 1169 searched_soa = 1;
6938f347 1170 ttl = find_soa(header, qlen, NULL, doctored);
1cff166d 1171 }
fd9fa481 1172 /* If there's no SOA to get the TTL from, but there is a CNAME
824af85b 1173 pointing at this, inherit its TTL */
fd9fa481 1174 if (ttl || cpp)
9e4abcb5 1175 {
0435d041 1176 newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | secflag);
26128d27 1177 if (newc && cpp)
9e4abcb5 1178 {
d56a604a 1179 cpp->addr.cname.target.cache = newc;
fd9fa481
SK
1180 cpp->addr.cname.uid = newc->uid;
1181 }
9e4abcb5 1182 }
9e4abcb5 1183 }
fd9fa481 1184 }
9e4abcb5 1185 }
fd9fa481 1186
1023dcbc 1187 /* Don't put stuff from a truncated packet into the cache.
1023dcbc
SK
1188 Don't cache replies from non-recursive nameservers, since we may get a
1189 reply containing a CNAME but not its target, even though the target
1190 does exist. */
1191 if (!(header->hb3 & HB3_TC) &&
1192 !(header->hb4 & HB4_CD) &&
1193 (header->hb4 & HB4_RA) &&
3a237152 1194 !no_cache_dnssec)
824af85b
SK
1195 cache_end_insert();
1196
1197 return 0;
9e4abcb5
SK
1198}
1199
1200/* If the packet holds exactly one query
28866e95 1201 return F_IPV4 or F_IPV6 and leave the name from the query in name */
572b41eb 1202unsigned int extract_request(struct dns_header *header, size_t qlen, char *name, unsigned short *typep)
9e4abcb5
SK
1203{
1204 unsigned char *p = (unsigned char *)(header+1);
1205 int qtype, qclass;
1206
c1bb8504
SK
1207 if (typep)
1208 *typep = 0;
1209
572b41eb 1210 if (ntohs(header->qdcount) != 1 || OPCODE(header) != QUERY)
9e4abcb5
SK
1211 return 0; /* must be exactly one query. */
1212
9009d746 1213 if (!extract_name(header, qlen, &p, name, 1, 4))
9e4abcb5
SK
1214 return 0; /* bad packet */
1215
1216 GETSHORT(qtype, p);
1217 GETSHORT(qclass, p);
1218
0a852541
SK
1219 if (typep)
1220 *typep = qtype;
1221
9e4abcb5
SK
1222 if (qclass == C_IN)
1223 {
1224 if (qtype == T_A)
1225 return F_IPV4;
1226 if (qtype == T_AAAA)
1227 return F_IPV6;
1228 if (qtype == T_ANY)
1229 return F_IPV4 | F_IPV6;
1230 }
1231
1232 return F_QUERY;
1233}
1234
1235
572b41eb 1236size_t setup_reply(struct dns_header *header, size_t qlen,
28866e95 1237 struct all_addr *addrp, unsigned int flags, unsigned long ttl)
9e4abcb5 1238{
ad4a8ff7
SK
1239 unsigned char *p;
1240
1241 if (!(p = skip_questions(header, qlen)))
1242 return 0;
9e4abcb5 1243
572b41eb
SK
1244 /* clear authoritative and truncated flags, set QR flag */
1245 header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
1246 /* set RA flag */
1247 header->hb4 |= HB4_RA;
1248
9e4abcb5
SK
1249 header->nscount = htons(0);
1250 header->arcount = htons(0);
feba5c1d 1251 header->ancount = htons(0); /* no answers unless changed below */
9e4abcb5 1252 if (flags == F_NEG)
572b41eb 1253 SET_RCODE(header, SERVFAIL); /* couldn't get memory */
824af85b 1254 else if (flags == F_NOERR)
572b41eb 1255 SET_RCODE(header, NOERROR); /* empty domain */
9e4abcb5 1256 else if (flags == F_NXDOMAIN)
572b41eb 1257 SET_RCODE(header, NXDOMAIN);
ad4a8ff7 1258 else if (flags == F_IPV4)
9e4abcb5 1259 { /* we know the address */
572b41eb 1260 SET_RCODE(header, NOERROR);
9e4abcb5 1261 header->ancount = htons(1);
572b41eb
SK
1262 header->hb3 |= HB3_AA;
1263 add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_A, C_IN, "4", addrp);
9e4abcb5
SK
1264 }
1265#ifdef HAVE_IPV6
ad4a8ff7 1266 else if (flags == F_IPV6)
9e4abcb5 1267 {
572b41eb 1268 SET_RCODE(header, NOERROR);
9e4abcb5 1269 header->ancount = htons(1);
572b41eb
SK
1270 header->hb3 |= HB3_AA;
1271 add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
9e4abcb5
SK
1272 }
1273#endif
1274 else /* nowhere to forward to */
572b41eb 1275 SET_RCODE(header, REFUSED);
9e4abcb5
SK
1276
1277 return p - (unsigned char *)header;
1278}
36717eee
SK
1279
1280/* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
5aabfc78 1281int check_for_local_domain(char *name, time_t now)
36717eee
SK
1282{
1283 struct crec *crecp;
0a852541
SK
1284 struct mx_srv_record *mx;
1285 struct txt_record *txt;
f2621c7f
SK
1286 struct interface_name *intr;
1287 struct ptr_record *ptr;
7de060b0
SK
1288 struct naptr *naptr;
1289
288df49c
SK
1290 /* Note: the call to cache_find_by_name is intended to find any record which matches
1291 ie A, AAAA, CNAME, DS. Because RRSIG records are marked by setting both F_DS and F_DNSKEY,
1292 cache_find_by name ordinarily only returns records with an exact match on those bits (ie
1293 for the call below, only DS records). The F_NSIGMATCH bit changes this behaviour */
1294
1295 if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME | F_DS | F_NO_RR | F_NSIGMATCH)) &&
7b174c25 1296 (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
36717eee
SK
1297 return 1;
1298
7de060b0
SK
1299 for (naptr = daemon->naptr; naptr; naptr = naptr->next)
1300 if (hostname_isequal(name, naptr->name))
1301 return 1;
1302
1303 for (mx = daemon->mxnames; mx; mx = mx->next)
0a852541 1304 if (hostname_isequal(name, mx->name))
36717eee 1305 return 1;
f6b7dc47 1306
0a852541
SK
1307 for (txt = daemon->txt; txt; txt = txt->next)
1308 if (hostname_isequal(name, txt->name))
f6b7dc47 1309 return 1;
f2621c7f
SK
1310
1311 for (intr = daemon->int_names; intr; intr = intr->next)
1312 if (hostname_isequal(name, intr->name))
1313 return 1;
1314
1315 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1316 if (hostname_isequal(name, ptr->name))
1317 return 1;
1318
36717eee
SK
1319 return 0;
1320}
9e4abcb5
SK
1321
1322/* Is the packet a reply with the answer address equal to addr?
1323 If so mung is into an NXDOMAIN reply and also put that information
1324 in the cache. */
572b41eb 1325int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
9e4abcb5
SK
1326 struct bogus_addr *baddr, time_t now)
1327{
1328 unsigned char *p;
1329 int i, qtype, qclass, rdlen;
1330 unsigned long ttl;
1331 struct bogus_addr *baddrp;
1332
1333 /* skip over questions */
1334 if (!(p = skip_questions(header, qlen)))
1335 return 0; /* bad packet */
1336
5aabfc78 1337 for (i = ntohs(header->ancount); i != 0; i--)
9e4abcb5 1338 {
9009d746 1339 if (!extract_name(header, qlen, &p, name, 1, 10))
9e4abcb5
SK
1340 return 0; /* bad packet */
1341
1342 GETSHORT(qtype, p);
1343 GETSHORT(qclass, p);
1344 GETLONG(ttl, p);
1345 GETSHORT(rdlen, p);
1346
1347 if (qclass == C_IN && qtype == T_A)
9009d746
SK
1348 {
1349 if (!CHECK_LEN(header, p, qlen, INADDRSZ))
1350 return 0;
1351
1352 for (baddrp = baddr; baddrp; baddrp = baddrp->next)
1353 if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
1354 {
1355 /* Found a bogus address. Insert that info here, since there no SOA record
1356 to get the ttl from in the normal processing */
1357 cache_start_insert();
8db957df 1358 cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
9009d746
SK
1359 cache_end_insert();
1360
1361 return 1;
1362 }
1363 }
9e4abcb5 1364
9009d746
SK
1365 if (!ADD_RDLEN(header, p, qlen, rdlen))
1366 return 0;
9e4abcb5
SK
1367 }
1368
1369 return 0;
1370}
1371
32fc6dbe
GH
1372int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr)
1373{
1374 unsigned char *p;
1375 int i, qtype, qclass, rdlen;
1376 struct bogus_addr *baddrp;
1377
1378 /* skip over questions */
1379 if (!(p = skip_questions(header, qlen)))
1380 return 0; /* bad packet */
1381
1382 for (i = ntohs(header->ancount); i != 0; i--)
1383 {
1384 if (!(p = skip_name(p, header, qlen, 10)))
1385 return 0; /* bad packet */
1386
1387 GETSHORT(qtype, p);
1388 GETSHORT(qclass, p);
1389 p += 4; /* TTL */
1390 GETSHORT(rdlen, p);
1391
1392 if (qclass == C_IN && qtype == T_A)
1393 {
1394 if (!CHECK_LEN(header, p, qlen, INADDRSZ))
1395 return 0;
1396
1397 for (baddrp = baddr; baddrp; baddrp = baddrp->next)
1398 if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
1399 return 1;
1400 }
1401
1402 if (!ADD_RDLEN(header, p, qlen, rdlen))
1403 return 0;
1404 }
1405
1406 return 0;
1407}
1408
b75e9363 1409int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp,
e1ff419c 1410 unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
f6b7dc47
SK
1411{
1412 va_list ap;
1413 unsigned char *sav, *p = *pp;
1414 int j;
1415 unsigned short usval;
1416 long lval;
1417 char *sval;
1418
1419 if (truncp && *truncp)
1420 return 0;
4f7b304f
SK
1421
1422 va_start(ap, format); /* make ap point to 1st unamed argument */
1423
b75e9363 1424 if (nameoffset > 0)
4f7b304f
SK
1425 {
1426 PUTSHORT(nameoffset | 0xc000, p);
1427 }
1428 else
1429 {
e1ff419c
SK
1430 char *name = va_arg(ap, char *);
1431 if (name)
1432 p = do_rfc1035_name(p, name);
b75e9363
SK
1433 if (nameoffset < 0)
1434 {
1435 PUTSHORT(-nameoffset | 0xc000, p);
1436 }
1437 else
1438 *p++ = 0;
4f7b304f 1439 }
f6b7dc47 1440
f6b7dc47
SK
1441 PUTSHORT(type, p);
1442 PUTSHORT(class, p);
1443 PUTLONG(ttl, p); /* TTL */
1444
1445 sav = p; /* Save pointer to RDLength field */
1446 PUTSHORT(0, p); /* Placeholder RDLength */
1447
f6b7dc47
SK
1448 for (; *format; format++)
1449 switch (*format)
1450 {
1451#ifdef HAVE_IPV6
1452 case '6':
1453 sval = va_arg(ap, char *);
1454 memcpy(p, sval, IN6ADDRSZ);
1455 p += IN6ADDRSZ;
1456 break;
1457#endif
1458
1459 case '4':
1460 sval = va_arg(ap, char *);
1461 memcpy(p, sval, INADDRSZ);
1462 p += INADDRSZ;
1463 break;
1464
51ea3ca2
SK
1465 case 'b':
1466 usval = va_arg(ap, int);
1467 *p++ = usval;
1468 break;
1469
f6b7dc47
SK
1470 case 's':
1471 usval = va_arg(ap, int);
1472 PUTSHORT(usval, p);
1473 break;
1474
1475 case 'l':
1476 lval = va_arg(ap, long);
1477 PUTLONG(lval, p);
1478 break;
1479
1480 case 'd':
1481 /* get domain-name answer arg and store it in RDATA field */
0a852541
SK
1482 if (offset)
1483 *offset = p - (unsigned char *)header;
3d8df260 1484 p = do_rfc1035_name(p, va_arg(ap, char *));
f6b7dc47
SK
1485 *p++ = 0;
1486 break;
3d8df260 1487
f6b7dc47 1488 case 't':
0a852541 1489 usval = va_arg(ap, int);
f6b7dc47 1490 sval = va_arg(ap, char *);
9f7f3b12
SK
1491 if (usval != 0)
1492 memcpy(p, sval, usval);
0a852541 1493 p += usval;
f6b7dc47 1494 break;
1a6bca81
SK
1495
1496 case 'z':
1497 sval = va_arg(ap, char *);
1498 usval = sval ? strlen(sval) : 0;
1499 if (usval > 255)
1500 usval = 255;
1501 *p++ = (unsigned char)usval;
1502 memcpy(p, sval, usval);
1503 p += usval;
1504 break;
f6b7dc47
SK
1505 }
1506
1507 va_end(ap); /* clean up variable argument pointer */
1508
1509 j = p - sav - 2;
1510 PUTSHORT(j, sav); /* Now, store real RDLength */
1511
f6b7dc47
SK
1512 /* check for overflow of buffer */
1513 if (limit && ((unsigned char *)limit - p) < 0)
1514 {
1515 if (truncp)
1516 *truncp = 1;
1517 return 0;
1518 }
1519
1520 *pp = p;
1521 return 1;
1522}
1523
9009d746
SK
1524static unsigned long crec_ttl(struct crec *crecp, time_t now)
1525{
1526 /* Return 0 ttl for DHCP entries, which might change
1527 before the lease expires. */
1528
1529 if (crecp->flags & (F_IMMORTAL | F_DHCP))
1530 return daemon->local_ttl;
1531
8ef5ada2
SK
1532 /* Return the Max TTL value if it is lower then the actual TTL */
1533 if (daemon->max_ttl == 0 || ((unsigned)(crecp->ttd - now) < daemon->max_ttl))
1534 return crecp->ttd - now;
1535 else
1536 return daemon->max_ttl;
9009d746
SK
1537}
1538
1539
9e4abcb5 1540/* return zero if we can't answer from cache, or packet size if we can */
572b41eb 1541size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
83349b8a 1542 struct in_addr local_addr, struct in_addr local_netmask,
613ad15d 1543 time_t now, int *ad_reqd, int *do_bit)
9e4abcb5 1544{
3be34541 1545 char *name = daemon->namebuff;
feba5c1d 1546 unsigned char *p, *ansp, *pheader;
3f7483e8 1547 unsigned int qtype, qclass;
9e4abcb5 1548 struct all_addr addr;
b75e9363 1549 int nameoffset;
feba5c1d 1550 unsigned short flag;
0a852541 1551 int q, ans, anscount = 0, addncount = 0;
a25720a3 1552 int dryrun = 0, sec_reqd = 0, have_pseudoheader = 0;
9e4abcb5 1553 struct crec *crecp;
0fc2f313 1554 int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1;
0a852541 1555 struct mx_srv_record *rec;
a25720a3 1556 size_t len;
0a852541 1557
e243c072 1558 /* Don't return AD set if checking disabled. */
a25720a3
SK
1559 if (header->hb4 & HB4_CD)
1560 sec_data = 0;
83349b8a
SK
1561
1562 /* RFC 6840 5.7 */
1563 *ad_reqd = header->hb4 & HB4_AD;
613ad15d
SK
1564 *do_bit = 0;
1565
feba5c1d
SK
1566 /* If there is an RFC2671 pseudoheader then it will be overwritten by
1567 partial replies, so we have to do a dry run to see if we can answer
1568 the query. We check to see if the do bit is set, if so we always
1569 forward rather than answering from the cache, which doesn't include
a25720a3 1570 security information, unless we're in DNSSEC validation mode. */
feba5c1d 1571
a77cec8d 1572 if (find_pseudoheader(header, qlen, NULL, &pheader, NULL))
feba5c1d 1573 {
a77cec8d
SK
1574 unsigned short flags;
1575
a25720a3
SK
1576 have_pseudoheader = 1;
1577
a77cec8d 1578 pheader += 4; /* udp size, ext_rcode */
feba5c1d
SK
1579 GETSHORT(flags, pheader);
1580
613ad15d
SK
1581 if ((sec_reqd = flags & 0x8000))
1582 *do_bit = 1;/* do bit */
feba5c1d 1583
a77cec8d 1584 *ad_reqd = 1;
feba5c1d
SK
1585 dryrun = 1;
1586 }
1587
572b41eb 1588 if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
832af0ba
SK
1589 return 0;
1590
0a852541
SK
1591 for (rec = daemon->mxnames; rec; rec = rec->next)
1592 rec->offset = 0;
1593
feba5c1d 1594 rerun:
9e4abcb5
SK
1595 /* determine end of question section (we put answers there) */
1596 if (!(ansp = skip_questions(header, qlen)))
1597 return 0; /* bad packet */
1598
1599 /* now process each question, answers go in RRs after the question */
1600 p = (unsigned char *)(header+1);
feba5c1d 1601
5aabfc78 1602 for (q = ntohs(header->qdcount); q != 0; q--)
9e4abcb5
SK
1603 {
1604 /* save pointer to name for copying into answers */
1605 nameoffset = p - (unsigned char *)header;
1606
1607 /* now extract name as .-concatenated string into name */
9009d746 1608 if (!extract_name(header, qlen, &p, name, 1, 4))
9e4abcb5 1609 return 0; /* bad packet */
832af0ba 1610
9e4abcb5
SK
1611 GETSHORT(qtype, p);
1612 GETSHORT(qclass, p);
1613
2ed162ac
SK
1614 /* Don't filter RRSIGS from answers to ANY queries, even if do-bit
1615 not set. */
1616 if (qtype == T_ANY)
1617 *do_bit = 1;
1618
9e4abcb5
SK
1619 ans = 0; /* have we answered this question */
1620
0a852541 1621 if (qtype == T_TXT || qtype == T_ANY)
9e4abcb5 1622 {
0a852541
SK
1623 struct txt_record *t;
1624 for(t = daemon->txt; t ; t = t->next)
9e4abcb5 1625 {
0a852541
SK
1626 if (t->class == qclass && hostname_isequal(name, t->name))
1627 {
1628 ans = 1;
e17fb629
SK
1629 if (!dryrun)
1630 {
fec216df
SK
1631 unsigned long ttl = daemon->local_ttl;
1632 int ok = 1;
28866e95 1633 log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
fec216df
SK
1634 /* Dynamically generate stat record */
1635 if (t->stat != 0)
1636 {
1637 ttl = 0;
1638 if (!cache_make_stat(t))
1639 ok = 0;
1640 }
1641
1642 if (ok && add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1643 ttl, NULL,
1644 T_TXT, t->class, "t", t->len, t->txt))
e17fb629
SK
1645 anscount++;
1646
1647 }
0a852541 1648 }
9e4abcb5 1649 }
0a852541 1650 }
f6b7dc47 1651
51ea3ca2 1652#ifdef HAVE_DNSSEC
c8ca33f8 1653 if (option_bool(OPT_DNSSEC_VALID) && (qtype == T_DNSKEY || qtype == T_DS))
51ea3ca2 1654 {
c8ca33f8 1655 int gotone = 0;
bce6e1bc 1656 struct blockdata *keydata;
51ea3ca2 1657
bce6e1bc 1658 /* Do we have RRSIG? Can't do DS or DNSKEY otherwise. */
c8ca33f8 1659 if (sec_reqd)
bce6e1bc 1660 {
c8ca33f8
SK
1661 crecp = NULL;
1662 while ((crecp = cache_find_by_name(crecp, name, now, F_DNSKEY | F_DS)))
1663 if (crecp->uid == qclass && crecp->addr.sig.type_covered == qtype)
1664 break;
5f938534 1665 }
c8ca33f8
SK
1666
1667 if (!sec_reqd || crecp)
5f938534 1668 {
c8ca33f8
SK
1669 if (qtype == T_DS)
1670 {
1671 crecp = NULL;
1672 while ((crecp = cache_find_by_name(crecp, name, now, F_DS)))
1673 if (crecp->uid == qclass)
1674 {
b8eac191
SK
1675 gotone = 1;
1676 if (!dryrun)
1677 {
1678 if (crecp->flags & F_NEG)
1679 {
1680 if (crecp->flags & F_NXDOMAIN)
1681 nxdomain = 1;
ae4624bf 1682 log_query(F_UPSTREAM, name, NULL, "no DS");
b8eac191
SK
1683 }
1684 else if ((keydata = blockdata_retrieve(crecp->addr.ds.keydata, crecp->addr.ds.keylen, NULL)))
1685 {
1686 struct all_addr a;
1687 a.addr.keytag = crecp->addr.ds.keytag;
1688 log_query(F_KEYTAG | (crecp->flags & F_CONFIG), name, &a, "DS keytag %u");
1689 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1690 crec_ttl(crecp, now), &nameoffset,
1691 T_DS, qclass, "sbbt",
1692 crecp->addr.ds.keytag, crecp->addr.ds.algo,
1693 crecp->addr.ds.digest, crecp->addr.ds.keylen, keydata))
1694 anscount++;
1695
1696 }
1697 }
c8ca33f8
SK
1698 }
1699 }
1700 else /* DNSKEY */
1701 {
1702 crecp = NULL;
1703 while ((crecp = cache_find_by_name(crecp, name, now, F_DNSKEY)))
1704 if (crecp->uid == qclass)
5f938534 1705 {
ee415867
SK
1706 gotone = 1;
1707 if (!dryrun && (keydata = blockdata_retrieve(crecp->addr.key.keydata, crecp->addr.key.keylen, NULL)))
1708 {
1709 struct all_addr a;
1710 a.addr.keytag = crecp->addr.key.keytag;
1711 log_query(F_KEYTAG | (crecp->flags & F_CONFIG), name, &a, "DNSKEY keytag %u");
1712 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1713 crec_ttl(crecp, now), &nameoffset,
1714 T_DNSKEY, qclass, "sbbt",
1715 crecp->addr.key.flags, 3, crecp->addr.key.algo, crecp->addr.key.keylen, keydata))
1716 anscount++;
5f938534
SK
1717 }
1718 }
c8ca33f8 1719 }
5f938534 1720 }
c8ca33f8 1721
5f938534
SK
1722 /* Now do RRSIGs */
1723 if (gotone)
1724 {
c8ca33f8
SK
1725 ans = 1;
1726 auth = 0;
1727 if (!dryrun && sec_reqd)
1728 {
1729 crecp = NULL;
1730 while ((crecp = cache_find_by_name(crecp, name, now, F_DNSKEY | F_DS)))
1731 if (crecp->uid == qclass && crecp->addr.sig.type_covered == qtype &&
1732 (keydata = blockdata_retrieve(crecp->addr.sig.keydata, crecp->addr.sig.keylen, NULL)))
1733 {
5f938534
SK
1734 add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1735 crec_ttl(crecp, now), &nameoffset,
c8ca33f8
SK
1736 T_RRSIG, qclass, "t", crecp->addr.sig.keylen, keydata);
1737 anscount++;
1738 }
1739 }
bce6e1bc 1740 }
51ea3ca2
SK
1741 }
1742#endif
1743
0a852541 1744 if (qclass == C_IN)
9e4abcb5 1745 {
9f7f3b12
SK
1746 struct txt_record *t;
1747
1748 for (t = daemon->rr; t; t = t->next)
1749 if ((t->class == qtype || qtype == T_ANY) && hostname_isequal(name, t->name))
1750 {
1751 ans = 1;
1752 if (!dryrun)
1753 {
1754 log_query(F_CONFIG | F_RRNAME, name, NULL, "<RR>");
1755 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1756 daemon->local_ttl, NULL,
1757 t->class, C_IN, "t", t->len, t->txt))
1758 anscount ++;
1759 }
1760 }
1761
f6b7dc47 1762 if (qtype == T_PTR || qtype == T_ANY)
c1bb8504 1763 {
832af0ba
SK
1764 /* see if it's w.z.y.z.in-addr.arpa format */
1765 int is_arpa = in_arpa_name_2_addr(name, &addr);
1766 struct ptr_record *ptr;
f2621c7f 1767 struct interface_name* intr = NULL;
832af0ba
SK
1768
1769 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1770 if (hostname_isequal(name, ptr->name))
1771 break;
1772
f2621c7f
SK
1773 if (is_arpa == F_IPV4)
1774 for (intr = daemon->int_names; intr; intr = intr->next)
5aabfc78 1775 {
115ac3e4
SK
1776 struct addrlist *addrlist;
1777
376d48c7
SK
1778 for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1779 if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
115ac3e4
SK
1780 break;
1781
1782 if (addrlist)
1783 break;
1784 else
1785 while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1786 intr = intr->next;
1787 }
1788#ifdef HAVE_IPV6
1789 else if (is_arpa == F_IPV6)
1790 for (intr = daemon->int_names; intr; intr = intr->next)
1791 {
1792 struct addrlist *addrlist;
1793
376d48c7
SK
1794 for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
1795 if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
115ac3e4
SK
1796 break;
1797
1798 if (addrlist)
5aabfc78
SK
1799 break;
1800 else
1801 while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1802 intr = intr->next;
1803 }
115ac3e4 1804#endif
f2621c7f
SK
1805
1806 if (intr)
1807 {
1808 ans = 1;
1809 if (!dryrun)
f6b7dc47 1810 {
115ac3e4 1811 log_query(is_arpa | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
f2621c7f
SK
1812 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1813 daemon->local_ttl, NULL,
1814 T_PTR, C_IN, "d", intr->name))
1815 anscount++;
9e4abcb5 1816 }
9e4abcb5 1817 }
832af0ba
SK
1818 else if (ptr)
1819 {
1820 ans = 1;
1821 if (!dryrun)
1822 {
28866e95 1823 log_query(F_CONFIG | F_RRNAME, name, NULL, "<PTR>");
832af0ba 1824 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
f2621c7f
SK
1825 if (hostname_isequal(name, ptr->name) &&
1826 add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1827 daemon->local_ttl, NULL,
1828 T_PTR, C_IN, "d", ptr->ptr))
1829 anscount++;
1830
1831 }
1832 }
1833 else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
2d33bda2 1834 {
0744ca66 1835 if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && sec_reqd)
2d33bda2 1836 {
0744ca66
SK
1837 if (!option_bool(OPT_DNSSEC_VALID) || ((crecp->flags & F_NEG) && (crecp->flags & F_DNSSECOK)))
1838 crecp = NULL;
1839#ifdef HAVE_DNSSEC
1840 else if (crecp->flags & F_DNSSECOK)
2d33bda2 1841 {
0744ca66 1842 int gotsig = 0;
12fae49f
SK
1843 struct crec *rr_crec = NULL;
1844
1845 while ((rr_crec = cache_find_by_name(rr_crec, name, now, F_DS | F_DNSKEY)))
2d33bda2 1846 {
12fae49f 1847 if (rr_crec->addr.sig.type_covered == T_PTR && rr_crec->uid == C_IN)
0744ca66 1848 {
12fae49f 1849 char *sigdata = blockdata_retrieve(rr_crec->addr.sig.keydata, rr_crec->addr.sig.keylen, NULL);
0744ca66
SK
1850 gotsig = 1;
1851
1852 if (!dryrun &&
1853 add_resource_record(header, limit, &trunc, nameoffset, &ansp,
12fae49f 1854 rr_crec->ttd - now, &nameoffset,
0744ca66
SK
1855 T_RRSIG, C_IN, "t", crecp->addr.sig.keylen, sigdata))
1856 anscount++;
1857 }
1858 }
12fae49f
SK
1859
1860 if (!gotsig)
1861 crecp = NULL;
0744ca66 1862 }
2d33bda2 1863#endif
5b3bf921 1864 }
2d33bda2
SK
1865
1866 if (crecp)
1867 {
1868 do
1869 {
1870 /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
1871 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1872 continue;
1873
1874 if (!(crecp->flags & F_DNSSECOK))
1875 sec_data = 0;
1876
1877 if (crecp->flags & F_NEG)
1878 {
1879 ans = 1;
1880 auth = 0;
1881 if (crecp->flags & F_NXDOMAIN)
1882 nxdomain = 1;
1883 if (!dryrun)
1884 log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
1885 }
1886 else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd || option_bool(OPT_DNSSEC_VALID))
1887 {
1888 ans = 1;
1889 if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1890 auth = 0;
1891 if (!dryrun)
1892 {
1893 log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
1894 record_source(crecp->uid));
1895
1896 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1897 crec_ttl(crecp, now), NULL,
1898 T_PTR, C_IN, "d", cache_get_name(crecp)))
1899 anscount++;
1900 }
1901 }
1902 } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
1903 }
1904 }
2bb73af7
SK
1905 else if (is_rev_synth(is_arpa, &addr, name))
1906 {
1907 ans = 1;
1908 if (!dryrun)
1909 {
1910 log_query(F_CONFIG | F_REVERSE | is_arpa, name, &addr, NULL);
1911
1912 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1913 daemon->local_ttl, NULL,
1914 T_PTR, C_IN, "d", name))
1915 anscount++;
1916 }
1917 }
f2621c7f 1918 else if (is_arpa == F_IPV4 &&
28866e95 1919 option_bool(OPT_BOGUSPRIV) &&
8ef5ada2 1920 private_net(addr.addr.addr4, 1))
f2621c7f
SK
1921 {
1922 /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
1923 ans = 1;
1924 nxdomain = 1;
1925 if (!dryrun)
1926 log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN,
1a6bca81 1927 name, &addr, NULL);
832af0ba 1928 }
f6b7dc47 1929 }
f2621c7f 1930
f6b7dc47
SK
1931 for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
1932 {
1933 unsigned short type = T_A;
115ac3e4
SK
1934 struct interface_name *intr;
1935
f6b7dc47 1936 if (flag == F_IPV6)
feba5c1d 1937#ifdef HAVE_IPV6
3d8df260 1938 type = T_AAAA;
feba5c1d 1939#else
3d8df260 1940 break;
feba5c1d 1941#endif
f6b7dc47
SK
1942
1943 if (qtype != type && qtype != T_ANY)
1944 continue;
1945
316e2730
SK
1946 /* Check for "A for A" queries; be rather conservative
1947 about what looks like dotted-quad. */
1948 if (qtype == T_A)
3d8df260 1949 {
316e2730
SK
1950 char *cp;
1951 unsigned int i, a;
1952 int x;
1953
1954 for (cp = name, i = 0, a = 0; *cp; i++)
3d8df260 1955 {
572b41eb 1956 if (!isdigit((unsigned char)*cp) || (x = strtol(cp, &cp, 10)) > 255)
316e2730
SK
1957 {
1958 i = 5;
1959 break;
1960 }
1961
1962 a = (a << 8) + x;
1963
1964 if (*cp == '.')
1965 cp++;
1966 }
1967
1968 if (i == 4)
1969 {
1970 ans = 1;
1971 if (!dryrun)
1972 {
1973 addr.addr.addr4.s_addr = htonl(a);
1974 log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
1975 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1976 daemon->local_ttl, NULL, type, C_IN, "4", &addr))
1977 anscount++;
1978 }
1979 continue;
3d8df260 1980 }
3d8df260
SK
1981 }
1982
f2621c7f 1983 /* interface name stuff */
d56a604a 1984 intname_restart:
115ac3e4
SK
1985 for (intr = daemon->int_names; intr; intr = intr->next)
1986 if (hostname_isequal(name, intr->name))
1987 break;
1988
1989 if (intr)
f2621c7f 1990 {
115ac3e4 1991 struct addrlist *addrlist;
fb63dd13 1992 int gotit = 0;
f2621c7f 1993
115ac3e4 1994 enumerate_interfaces(0);
f2621c7f 1995
fb63dd13
SK
1996 for (intr = daemon->int_names; intr; intr = intr->next)
1997 if (hostname_isequal(name, intr->name))
1998 {
47669367 1999 for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
376d48c7 2000#ifdef HAVE_IPV6
47669367 2001 if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
376d48c7 2002#endif
47669367
SK
2003 {
2004#ifdef HAVE_IPV6
2005 if (addrlist->flags & ADDRLIST_REVONLY)
2006 continue;
2007#endif
2008 ans = 1;
2009 if (!dryrun)
376d48c7
SK
2010 {
2011 gotit = 1;
2012 log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
2013 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
2014 daemon->local_ttl, NULL, type, C_IN,
2015 type == T_A ? "4" : "6", &addrlist->addr))
2016 anscount++;
2017 }
47669367 2018 }
fb63dd13
SK
2019 }
2020
2021 if (!dryrun && !gotit)
2022 log_query(F_FORWARD | F_CONFIG | flag | F_NEG, name, NULL, NULL);
2023
115ac3e4 2024 continue;
f2621c7f
SK
2025 }
2026
f6b7dc47 2027 cname_restart:
12fae49f 2028 if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME | (dryrun ? F_NO_RR : 0))))
f6b7dc47
SK
2029 {
2030 int localise = 0;
feba5c1d 2031
f6b7dc47
SK
2032 /* See if a putative address is on the network from which we recieved
2033 the query, is so we'll filter other answers. */
28866e95 2034 if (local_addr.s_addr != 0 && option_bool(OPT_LOCALISE) && flag == F_IPV4)
f6b7dc47
SK
2035 {
2036 struct crec *save = crecp;
2037 do {
2038 if ((crecp->flags & F_HOSTS) &&
2039 is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
2040 {
2041 localise = 1;
2042 break;
2043 }
2044 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
2045 crecp = save;
2046 }
824202ef 2047
0744ca66
SK
2048 /* If the client asked for DNSSEC and we can't provide RRSIGs, either
2049 because we've not doing DNSSEC or the cached answer is signed by negative,
2050 don't answer from the cache, forward instead. */
2051 if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && sec_reqd)
824202ef 2052 {
0744ca66
SK
2053 if (!option_bool(OPT_DNSSEC_VALID) || ((crecp->flags & F_NEG) && (crecp->flags & F_DNSSECOK)))
2054 crecp = NULL;
2055#ifdef HAVE_DNSSEC
2056 else if (crecp->flags & F_DNSSECOK)
9e4abcb5 2057 {
0744ca66 2058 /* We're returning validated data, need to return the RRSIG too. */
12fae49f 2059 struct crec *rr_crec = NULL;
0744ca66
SK
2060 int sigtype = type;
2061 /* The signature may have expired even though the data is still in cache,
2062 forward instead of answering from cache if so. */
2063 int gotsig = 0;
2064
2065 if (crecp->flags & F_CNAME)
2066 sigtype = T_CNAME;
2067
12fae49f 2068 while ((rr_crec = cache_find_by_name(rr_crec, name, now, F_DS | F_DNSKEY)))
feba5c1d 2069 {
12fae49f 2070 if (rr_crec->addr.sig.type_covered == sigtype && rr_crec->uid == C_IN)
0744ca66 2071 {
12fae49f 2072 char *sigdata = blockdata_retrieve(rr_crec->addr.sig.keydata, rr_crec->addr.sig.keylen, NULL);
0744ca66
SK
2073 gotsig = 1;
2074
2075 if (!dryrun &&
2076 add_resource_record(header, limit, &trunc, nameoffset, &ansp,
12fae49f
SK
2077 rr_crec->ttd - now, &nameoffset,
2078 T_RRSIG, C_IN, "t", rr_crec->addr.sig.keylen, sigdata))
0744ca66
SK
2079 anscount++;
2080 }
feba5c1d 2081 }
12fae49f
SK
2082
2083 if (!gotsig)
2084 crecp = NULL;
9e4abcb5 2085 }
824202ef 2086#endif
5b3bf921
SK
2087 }
2088
824202ef
SK
2089 if (crecp)
2090 do
2091 {
2092 /* don't answer wildcard queries with data not from /etc/hosts
2093 or DHCP leases */
2094 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
2095 break;
2096
2097 if (!(crecp->flags & F_DNSSECOK))
2098 sec_data = 0;
2099
2100 if (crecp->flags & F_CNAME)
2101 {
2102 char *cname_target = cache_get_cname_target(crecp);
2103
2104 if (!dryrun)
2105 {
2106 log_query(crecp->flags, name, NULL, record_source(crecp->uid));
2107 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
2108 crec_ttl(crecp, now), &nameoffset,
2109 T_CNAME, C_IN, "d", cname_target))
2110 anscount++;
2111 }
2112
2113 strcpy(name, cname_target);
2114 /* check if target interface_name */
3e21a1a6 2115 if (crecp->addr.cname.uid == SRC_INTERFACE)
824202ef
SK
2116 goto intname_restart;
2117 else
2118 goto cname_restart;
2119 }
2120
2121 if (crecp->flags & F_NEG)
2122 {
2123 /* We don't cache NSEC records, so if a DNSSEC-validated negative answer
2124 is cached and the client wants DNSSEC, forward rather than answering from the cache */
2125 if (!sec_reqd || !(crecp->flags & F_DNSSECOK))
2126 {
2127 ans = 1;
2128 auth = 0;
2129 if (crecp->flags & F_NXDOMAIN)
2130 nxdomain = 1;
2131 if (!dryrun)
2132 log_query(crecp->flags, name, NULL, NULL);
2133 }
2134 }
2135 else
2136 {
2137 /* If we are returning local answers depending on network,
2138 filter here. */
2139 if (localise &&
2140 (crecp->flags & F_HOSTS) &&
2141 !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
2142 continue;
2143
2144 if (!(crecp->flags & (F_HOSTS | F_DHCP)))
2145 auth = 0;
2146
2147 ans = 1;
2148 if (!dryrun)
2149 {
2150 log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
2151 record_source(crecp->uid));
2152
2153 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
2154 crec_ttl(crecp, now), NULL, type, C_IN,
2155 type == T_A ? "4" : "6", &crecp->addr))
2156 anscount++;
2157 }
2158 }
2159 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
9e4abcb5 2160 }
2bb73af7
SK
2161 else if (is_name_synthetic(flag, name, &addr))
2162 {
2163 ans = 1;
2164 if (!dryrun)
2165 {
2166 log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
2167 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
2168 daemon->local_ttl, NULL, type, C_IN, type == T_A ? "4" : "6", &addr))
2169 anscount++;
2170 }
2171 }
f6b7dc47 2172 }
d1c759c5
SK
2173
2174 if (qtype == T_CNAME || qtype == T_ANY)
2175 {
2176 if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME)) &&
12fae49f 2177 (qtype == T_CNAME || (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG | (dryrun ? F_NO_RR : 0)))))
d1c759c5 2178 {
0fc2f313
SK
2179 if (!(crecp->flags & F_DNSSECOK))
2180 sec_data = 0;
2181
d1c759c5
SK
2182 ans = 1;
2183 if (!dryrun)
2184 {
2185 log_query(crecp->flags, name, NULL, record_source(crecp->uid));
2186 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
2187 crec_ttl(crecp, now), &nameoffset,
d56a604a 2188 T_CNAME, C_IN, "d", cache_get_cname_target(crecp)))
d1c759c5
SK
2189 anscount++;
2190 }
2191 }
2192 }
51ea3ca2 2193
f6b7dc47
SK
2194 if (qtype == T_MX || qtype == T_ANY)
2195 {
2196 int found = 0;
0a852541
SK
2197 for (rec = daemon->mxnames; rec; rec = rec->next)
2198 if (!rec->issrv && hostname_isequal(name, rec->name))
f6b7dc47
SK
2199 {
2200 ans = found = 1;
2201 if (!dryrun)
feba5c1d 2202 {
e1ff419c 2203 int offset;
28866e95 2204 log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
0a852541
SK
2205 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
2206 &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
2207 {
2208 anscount++;
2209 if (rec->target)
2210 rec->offset = offset;
2211 }
feba5c1d 2212 }
f6b7dc47
SK
2213 }
2214
28866e95 2215 if (!found && (option_bool(OPT_SELFMX) || option_bool(OPT_LOCALMX)) &&
12fae49f 2216 cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP | F_NO_RR))
f6b7dc47
SK
2217 {
2218 ans = 1;
2219 if (!dryrun)
2220 {
28866e95 2221 log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
f6b7dc47
SK
2222 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
2223 T_MX, C_IN, "sd", 1,
28866e95 2224 option_bool(OPT_SELFMX) ? name : daemon->mxtarget))
f6b7dc47 2225 anscount++;
9e4abcb5
SK
2226 }
2227 }
f6b7dc47
SK
2228 }
2229
2230 if (qtype == T_SRV || qtype == T_ANY)
2231 {
2232 int found = 0;
28866e95
SK
2233 struct mx_srv_record *move = NULL, **up = &daemon->mxnames;
2234
0a852541
SK
2235 for (rec = daemon->mxnames; rec; rec = rec->next)
2236 if (rec->issrv && hostname_isequal(name, rec->name))
f6b7dc47
SK
2237 {
2238 found = ans = 1;
2239 if (!dryrun)
2240 {
e1ff419c 2241 int offset;
28866e95 2242 log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>");
f6b7dc47 2243 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
0a852541
SK
2244 &offset, T_SRV, C_IN, "sssd",
2245 rec->priority, rec->weight, rec->srvport, rec->target))
2246 {
2247 anscount++;
2248 if (rec->target)
2249 rec->offset = offset;
2250 }
f6b7dc47 2251 }
28866e95
SK
2252
2253 /* unlink first SRV record found */
2254 if (!move)
2255 {
2256 move = rec;
2257 *up = rec->next;
2258 }
2259 else
2260 up = &rec->next;
f6b7dc47 2261 }
28866e95
SK
2262 else
2263 up = &rec->next;
2264
2265 /* put first SRV record back at the end. */
2266 if (move)
2267 {
2268 *up = move;
2269 move->next = NULL;
2270 }
feba5c1d 2271
28866e95 2272 if (!found && option_bool(OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
f6b7dc47
SK
2273 {
2274 ans = 1;
2275 if (!dryrun)
1a6bca81 2276 log_query(F_CONFIG | F_NEG, name, NULL, NULL);
f6b7dc47
SK
2277 }
2278 }
1a6bca81
SK
2279
2280 if (qtype == T_NAPTR || qtype == T_ANY)
2281 {
2282 struct naptr *na;
2283 for (na = daemon->naptr; na; na = na->next)
2284 if (hostname_isequal(name, na->name))
2285 {
2286 ans = 1;
2287 if (!dryrun)
2288 {
28866e95 2289 log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>");
1a6bca81
SK
2290 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
2291 NULL, T_NAPTR, C_IN, "sszzzd",
2292 na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
2293 anscount++;
2294 }
2295 }
2296 }
f6b7dc47
SK
2297
2298 if (qtype == T_MAILB)
2299 ans = 1, nxdomain = 1;
2300
28866e95 2301 if (qtype == T_SOA && option_bool(OPT_FILTER))
f6b7dc47
SK
2302 {
2303 ans = 1;
2304 if (!dryrun)
1a6bca81 2305 log_query(F_CONFIG | F_NEG, name, &addr, NULL);
feba5c1d 2306 }
9e4abcb5 2307 }
f6b7dc47
SK
2308
2309 if (!ans)
9e4abcb5 2310 return 0; /* failed to answer a question */
feba5c1d 2311 }
f6b7dc47 2312
feba5c1d
SK
2313 if (dryrun)
2314 {
2315 dryrun = 0;
2316 goto rerun;
9e4abcb5
SK
2317 }
2318
0a852541
SK
2319 /* create an additional data section, for stuff in SRV and MX record replies. */
2320 for (rec = daemon->mxnames; rec; rec = rec->next)
2321 if (rec->offset != 0)
2322 {
2323 /* squash dupes */
2324 struct mx_srv_record *tmp;
2325 for (tmp = rec->next; tmp; tmp = tmp->next)
2326 if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
2327 tmp->offset = 0;
2328
2329 crecp = NULL;
2330 while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
2331 {
0a852541
SK
2332#ifdef HAVE_IPV6
2333 int type = crecp->flags & F_IPV4 ? T_A : T_AAAA;
2334#else
2335 int type = T_A;
2336#endif
2337 if (crecp->flags & F_NEG)
2338 continue;
2339
9009d746
SK
2340 if (add_resource_record(header, limit, NULL, rec->offset, &ansp,
2341 crec_ttl(crecp, now), NULL, type, C_IN,
0a852541
SK
2342 crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
2343 addncount++;
2344 }
2345 }
2346
9e4abcb5 2347 /* done all questions, set up header and return length of result */
572b41eb
SK
2348 /* clear authoritative and truncated flags, set QR flag */
2349 header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
2350 /* set RA flag */
2351 header->hb4 |= HB4_RA;
2352
2353 /* authoritive - only hosts and DHCP derived names. */
2354 if (auth)
2355 header->hb3 |= HB3_AA;
2356
2357 /* truncation */
2358 if (trunc)
2359 header->hb3 |= HB3_TC;
0fc2f313 2360
45cca585 2361 if (nxdomain)
572b41eb 2362 SET_RCODE(header, NXDOMAIN);
9e4abcb5 2363 else
572b41eb 2364 SET_RCODE(header, NOERROR); /* no error */
9e4abcb5
SK
2365 header->ancount = htons(anscount);
2366 header->nscount = htons(0);
0a852541 2367 header->arcount = htons(addncount);
e243c072 2368
a25720a3
SK
2369 len = ansp - (unsigned char *)header;
2370
2371 if (have_pseudoheader)
e243c072
SK
2372 len = add_pseudoheader(header, len, (unsigned char *)limit, 0, NULL, 0, sec_reqd);
2373
83349b8a 2374 if (*ad_reqd && sec_data)
e243c072 2375 header->hb4 |= HB4_AD;
83349b8a
SK
2376 else
2377 header->hb4 &= ~HB4_AD;
a25720a3 2378
7c28612a 2379 return len;
9e4abcb5
SK
2380}
2381