1 /* dnsmasq is Copyright (c) 2000-2010 Simon Kelley
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
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.
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/>.
19 static int add_resource_record(HEADER
*header
, char *limit
, int *truncp
,
20 unsigned int nameoffset
, unsigned char **pp
,
21 unsigned long ttl
, unsigned int *offset
, unsigned short type
,
22 unsigned short class, char *format
, ...);
24 #define CHECK_LEN(header, pp, plen, len) \
25 ((size_t)((pp) - (unsigned char *)(header) + (len)) <= (plen))
27 #define ADD_RDLEN(header, pp, plen, len) \
28 (!CHECK_LEN(header, pp, plen, len) ? 0 : (long)((pp) += (len)), 1)
30 static int extract_name(HEADER
*header
, size_t plen
, unsigned char **pp
,
31 char *name
, int isExtract
, int extrabytes
)
33 unsigned char *cp
= (unsigned char *)name
, *p
= *pp
, *p1
= NULL
;
34 unsigned int j
, l
, hops
= 0;
42 unsigned int label_type
;
44 if (!CHECK_LEN(header
, p
, plen
, 1))
50 /* check that there are the correct no of bytes after the name */
51 if (!CHECK_LEN(header
, p
, plen
, extrabytes
))
56 if (cp
!= (unsigned char *)name
)
58 *cp
= 0; /* terminate: lose final period */
63 if (p1
) /* we jumped via compression */
71 label_type
= l
& 0xc0;
73 if (label_type
== 0xc0) /* pointer */
75 if (!CHECK_LEN(header
, p
, plen
, 1))
82 if (!p1
) /* first jump, save location to go back to */
85 hops
++; /* break malicious infinite loops */
89 p
= l
+ (unsigned char *)header
;
91 else if (label_type
== 0x80)
92 return 0; /* reserved */
93 else if (label_type
== 0x40)
95 unsigned int count
, digs
;
98 return 0; /* we only understand bitstrings */
101 return 0; /* Cannot compare bitsrings */
106 digs
= ((count
-1)>>2)+1;
108 /* output is \[x<hex>/siz]. which is digs+9 chars */
109 if (cp
- (unsigned char *)name
+ digs
+ 9 >= MAXDNAME
)
111 if (!CHECK_LEN(header
, p
, plen
, (count
-1)>>3))
117 for (j
=0; j
<digs
; j
++)
125 *cp
++ = dig
< 10 ? dig
+ '0' : dig
+ 'A' - 10;
127 cp
+= sprintf((char *)cp
, "/%d]", count
);
128 /* do this here to overwrite the zero char from sprintf */
132 { /* label_type = 0 -> label. */
133 if (cp
- (unsigned char *)name
+ l
+ 1 >= MAXDNAME
)
135 if (!CHECK_LEN(header
, p
, plen
, l
))
138 for(j
=0; j
<l
; j
++, p
++)
141 unsigned char c
= *p
;
142 if (isascii(c
) && !iscntrl(c
) && c
!= '.')
149 unsigned char c1
= *cp
, c2
= *p
;
156 if (c1
>= 'A' && c1
<= 'Z')
158 if (c2
>= 'A' && c2
<= 'Z')
168 else if (*cp
!= 0 && *cp
++ != '.')
174 /* Max size of input string (for IPv6) is 75 chars.) */
175 #define MAXARPANAME 75
176 static int in_arpa_name_2_addr(char *namein
, struct all_addr
*addrp
)
179 char name
[MAXARPANAME
+1], *cp1
;
180 unsigned char *addr
= (unsigned char *)addrp
;
181 char *lastchunk
= NULL
, *penchunk
= NULL
;
183 if (strlen(namein
) > MAXARPANAME
)
186 memset(addrp
, 0, sizeof(struct all_addr
));
188 /* turn name into a series of asciiz strings */
189 /* j counts no of labels */
190 for(j
= 1,cp1
= name
; *namein
; cp1
++, namein
++)
193 penchunk
= lastchunk
;
206 if (hostname_isequal(lastchunk
, "arpa") && hostname_isequal(penchunk
, "in-addr"))
209 /* address arives as a name of the form
210 www.xxx.yyy.zzz.in-addr.arpa
211 some of the low order address octets might be missing
212 and should be set to zero. */
213 for (cp1
= name
; cp1
!= penchunk
; cp1
+= strlen(cp1
)+1)
215 /* check for digits only (weeds out things like
216 50.0/24.67.28.64.in-addr.arpa which are used
217 as CNAME targets according to RFC 2317 */
219 for (cp
= cp1
; *cp
; cp
++)
220 if (!isdigit((int)*cp
))
232 else if (hostname_isequal(penchunk
, "ip6") &&
233 (hostname_isequal(lastchunk
, "int") || hostname_isequal(lastchunk
, "arpa")))
236 Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
237 or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]
239 Note that most of these the various reprentations are obsolete and
240 left-over from the many DNS-for-IPv6 wars. We support all the formats
241 that we can since there is no reason not to.
244 if (*name
== '\\' && *(name
+1) == '[' &&
245 (*(name
+2) == 'x' || *(name
+2) == 'X'))
247 for (j
= 0, cp1
= name
+3; *cp1
&& isxdigit((int) *cp1
) && j
< 32; cp1
++, j
++)
253 addr
[j
/2] |= strtol(xdig
, NULL
, 16);
255 addr
[j
/2] = strtol(xdig
, NULL
, 16) << 4;
258 if (*cp1
== '/' && j
== 32)
263 for (cp1
= name
; cp1
!= penchunk
; cp1
+= strlen(cp1
)+1)
265 if (*(cp1
+1) || !isxdigit((int)*cp1
))
268 for (j
= sizeof(struct all_addr
)-1; j
>0; j
--)
269 addr
[j
] = (addr
[j
] >> 4) | (addr
[j
-1] << 4);
270 addr
[0] = (addr
[0] >> 4) | (strtol(cp1
, NULL
, 16) << 4);
281 static unsigned char *skip_name(unsigned char *ansp
, HEADER
*header
, size_t plen
, int extrabytes
)
285 unsigned int label_type
;
287 if (!CHECK_LEN(header
, ansp
, plen
, 1))
290 label_type
= (*ansp
) & 0xc0;
292 if (label_type
== 0xc0)
294 /* pointer for compression. */
298 else if (label_type
== 0x80)
299 return NULL
; /* reserved */
300 else if (label_type
== 0x40)
302 /* Extended label type */
305 if (!CHECK_LEN(header
, ansp
, plen
, 2))
308 if (((*ansp
++) & 0x3f) != 1)
309 return NULL
; /* we only understand bitstrings */
311 count
= *(ansp
++); /* Bits in bitstring */
313 if (count
== 0) /* count == 0 means 256 bits */
316 ansp
+= ((count
-1)>>3)+1;
319 { /* label type == 0 Bottom six bits is length */
320 unsigned int len
= (*ansp
++) & 0x3f;
322 if (!ADD_RDLEN(header
, ansp
, plen
, len
))
326 break; /* zero length label marks the end. */
330 if (!CHECK_LEN(header
, ansp
, plen
, extrabytes
))
336 static unsigned char *skip_questions(HEADER
*header
, size_t plen
)
339 unsigned char *ansp
= (unsigned char *)(header
+1);
341 for (q
= ntohs(header
->qdcount
); q
!= 0; q
--)
343 if (!(ansp
= skip_name(ansp
, header
, plen
, 4)))
345 ansp
+= 4; /* class and type */
351 static unsigned char *skip_section(unsigned char *ansp
, int count
, HEADER
*header
, size_t plen
)
355 for (i
= 0; i
< count
; i
++)
357 if (!(ansp
= skip_name(ansp
, header
, plen
, 10)))
359 ansp
+= 8; /* type, class, TTL */
360 GETSHORT(rdlen
, ansp
);
361 if (!ADD_RDLEN(header
, ansp
, plen
, rdlen
))
368 /* CRC the question section. This is used to safely detect query
369 retransmision and to detect answers to questions we didn't ask, which
370 might be poisoning attacks. Note that we decode the name rather
371 than CRC the raw bytes, since replies might be compressed differently.
372 We ignore case in the names for the same reason. Return all-ones
373 if there is not question section. */
374 unsigned int questions_crc(HEADER
*header
, size_t plen
, char *name
)
377 unsigned int crc
= 0xffffffff;
378 unsigned char *p1
, *p
= (unsigned char *)(header
+1);
380 for (q
= ntohs(header
->qdcount
); q
!= 0; q
--)
382 if (!extract_name(header
, plen
, &p
, name
, 1, 4))
383 return crc
; /* bad packet */
385 for (p1
= (unsigned char *)name
; *p1
; p1
++)
390 if (c
>= 'A' && c
<= 'Z')
395 crc
= crc
& 0x80000000 ? (crc
<< 1) ^ 0x04c11db7 : crc
<< 1;
398 /* CRC the class and type as well */
399 for (p1
= p
; p1
< p
+4; p1
++)
404 crc
= crc
& 0x80000000 ? (crc
<< 1) ^ 0x04c11db7 : crc
<< 1;
408 if (!CHECK_LEN(header
, p
, plen
, 0))
409 return crc
; /* bad packet */
416 size_t resize_packet(HEADER
*header
, size_t plen
, unsigned char *pheader
, size_t hlen
)
418 unsigned char *ansp
= skip_questions(header
, plen
);
420 /* if packet is malformed, just return as-is. */
424 if (!(ansp
= skip_section(ansp
, ntohs(header
->ancount
) + ntohs(header
->nscount
) + ntohs(header
->arcount
),
428 /* restore pseudoheader */
429 if (pheader
&& ntohs(header
->arcount
) == 0)
431 /* must use memmove, may overlap */
432 memmove(ansp
, pheader
, hlen
);
433 header
->arcount
= htons(1);
437 return ansp
- (unsigned char *)header
;
440 unsigned char *find_pseudoheader(HEADER
*header
, size_t plen
, size_t *len
, unsigned char **p
, int *is_sign
)
442 /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
443 also return length of pseudoheader in *len and pointer to the UDP size in *p
444 Finally, check to see if a packet is signed. If it is we cannot change a single bit before
445 forwarding. We look for SIG and TSIG in the addition section, and TKEY queries (for GSS-TSIG) */
447 int i
, arcount
= ntohs(header
->arcount
);
448 unsigned char *ansp
= (unsigned char *)(header
+1);
449 unsigned short rdlen
, type
, class;
450 unsigned char *ret
= NULL
;
456 if (header
->opcode
== QUERY
)
458 for (i
= ntohs(header
->qdcount
); i
!= 0; i
--)
460 if (!(ansp
= skip_name(ansp
, header
, plen
, 4)))
463 GETSHORT(type
, ansp
);
464 GETSHORT(class, ansp
);
466 if (class == C_IN
&& type
== T_TKEY
)
473 if (!(ansp
= skip_questions(header
, plen
)))
480 if (!(ansp
= skip_section(ansp
, ntohs(header
->ancount
) + ntohs(header
->nscount
), header
, plen
)))
483 for (i
= 0; i
< arcount
; i
++)
485 unsigned char *save
, *start
= ansp
;
486 if (!(ansp
= skip_name(ansp
, header
, plen
, 10)))
489 GETSHORT(type
, ansp
);
491 GETSHORT(class, ansp
);
493 GETSHORT(rdlen
, ansp
);
494 if (!ADD_RDLEN(header
, ansp
, plen
, rdlen
))
507 (type
== T_SIG
|| type
== T_TSIG
))
515 /* is addr in the non-globally-routed IP space? */
516 static int private_net(struct in_addr addr
, int ban_localhost
)
518 in_addr_t ip_addr
= ntohl(addr
.s_addr
);
521 (((ip_addr
& 0xFF000000) == 0x7F000000) && ban_localhost
) /* 127.0.0.0/8 (loopback) */ ||
522 ((ip_addr
& 0xFFFF0000) == 0xC0A80000) /* 192.168.0.0/16 (private) */ ||
523 ((ip_addr
& 0xFF000000) == 0x0A000000) /* 10.0.0.0/8 (private) */ ||
524 ((ip_addr
& 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12 (private) */ ||
525 ((ip_addr
& 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */ ;
528 static unsigned char *do_doctor(unsigned char *p
, int count
, HEADER
*header
, size_t qlen
, char *name
)
530 int i
, qtype
, qclass
, rdlen
;
533 for (i
= count
; i
!= 0; i
--)
535 if (name
&& (daemon
->options
& OPT_LOG
))
537 if (!extract_name(header
, qlen
, &p
, name
, 1, 10))
540 else if (!(p
= skip_name(p
, header
, qlen
, 10)))
541 return 0; /* bad packet */
548 if (qclass
== C_IN
&& qtype
== T_A
)
550 struct doctor
*doctor
;
553 if (!CHECK_LEN(header
, p
, qlen
, INADDRSZ
))
557 memcpy(&addr
, p
, INADDRSZ
);
559 for (doctor
= daemon
->doctors
; doctor
; doctor
= doctor
->next
)
561 if (doctor
->end
.s_addr
== 0)
563 if (!is_same_net(doctor
->in
, addr
, doctor
->mask
))
566 else if (ntohl(doctor
->in
.s_addr
) > ntohl(addr
.s_addr
) ||
567 ntohl(doctor
->end
.s_addr
) < ntohl(addr
.s_addr
))
570 addr
.s_addr
&= ~doctor
->mask
.s_addr
;
571 addr
.s_addr
|= (doctor
->out
.s_addr
& doctor
->mask
.s_addr
);
572 /* Since we munged the data, the server it came from is no longer authoritative */
574 memcpy(p
, &addr
, INADDRSZ
);
578 else if (qtype
== T_TXT
&& name
&& (daemon
->options
& OPT_LOG
))
580 unsigned char *p1
= p
;
581 if (!CHECK_LEN(header
, p1
, qlen
, rdlen
))
583 while ((p1
- p
) < rdlen
)
585 unsigned int i
, len
= *p1
;
586 unsigned char *p2
= p1
;
587 /* make counted string zero-term and sanitise */
588 for (i
= 0; i
< len
; i
++)
589 if (isprint(*(p2
+1)))
595 my_syslog(LOG_DEBUG
, "reply %s is %s", name
, p1
);
597 memmove(p1
+ 1, p1
, len
);
603 if (!ADD_RDLEN(header
, p
, qlen
, rdlen
))
604 return 0; /* bad packet */
610 static int find_soa(HEADER
*header
, size_t qlen
, char *name
)
613 int qtype
, qclass
, rdlen
;
614 unsigned long ttl
, minttl
= ULONG_MAX
;
615 int i
, found_soa
= 0;
617 /* first move to NS section and find TTL from any SOA section */
618 if (!(p
= skip_questions(header
, qlen
)) ||
619 !(p
= do_doctor(p
, ntohs(header
->ancount
), header
, qlen
, name
)))
620 return 0; /* bad packet */
622 for (i
= ntohs(header
->nscount
); i
!= 0; i
--)
624 if (!(p
= skip_name(p
, header
, qlen
, 10)))
625 return 0; /* bad packet */
632 if ((qclass
== C_IN
) && (qtype
== T_SOA
))
639 if (!(p
= skip_name(p
, header
, qlen
, 0)))
642 if (!(p
= skip_name(p
, header
, qlen
, 20)))
644 p
+= 16; /* SERIAL REFRESH RETRY EXPIRE */
646 GETLONG(ttl
, p
); /* minTTL */
650 else if (!ADD_RDLEN(header
, p
, qlen
, rdlen
))
651 return 0; /* bad packet */
654 /* rewrite addresses in additioal section too */
655 if (!do_doctor(p
, ntohs(header
->arcount
), header
, qlen
, NULL
))
659 minttl
= daemon
->neg_ttl
;
664 /* Note that the following code can create CNAME chains that don't point to a real record,
665 either because of lack of memory, or lack of SOA records. These are treated by the cache code as
666 expired and cleaned out that way.
667 Return 1 if we reject an address because it look like part of dns-rebinding attack. */
668 int extract_addresses(HEADER
*header
, size_t qlen
, char *name
, time_t now
, int is_sign
, int check_rebind
)
670 unsigned char *p
, *p1
, *endrr
, *namep
;
671 int i
, j
, qtype
, qclass
, aqtype
, aqclass
, ardlen
, res
, searched_soa
= 0;
672 unsigned long ttl
= 0;
673 struct all_addr addr
;
675 cache_start_insert();
677 /* find_soa is needed for dns_doctor and logging side-effects, so don't call it lazily if there are any. */
678 if (daemon
->doctors
|| (daemon
->options
& OPT_LOG
))
681 ttl
= find_soa(header
, qlen
, name
);
684 /* go through the questions. */
685 p
= (unsigned char *)(header
+1);
687 for (i
= ntohs(header
->qdcount
); i
!= 0; i
--)
689 int found
= 0, cname_count
= 5;
690 struct crec
*cpp
= NULL
;
691 int flags
= header
->rcode
== NXDOMAIN
? F_NXDOMAIN
: 0;
692 unsigned long cttl
= ULONG_MAX
, attl
;
695 if (!extract_name(header
, qlen
, &p
, name
, 1, 4))
696 return 0; /* bad packet */
704 /* PTRs: we chase CNAMEs here, since we have no way to
705 represent them in the cache. */
708 int name_encoding
= in_arpa_name_2_addr(name
, &addr
);
713 if (!(flags
& F_NXDOMAIN
))
716 if (!(p1
= skip_questions(header
, qlen
)))
719 for (j
= ntohs(header
->ancount
); j
!= 0; j
--)
721 unsigned char *tmp
= namep
;
722 /* the loop body overwrites the original name, so get it back here. */
723 if (!extract_name(header
, qlen
, &tmp
, name
, 1, 0) ||
724 !(res
= extract_name(header
, qlen
, &p1
, name
, 0, 10)))
725 return 0; /* bad packet */
727 GETSHORT(aqtype
, p1
);
728 GETSHORT(aqclass
, p1
);
730 if ((daemon
->max_ttl
!= 0) && (attl
> daemon
->max_ttl
) && !is_sign
)
733 PUTLONG(daemon
->max_ttl
, p1
);
735 GETSHORT(ardlen
, p1
);
738 /* TTL of record is minimum of CNAMES and PTR */
742 if (aqclass
== C_IN
&& res
!= 2 && (aqtype
== T_CNAME
|| aqtype
== T_PTR
))
744 if (!extract_name(header
, qlen
, &p1
, name
, 1, 0))
747 if (aqtype
== T_CNAME
)
750 return 0; /* looped CNAMES */
754 cache_insert(name
, &addr
, now
, cttl
, name_encoding
| F_REVERSE
);
759 if (!CHECK_LEN(header
, p1
, qlen
, 0))
760 return 0; /* bad packet */
764 if (!found
&& !(daemon
->options
& OPT_NO_NEG
))
769 ttl
= find_soa(header
, qlen
, NULL
);
772 cache_insert(NULL
, &addr
, now
, ttl
, name_encoding
| F_REVERSE
| F_NEG
| flags
);
777 /* everything other than PTR */
787 else if (qtype
== T_AAAA
)
796 if (!(flags
& F_NXDOMAIN
))
799 if (!(p1
= skip_questions(header
, qlen
)))
802 for (j
= ntohs(header
->ancount
); j
!= 0; j
--)
804 if (!(res
= extract_name(header
, qlen
, &p1
, name
, 0, 10)))
805 return 0; /* bad packet */
807 GETSHORT(aqtype
, p1
);
808 GETSHORT(aqclass
, p1
);
810 if ((daemon
->max_ttl
!= 0) && (attl
> daemon
->max_ttl
) && !is_sign
)
813 PUTLONG(daemon
->max_ttl
, p1
);
815 GETSHORT(ardlen
, p1
);
818 if (aqclass
== C_IN
&& res
!= 2 && (aqtype
== T_CNAME
|| aqtype
== qtype
))
820 if (aqtype
== T_CNAME
)
823 return 0; /* looped CNAMES */
824 newc
= cache_insert(name
, NULL
, now
, attl
, F_CNAME
| F_FORWARD
);
827 cpp
->addr
.cname
.cache
= newc
;
828 cpp
->addr
.cname
.uid
= newc
->uid
;
835 if (!extract_name(header
, qlen
, &p1
, name
, 1, 0))
843 /* copy address into aligned storage */
844 if (!CHECK_LEN(header
, p1
, qlen
, addrlen
))
845 return 0; /* bad packet */
846 memcpy(&addr
, p1
, addrlen
);
848 /* check for returned address in private space */
851 private_net(addr
.addr
.addr4
, !(daemon
->options
& OPT_LOCAL_REBIND
)))
854 newc
= cache_insert(name
, &addr
, now
, attl
, flags
| F_FORWARD
);
857 cpp
->addr
.cname
.cache
= newc
;
858 cpp
->addr
.cname
.uid
= newc
->uid
;
865 if (!CHECK_LEN(header
, p1
, qlen
, 0))
866 return 0; /* bad packet */
870 if (!found
&& !(daemon
->options
& OPT_NO_NEG
))
875 ttl
= find_soa(header
, qlen
, NULL
);
877 /* If there's no SOA to get the TTL from, but there is a CNAME
878 pointing at this, inherit its TTL */
881 newc
= cache_insert(name
, NULL
, now
, ttl
? ttl
: cttl
, F_FORWARD
| F_NEG
| flags
);
884 cpp
->addr
.cname
.cache
= newc
;
885 cpp
->addr
.cname
.uid
= newc
->uid
;
892 /* Don't put stuff from a truncated packet into the cache, but do everything else */
899 /* If the packet holds exactly one query
900 return F_IPV4 or F_IPV6 and leave the name from the query in name.
901 Abuse F_BIGNAME to indicate an NS query - yuck. */
903 unsigned short extract_request(HEADER
*header
, size_t qlen
, char *name
, unsigned short *typep
)
905 unsigned char *p
= (unsigned char *)(header
+1);
911 if (ntohs(header
->qdcount
) != 1 || header
->opcode
!= QUERY
)
912 return 0; /* must be exactly one query. */
914 if (!extract_name(header
, qlen
, &p
, name
, 1, 4))
915 return 0; /* bad packet */
930 return F_IPV4
| F_IPV6
;
931 if (qtype
== T_NS
|| qtype
== T_SOA
)
932 return F_QUERY
| F_BIGNAME
;
939 size_t setup_reply(HEADER
*header
, size_t qlen
,
940 struct all_addr
*addrp
, unsigned short flags
, unsigned long ttl
)
942 unsigned char *p
= skip_questions(header
, qlen
);
944 header
->qr
= 1; /* response */
945 header
->aa
= 0; /* authoritive */
946 header
->ra
= 1; /* recursion if available */
947 header
->tc
= 0; /* not truncated */
948 header
->nscount
= htons(0);
949 header
->arcount
= htons(0);
950 header
->ancount
= htons(0); /* no answers unless changed below */
952 header
->rcode
= SERVFAIL
; /* couldn't get memory */
953 else if (flags
== F_NOERR
)
954 header
->rcode
= NOERROR
; /* empty domain */
955 else if (flags
== F_NXDOMAIN
)
956 header
->rcode
= NXDOMAIN
;
957 else if (p
&& flags
== F_IPV4
)
958 { /* we know the address */
959 header
->rcode
= NOERROR
;
960 header
->ancount
= htons(1);
962 add_resource_record(header
, NULL
, NULL
, sizeof(HEADER
), &p
, ttl
, NULL
, T_A
, C_IN
, "4", addrp
);
965 else if (p
&& flags
== F_IPV6
)
967 header
->rcode
= NOERROR
;
968 header
->ancount
= htons(1);
970 add_resource_record(header
, NULL
, NULL
, sizeof(HEADER
), &p
, ttl
, NULL
, T_AAAA
, C_IN
, "6", addrp
);
973 else /* nowhere to forward to */
974 header
->rcode
= REFUSED
;
976 return p
- (unsigned char *)header
;
979 /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
980 int check_for_local_domain(char *name
, time_t now
)
983 struct mx_srv_record
*mx
;
984 struct txt_record
*txt
;
985 struct interface_name
*intr
;
986 struct ptr_record
*ptr
;
988 if ((crecp
= cache_find_by_name(NULL
, name
, now
, F_IPV4
| F_IPV6
)) &&
989 (crecp
->flags
& (F_HOSTS
| F_DHCP
)))
992 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
993 if (hostname_isequal(name
, mx
->name
))
996 for (txt
= daemon
->txt
; txt
; txt
= txt
->next
)
997 if (hostname_isequal(name
, txt
->name
))
1000 for (intr
= daemon
->int_names
; intr
; intr
= intr
->next
)
1001 if (hostname_isequal(name
, intr
->name
))
1004 for (ptr
= daemon
->ptr
; ptr
; ptr
= ptr
->next
)
1005 if (hostname_isequal(name
, ptr
->name
))
1011 /* Is the packet a reply with the answer address equal to addr?
1012 If so mung is into an NXDOMAIN reply and also put that information
1014 int check_for_bogus_wildcard(HEADER
*header
, size_t qlen
, char *name
,
1015 struct bogus_addr
*baddr
, time_t now
)
1018 int i
, qtype
, qclass
, rdlen
;
1020 struct bogus_addr
*baddrp
;
1022 /* skip over questions */
1023 if (!(p
= skip_questions(header
, qlen
)))
1024 return 0; /* bad packet */
1026 for (i
= ntohs(header
->ancount
); i
!= 0; i
--)
1028 if (!extract_name(header
, qlen
, &p
, name
, 1, 10))
1029 return 0; /* bad packet */
1032 GETSHORT(qclass
, p
);
1036 if (qclass
== C_IN
&& qtype
== T_A
)
1038 if (!CHECK_LEN(header
, p
, qlen
, INADDRSZ
))
1041 for (baddrp
= baddr
; baddrp
; baddrp
= baddrp
->next
)
1042 if (memcmp(&baddrp
->addr
, p
, INADDRSZ
) == 0)
1044 /* Found a bogus address. Insert that info here, since there no SOA record
1045 to get the ttl from in the normal processing */
1046 cache_start_insert();
1047 cache_insert(name
, NULL
, now
, ttl
, F_IPV4
| F_FORWARD
| F_NEG
| F_NXDOMAIN
| F_CONFIG
);
1054 if (!ADD_RDLEN(header
, p
, qlen
, rdlen
))
1061 static int add_resource_record(HEADER
*header
, char *limit
, int *truncp
, unsigned int nameoffset
, unsigned char **pp
,
1062 unsigned long ttl
, unsigned int *offset
, unsigned short type
, unsigned short class, char *format
, ...)
1065 unsigned char *sav
, *p
= *pp
;
1067 unsigned short usval
;
1071 if (truncp
&& *truncp
)
1074 PUTSHORT(nameoffset
| 0xc000, p
);
1077 PUTLONG(ttl
, p
); /* TTL */
1079 sav
= p
; /* Save pointer to RDLength field */
1080 PUTSHORT(0, p
); /* Placeholder RDLength */
1082 va_start(ap
, format
); /* make ap point to 1st unamed argument */
1084 for (; *format
; format
++)
1089 sval
= va_arg(ap
, char *);
1090 memcpy(p
, sval
, IN6ADDRSZ
);
1096 sval
= va_arg(ap
, char *);
1097 memcpy(p
, sval
, INADDRSZ
);
1102 usval
= va_arg(ap
, int);
1107 lval
= va_arg(ap
, long);
1112 /* get domain-name answer arg and store it in RDATA field */
1114 *offset
= p
- (unsigned char *)header
;
1115 p
= do_rfc1035_name(p
, va_arg(ap
, char *));
1120 usval
= va_arg(ap
, int);
1121 sval
= va_arg(ap
, char *);
1122 memcpy(p
, sval
, usval
);
1127 sval
= va_arg(ap
, char *);
1128 usval
= sval
? strlen(sval
) : 0;
1131 *p
++ = (unsigned char)usval
;
1132 memcpy(p
, sval
, usval
);
1137 va_end(ap
); /* clean up variable argument pointer */
1140 PUTSHORT(j
, sav
); /* Now, store real RDLength */
1142 /* check for overflow of buffer */
1143 if (limit
&& ((unsigned char *)limit
- p
) < 0)
1154 static unsigned long crec_ttl(struct crec
*crecp
, time_t now
)
1156 /* Return 0 ttl for DHCP entries, which might change
1157 before the lease expires. */
1159 if (crecp
->flags
& (F_IMMORTAL
| F_DHCP
))
1160 return daemon
->local_ttl
;
1162 /* Return the Max TTL value if it is lower then the actual TTL */
1163 if (daemon
->max_ttl
== 0 || ((unsigned)(crecp
->ttd
- now
) < daemon
->max_ttl
))
1164 return crecp
->ttd
- now
;
1166 return daemon
->max_ttl
;
1170 /* return zero if we can't answer from cache, or packet size if we can */
1171 size_t answer_request(HEADER
*header
, char *limit
, size_t qlen
,
1172 struct in_addr local_addr
, struct in_addr local_netmask
, time_t now
)
1174 char *name
= daemon
->namebuff
;
1175 unsigned char *p
, *ansp
, *pheader
;
1177 struct all_addr addr
;
1178 unsigned int nameoffset
;
1179 unsigned short flag
;
1180 int q
, ans
, anscount
= 0, addncount
= 0;
1181 int dryrun
= 0, sec_reqd
= 0;
1184 int nxdomain
= 0, auth
= 1, trunc
= 0;
1185 struct mx_srv_record
*rec
;
1187 /* If there is an RFC2671 pseudoheader then it will be overwritten by
1188 partial replies, so we have to do a dry run to see if we can answer
1189 the query. We check to see if the do bit is set, if so we always
1190 forward rather than answering from the cache, which doesn't include
1191 security information. */
1193 if (find_pseudoheader(header
, qlen
, NULL
, &pheader
, &is_sign
))
1195 unsigned short udpsz
, ext_rcode
, flags
;
1196 unsigned char *psave
= pheader
;
1198 GETSHORT(udpsz
, pheader
);
1199 GETSHORT(ext_rcode
, pheader
);
1200 GETSHORT(flags
, pheader
);
1202 sec_reqd
= flags
& 0x8000; /* do bit */
1204 /* If our client is advertising a larger UDP packet size
1205 than we allow, trim it so that we don't get an overlarge
1206 response from upstream */
1208 if (!is_sign
&& (udpsz
> daemon
->edns_pktsz
))
1209 PUTSHORT(daemon
->edns_pktsz
, psave
);
1214 if (ntohs(header
->qdcount
) == 0 || header
->opcode
!= QUERY
)
1217 for (rec
= daemon
->mxnames
; rec
; rec
= rec
->next
)
1221 /* determine end of question section (we put answers there) */
1222 if (!(ansp
= skip_questions(header
, qlen
)))
1223 return 0; /* bad packet */
1225 /* now process each question, answers go in RRs after the question */
1226 p
= (unsigned char *)(header
+1);
1228 for (q
= ntohs(header
->qdcount
); q
!= 0; q
--)
1230 /* save pointer to name for copying into answers */
1231 nameoffset
= p
- (unsigned char *)header
;
1233 /* now extract name as .-concatenated string into name */
1234 if (!extract_name(header
, qlen
, &p
, name
, 1, 4))
1235 return 0; /* bad packet */
1238 GETSHORT(qclass
, p
);
1240 ans
= 0; /* have we answered this question */
1242 if (qtype
== T_TXT
|| qtype
== T_ANY
)
1244 struct txt_record
*t
;
1245 for(t
= daemon
->txt
; t
; t
= t
->next
)
1247 if (t
->class == qclass
&& hostname_isequal(name
, t
->name
))
1252 log_query(F_CNAME
| F_FORWARD
| F_CONFIG
| F_NXDOMAIN
, name
, NULL
, "<TXT>");
1253 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1254 daemon
->local_ttl
, NULL
,
1255 T_TXT
, t
->class, "t", t
->len
, t
->txt
))
1265 if (qtype
== T_PTR
|| qtype
== T_ANY
)
1267 /* see if it's w.z.y.z.in-addr.arpa format */
1268 int is_arpa
= in_arpa_name_2_addr(name
, &addr
);
1269 struct ptr_record
*ptr
;
1270 struct interface_name
* intr
= NULL
;
1272 for (ptr
= daemon
->ptr
; ptr
; ptr
= ptr
->next
)
1273 if (hostname_isequal(name
, ptr
->name
))
1276 if (is_arpa
== F_IPV4
)
1277 for (intr
= daemon
->int_names
; intr
; intr
= intr
->next
)
1279 if (addr
.addr
.addr4
.s_addr
== get_ifaddr(intr
->intr
).s_addr
)
1282 while (intr
->next
&& strcmp(intr
->intr
, intr
->next
->intr
) == 0)
1291 log_query(F_IPV4
| F_REVERSE
| F_CONFIG
, intr
->name
, &addr
, NULL
);
1292 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1293 daemon
->local_ttl
, NULL
,
1294 T_PTR
, C_IN
, "d", intr
->name
))
1303 log_query(F_CNAME
| F_FORWARD
| F_CONFIG
| F_NXDOMAIN
, name
, NULL
, "<PTR>");
1304 for (ptr
= daemon
->ptr
; ptr
; ptr
= ptr
->next
)
1305 if (hostname_isequal(name
, ptr
->name
) &&
1306 add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1307 daemon
->local_ttl
, NULL
,
1308 T_PTR
, C_IN
, "d", ptr
->ptr
))
1313 else if ((crecp
= cache_find_by_addr(NULL
, &addr
, now
, is_arpa
)))
1316 /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
1317 if (qtype
== T_ANY
&& !(crecp
->flags
& (F_HOSTS
| F_DHCP
)))
1320 if (crecp
->flags
& F_NEG
)
1324 if (crecp
->flags
& F_NXDOMAIN
)
1327 log_query(crecp
->flags
& ~F_FORWARD
, name
, &addr
, NULL
);
1329 else if ((crecp
->flags
& (F_HOSTS
| F_DHCP
)) || !sec_reqd
)
1332 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
)))
1336 log_query(crecp
->flags
& ~F_FORWARD
, cache_get_name(crecp
), &addr
,
1337 record_source(crecp
->uid
));
1339 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1340 crec_ttl(crecp
, now
), NULL
,
1341 T_PTR
, C_IN
, "d", cache_get_name(crecp
)))
1345 } while ((crecp
= cache_find_by_addr(crecp
, &addr
, now
, is_arpa
)));
1346 else if (is_arpa
== F_IPV4
&&
1347 (daemon
->options
& OPT_BOGUSPRIV
) &&
1348 private_net(addr
.addr
.addr4
, 1))
1350 /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
1354 log_query(F_CONFIG
| F_REVERSE
| F_IPV4
| F_NEG
| F_NXDOMAIN
,
1359 for (flag
= F_IPV4
; flag
; flag
= (flag
== F_IPV4
) ? F_IPV6
: 0)
1361 unsigned short type
= T_A
;
1370 if (qtype
!= type
&& qtype
!= T_ANY
)
1373 /* Check for "A for A" queries; be rather conservative
1374 about what looks like dotted-quad. */
1381 for (cp
= name
, i
= 0, a
= 0; *cp
; i
++)
1383 if (!isdigit(*cp
) || (x
= strtol(cp
, &cp
, 10)) > 255)
1400 addr
.addr
.addr4
.s_addr
= htonl(a
);
1401 log_query(F_FORWARD
| F_CONFIG
| F_IPV4
, name
, &addr
, NULL
);
1402 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1403 daemon
->local_ttl
, NULL
, type
, C_IN
, "4", &addr
))
1410 /* interface name stuff */
1413 struct interface_name
*intr
;
1415 for (intr
= daemon
->int_names
; intr
; intr
= intr
->next
)
1416 if (hostname_isequal(name
, intr
->name
))
1424 if ((addr
.addr
.addr4
= get_ifaddr(intr
->intr
)).s_addr
== (in_addr_t
) -1)
1425 log_query(F_FORWARD
| F_CONFIG
| F_IPV4
| F_NEG
, name
, NULL
, NULL
);
1428 log_query(F_FORWARD
| F_CONFIG
| F_IPV4
, name
, &addr
, NULL
);
1429 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1430 daemon
->local_ttl
, NULL
, type
, C_IN
, "4", &addr
))
1439 if ((crecp
= cache_find_by_name(NULL
, name
, now
, flag
| F_CNAME
)))
1443 /* See if a putative address is on the network from which we recieved
1444 the query, is so we'll filter other answers. */
1445 if (local_addr
.s_addr
!= 0 && (daemon
->options
& OPT_LOCALISE
) && flag
== F_IPV4
)
1447 struct crec
*save
= crecp
;
1449 if ((crecp
->flags
& F_HOSTS
) &&
1450 is_same_net(*((struct in_addr
*)&crecp
->addr
), local_addr
, local_netmask
))
1455 } while ((crecp
= cache_find_by_name(crecp
, name
, now
, flag
| F_CNAME
)));
1461 /* don't answer wildcard queries with data not from /etc/hosts
1463 if (qtype
== T_ANY
&& !(crecp
->flags
& (F_HOSTS
| F_DHCP
)))
1466 if (crecp
->flags
& F_CNAME
)
1470 log_query(crecp
->flags
, name
, NULL
, record_source(crecp
->uid
));
1471 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1472 crec_ttl(crecp
, now
), &nameoffset
,
1473 T_CNAME
, C_IN
, "d", cache_get_name(crecp
->addr
.cname
.cache
)))
1477 strcpy(name
, cache_get_name(crecp
->addr
.cname
.cache
));
1481 if (crecp
->flags
& F_NEG
)
1485 if (crecp
->flags
& F_NXDOMAIN
)
1488 log_query(crecp
->flags
, name
, NULL
, NULL
);
1490 else if ((crecp
->flags
& (F_HOSTS
| F_DHCP
)) || !sec_reqd
)
1492 /* If we are returning local answers depending on network,
1495 (crecp
->flags
& F_HOSTS
) &&
1496 !is_same_net(*((struct in_addr
*)&crecp
->addr
), local_addr
, local_netmask
))
1499 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
)))
1505 log_query(crecp
->flags
& ~F_REVERSE
, name
, &crecp
->addr
.addr
,
1506 record_source(crecp
->uid
));
1508 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1509 crec_ttl(crecp
, now
), NULL
, type
, C_IN
,
1510 type
== T_A
? "4" : "6", &crecp
->addr
))
1514 } while ((crecp
= cache_find_by_name(crecp
, name
, now
, flag
| F_CNAME
)));
1518 if (qtype
== T_MX
|| qtype
== T_ANY
)
1521 for (rec
= daemon
->mxnames
; rec
; rec
= rec
->next
)
1522 if (!rec
->issrv
&& hostname_isequal(name
, rec
->name
))
1527 unsigned int offset
;
1528 log_query(F_CNAME
| F_FORWARD
| F_CONFIG
| F_NXDOMAIN
, name
, NULL
, "<MX>");
1529 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
, daemon
->local_ttl
,
1530 &offset
, T_MX
, C_IN
, "sd", rec
->weight
, rec
->target
))
1534 rec
->offset
= offset
;
1539 if (!found
&& (daemon
->options
& (OPT_SELFMX
| OPT_LOCALMX
)) &&
1540 cache_find_by_name(NULL
, name
, now
, F_HOSTS
| F_DHCP
))
1545 log_query(F_CNAME
| F_FORWARD
| F_CONFIG
| F_NXDOMAIN
, name
, NULL
, "<MX>");
1546 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
, daemon
->local_ttl
, NULL
,
1547 T_MX
, C_IN
, "sd", 1,
1548 (daemon
->options
& OPT_SELFMX
) ? name
: daemon
->mxtarget
))
1554 if (qtype
== T_SRV
|| qtype
== T_ANY
)
1558 for (rec
= daemon
->mxnames
; rec
; rec
= rec
->next
)
1559 if (rec
->issrv
&& hostname_isequal(name
, rec
->name
))
1564 unsigned int offset
;
1565 log_query(F_CNAME
| F_FORWARD
| F_CONFIG
| F_NXDOMAIN
, name
, NULL
, "<SRV>");
1566 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
, daemon
->local_ttl
,
1567 &offset
, T_SRV
, C_IN
, "sssd",
1568 rec
->priority
, rec
->weight
, rec
->srvport
, rec
->target
))
1572 rec
->offset
= offset
;
1577 if (!found
&& (daemon
->options
& OPT_FILTER
) && (qtype
== T_SRV
|| (qtype
== T_ANY
&& strchr(name
, '_'))))
1581 log_query(F_CONFIG
| F_NEG
, name
, NULL
, NULL
);
1585 if (qtype
== T_NAPTR
|| qtype
== T_ANY
)
1588 for (na
= daemon
->naptr
; na
; na
= na
->next
)
1589 if (hostname_isequal(name
, na
->name
))
1594 log_query(F_CNAME
| F_FORWARD
| F_CONFIG
| F_NXDOMAIN
, name
, NULL
, "<NAPTR>");
1595 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
, daemon
->local_ttl
,
1596 NULL
, T_NAPTR
, C_IN
, "sszzzd",
1597 na
->order
, na
->pref
, na
->flags
, na
->services
, na
->regexp
, na
->replace
))
1603 if (qtype
== T_MAILB
)
1604 ans
= 1, nxdomain
= 1;
1606 if (qtype
== T_SOA
&& (daemon
->options
& OPT_FILTER
))
1610 log_query(F_CONFIG
| F_NEG
, name
, &addr
, NULL
);
1615 return 0; /* failed to answer a question */
1624 /* create an additional data section, for stuff in SRV and MX record replies. */
1625 for (rec
= daemon
->mxnames
; rec
; rec
= rec
->next
)
1626 if (rec
->offset
!= 0)
1629 struct mx_srv_record
*tmp
;
1630 for (tmp
= rec
->next
; tmp
; tmp
= tmp
->next
)
1631 if (tmp
->offset
!= 0 && hostname_isequal(rec
->target
, tmp
->target
))
1635 while ((crecp
= cache_find_by_name(crecp
, rec
->target
, now
, F_IPV4
| F_IPV6
)))
1638 int type
= crecp
->flags
& F_IPV4
? T_A
: T_AAAA
;
1642 if (crecp
->flags
& F_NEG
)
1645 if (add_resource_record(header
, limit
, NULL
, rec
->offset
, &ansp
,
1646 crec_ttl(crecp
, now
), NULL
, type
, C_IN
,
1647 crecp
->flags
& F_IPV4
? "4" : "6", &crecp
->addr
))
1652 /* done all questions, set up header and return length of result */
1653 header
->qr
= 1; /* response */
1654 header
->aa
= auth
; /* authoritive - only hosts and DHCP derived names. */
1655 header
->ra
= 1; /* recursion if available */
1656 header
->tc
= trunc
; /* truncation */
1657 if (anscount
== 0 && nxdomain
)
1658 header
->rcode
= NXDOMAIN
;
1660 header
->rcode
= NOERROR
; /* no error */
1661 header
->ancount
= htons(anscount
);
1662 header
->nscount
= htons(0);
1663 header
->arcount
= htons(addncount
);
1664 return ansp
- (unsigned char *)header
;