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