1 /* dnsmasq is Copyright (c) 2000-2013 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/>.
20 #define CHECK_LEN(header, pp, plen, len) \
21 ((size_t)((pp) - (unsigned char *)(header) + (len)) <= (plen))
23 #define ADD_RDLEN(header, pp, plen, len) \
24 (!CHECK_LEN(header, pp, plen, len) ? 0 : (((pp) += (len)), 1))
26 int extract_name(struct dns_header
*header
, size_t plen
, unsigned char **pp
,
27 char *name
, int isExtract
, int extrabytes
)
29 unsigned char *cp
= (unsigned char *)name
, *p
= *pp
, *p1
= NULL
;
30 unsigned int j
, l
, hops
= 0;
38 unsigned int label_type
;
40 if (!CHECK_LEN(header
, p
, plen
, 1))
46 /* check that there are the correct no of bytes after the name */
47 if (!CHECK_LEN(header
, p
, plen
, extrabytes
))
52 if (cp
!= (unsigned char *)name
)
54 *cp
= 0; /* terminate: lose final period */
59 if (p1
) /* we jumped via compression */
67 label_type
= l
& 0xc0;
69 if (label_type
== 0xc0) /* pointer */
71 if (!CHECK_LEN(header
, p
, plen
, 1))
78 if (!p1
) /* first jump, save location to go back to */
81 hops
++; /* break malicious infinite loops */
85 p
= l
+ (unsigned char *)header
;
87 else if (label_type
== 0x80)
88 return 0; /* reserved */
89 else if (label_type
== 0x40)
91 unsigned int count
, digs
;
94 return 0; /* we only understand bitstrings */
97 return 0; /* Cannot compare bitsrings */
102 digs
= ((count
-1)>>2)+1;
104 /* output is \[x<hex>/siz]. which is digs+9 chars */
105 if (cp
- (unsigned char *)name
+ digs
+ 9 >= MAXDNAME
)
107 if (!CHECK_LEN(header
, p
, plen
, (count
-1)>>3))
113 for (j
=0; j
<digs
; j
++)
121 *cp
++ = dig
< 10 ? dig
+ '0' : dig
+ 'A' - 10;
123 cp
+= sprintf((char *)cp
, "/%d]", count
);
124 /* do this here to overwrite the zero char from sprintf */
128 { /* label_type = 0 -> label. */
129 if (cp
- (unsigned char *)name
+ l
+ 1 >= MAXDNAME
)
131 if (!CHECK_LEN(header
, p
, plen
, l
))
134 for(j
=0; j
<l
; j
++, p
++)
137 unsigned char c
= *p
;
138 if (isascii(c
) && !iscntrl(c
) && c
!= '.')
145 unsigned char c1
= *cp
, c2
= *p
;
152 if (c1
>= 'A' && c1
<= 'Z')
154 if (c2
>= 'A' && c2
<= 'Z')
164 else if (*cp
!= 0 && *cp
++ != '.')
170 /* Max size of input string (for IPv6) is 75 chars.) */
171 #define MAXARPANAME 75
172 int in_arpa_name_2_addr(char *namein
, struct all_addr
*addrp
)
175 char name
[MAXARPANAME
+1], *cp1
;
176 unsigned char *addr
= (unsigned char *)addrp
;
177 char *lastchunk
= NULL
, *penchunk
= NULL
;
179 if (strlen(namein
) > MAXARPANAME
)
182 memset(addrp
, 0, sizeof(struct all_addr
));
184 /* turn name into a series of asciiz strings */
185 /* j counts no of labels */
186 for(j
= 1,cp1
= name
; *namein
; cp1
++, namein
++)
189 penchunk
= lastchunk
;
202 if (hostname_isequal(lastchunk
, "arpa") && hostname_isequal(penchunk
, "in-addr"))
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)
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 */
215 for (cp
= cp1
; *cp
; cp
++)
216 if (!isdigit((unsigned char)*cp
))
228 else if (hostname_isequal(penchunk
, "ip6") &&
229 (hostname_isequal(lastchunk
, "int") || hostname_isequal(lastchunk
, "arpa")))
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]
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.
240 if (*name
== '\\' && *(name
+1) == '[' &&
241 (*(name
+2) == 'x' || *(name
+2) == 'X'))
243 for (j
= 0, cp1
= name
+3; *cp1
&& isxdigit((unsigned char) *cp1
) && j
< 32; cp1
++, j
++)
249 addr
[j
/2] |= strtol(xdig
, NULL
, 16);
251 addr
[j
/2] = strtol(xdig
, NULL
, 16) << 4;
254 if (*cp1
== '/' && j
== 32)
259 for (cp1
= name
; cp1
!= penchunk
; cp1
+= strlen(cp1
)+1)
261 if (*(cp1
+1) || !isxdigit((unsigned char)*cp1
))
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);
277 static unsigned char *skip_name(unsigned char *ansp
, struct dns_header
*header
, size_t plen
, int extrabytes
)
281 unsigned int label_type
;
283 if (!CHECK_LEN(header
, ansp
, plen
, 1))
286 label_type
= (*ansp
) & 0xc0;
288 if (label_type
== 0xc0)
290 /* pointer for compression. */
294 else if (label_type
== 0x80)
295 return NULL
; /* reserved */
296 else if (label_type
== 0x40)
298 /* Extended label type */
301 if (!CHECK_LEN(header
, ansp
, plen
, 2))
304 if (((*ansp
++) & 0x3f) != 1)
305 return NULL
; /* we only understand bitstrings */
307 count
= *(ansp
++); /* Bits in bitstring */
309 if (count
== 0) /* count == 0 means 256 bits */
312 ansp
+= ((count
-1)>>3)+1;
315 { /* label type == 0 Bottom six bits is length */
316 unsigned int len
= (*ansp
++) & 0x3f;
318 if (!ADD_RDLEN(header
, ansp
, plen
, len
))
322 break; /* zero length label marks the end. */
326 if (!CHECK_LEN(header
, ansp
, plen
, extrabytes
))
332 unsigned char *skip_questions(struct dns_header
*header
, size_t plen
)
335 unsigned char *ansp
= (unsigned char *)(header
+1);
337 for (q
= ntohs(header
->qdcount
); q
!= 0; q
--)
339 if (!(ansp
= skip_name(ansp
, header
, plen
, 4)))
341 ansp
+= 4; /* class and type */
347 static unsigned char *skip_section(unsigned char *ansp
, int count
, struct dns_header
*header
, size_t plen
)
351 for (i
= 0; i
< count
; i
++)
353 if (!(ansp
= skip_name(ansp
, header
, plen
, 10)))
355 ansp
+= 8; /* type, class, TTL */
356 GETSHORT(rdlen
, ansp
);
357 if (!ADD_RDLEN(header
, ansp
, plen
, rdlen
))
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.
368 We ignore case in the names for the same reason. Return all-ones
369 if there is not question section. */
370 unsigned int questions_crc(struct dns_header
*header
, size_t plen
, char *name
)
373 unsigned int crc
= 0xffffffff;
374 unsigned char *p1
, *p
= (unsigned char *)(header
+1);
376 for (q
= ntohs(header
->qdcount
); q
!= 0; q
--)
378 if (!extract_name(header
, plen
, &p
, name
, 1, 4))
379 return crc
; /* bad packet */
381 for (p1
= (unsigned char *)name
; *p1
; p1
++)
386 if (c
>= 'A' && c
<= 'Z')
391 crc
= crc
& 0x80000000 ? (crc
<< 1) ^ 0x04c11db7 : crc
<< 1;
394 /* CRC the class and type as well */
395 for (p1
= p
; p1
< p
+4; p1
++)
400 crc
= crc
& 0x80000000 ? (crc
<< 1) ^ 0x04c11db7 : crc
<< 1;
404 if (!CHECK_LEN(header
, p
, plen
, 0))
405 return crc
; /* bad packet */
412 size_t resize_packet(struct dns_header
*header
, size_t plen
, unsigned char *pheader
, size_t hlen
)
414 unsigned char *ansp
= skip_questions(header
, plen
);
416 /* if packet is malformed, just return as-is. */
420 if (!(ansp
= skip_section(ansp
, ntohs(header
->ancount
) + ntohs(header
->nscount
) + ntohs(header
->arcount
),
424 /* restore pseudoheader */
425 if (pheader
&& ntohs(header
->arcount
) == 0)
427 /* must use memmove, may overlap */
428 memmove(ansp
, pheader
, hlen
);
429 header
->arcount
= htons(1);
433 return ansp
- (unsigned char *)header
;
436 unsigned char *find_pseudoheader(struct dns_header
*header
, size_t plen
, size_t *len
, unsigned char **p
, int *is_sign
)
438 /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
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) */
443 int i
, arcount
= ntohs(header
->arcount
);
444 unsigned char *ansp
= (unsigned char *)(header
+1);
445 unsigned short rdlen
, type
, class;
446 unsigned char *ret
= NULL
;
452 if (OPCODE(header
) == QUERY
)
454 for (i
= ntohs(header
->qdcount
); i
!= 0; i
--)
456 if (!(ansp
= skip_name(ansp
, header
, plen
, 4)))
459 GETSHORT(type
, ansp
);
460 GETSHORT(class, ansp
);
462 if (class == C_IN
&& type
== T_TKEY
)
469 if (!(ansp
= skip_questions(header
, plen
)))
476 if (!(ansp
= skip_section(ansp
, ntohs(header
->ancount
) + ntohs(header
->nscount
), header
, plen
)))
479 for (i
= 0; i
< arcount
; i
++)
481 unsigned char *save
, *start
= ansp
;
482 if (!(ansp
= skip_name(ansp
, header
, plen
, 10)))
485 GETSHORT(type
, ansp
);
487 GETSHORT(class, ansp
);
489 GETSHORT(rdlen
, ansp
);
490 if (!ADD_RDLEN(header
, ansp
, plen
, rdlen
))
503 (type
== T_SIG
|| type
== T_TSIG
))
511 unsigned char *limit
;
512 struct dns_header
*header
;
514 union mysockaddr
*l3
;
517 static size_t add_pseudoheader(struct dns_header
*header
, size_t plen
, unsigned char *limit
,
518 int optno
, unsigned char *opt
, size_t optlen
)
520 unsigned char *lenp
, *datap
, *p
;
523 if (ntohs(header
->arcount
) == 0)
525 /* We are adding the pseudoheader */
526 if (!(p
= skip_questions(header
, plen
)) ||
527 !(p
= skip_section(p
,
528 ntohs(header
->ancount
) + ntohs(header
->nscount
),
531 *p
++ = 0; /* empty name */
533 PUTSHORT(daemon
->edns_pktsz
, p
); /* max packet length */
534 PUTLONG(0, p
); /* extended RCODE */
536 PUTSHORT(0, p
); /* RDLEN */
538 if (((ssize_t
)optlen
) > (limit
- (p
+ 4)))
539 return plen
; /* Too big */
540 header
->arcount
= htons(1);
546 unsigned short code
, len
;
548 if (ntohs(header
->arcount
) != 1 ||
549 !(p
= find_pseudoheader(header
, plen
, NULL
, NULL
, &is_sign
)) ||
551 (!(p
= skip_name(p
, header
, plen
, 10))))
554 p
+= 8; /* skip UDP length and RCODE */
558 if (!CHECK_LEN(header
, p
, plen
, rdlen
))
559 return plen
; /* bad packet */
562 /* check if option already there */
563 for (i
= 0; i
+ 4 < rdlen
; i
+= len
+ 4)
572 if (((ssize_t
)optlen
) > (limit
- (p
+ 4)))
573 return plen
; /* Too big */
578 memcpy(p
, opt
, optlen
);
581 PUTSHORT(p
- datap
, lenp
);
582 return p
- (unsigned char *)header
;
586 static int filter_mac(int family
, char *addrp
, char *mac
, size_t maclen
, void *parmv
)
588 struct macparm
*parm
= parmv
;
591 if (family
== parm
->l3
->sa
.sa_family
)
593 if (family
== AF_INET
&& memcmp (&parm
->l3
->in
.sin_addr
, addrp
, INADDRSZ
) == 0)
597 if (family
== AF_INET6
&& memcmp (&parm
->l3
->in6
.sin6_addr
, addrp
, IN6ADDRSZ
) == 0)
603 return 1; /* continue */
605 parm
->plen
= add_pseudoheader(parm
->header
, parm
->plen
, parm
->limit
, EDNS0_OPTION_MAC
, (unsigned char *)mac
, maclen
);
610 size_t add_mac(struct dns_header
*header
, size_t plen
, char *limit
, union mysockaddr
*l3
)
614 /* Must have an existing pseudoheader as the only ar-record,
615 or have no ar-records. Must also not be signed */
617 if (ntohs(header
->arcount
) > 1)
620 parm
.header
= header
;
621 parm
.limit
= (unsigned char *)limit
;
625 iface_enumerate(AF_UNSPEC
, &parm
, filter_mac
);
632 u8 source_netmask
, scope_netmask
;
640 size_t calc_subnet_opt(struct subnet_opt
*opt
, union mysockaddr
*source
)
642 /* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
648 if (source
->sa
.sa_family
== AF_INET6
)
650 opt
->family
= htons(2);
651 opt
->source_netmask
= daemon
->addr6_netmask
;
652 addrp
= &source
->in6
.sin6_addr
;
657 opt
->family
= htons(1);
658 opt
->source_netmask
= daemon
->addr4_netmask
;
659 addrp
= &source
->in
.sin_addr
;
662 opt
->scope_netmask
= 0;
665 if (opt
->source_netmask
!= 0)
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));
676 size_t add_source_addr(struct dns_header
*header
, size_t plen
, char *limit
, union mysockaddr
*source
)
678 /* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
681 struct subnet_opt opt
;
683 len
= calc_subnet_opt(&opt
, source
);
684 return add_pseudoheader(header
, plen
, (unsigned char *)limit
, EDNS0_OPTION_CLIENT_SUBNET
, (unsigned char *)&opt
, len
);
687 int check_source(struct dns_header
*header
, size_t plen
, unsigned char *pseudoheader
, union mysockaddr
*peer
)
689 /* Section 9.2, Check that subnet option in reply matches. */
693 struct subnet_opt opt
;
697 calc_len
= calc_subnet_opt(&opt
, peer
);
699 if (!(p
= skip_name(pseudoheader
, header
, plen
, 10)))
702 p
+= 8; /* skip UDP length and RCODE */
705 if (!CHECK_LEN(header
, p
, plen
, rdlen
))
706 return 1; /* bad packet */
708 /* check if option there */
709 for (i
= 0; i
+ 4 < rdlen
; i
+= len
+ 4)
713 if (code
== EDNS0_OPTION_CLIENT_SUBNET
)
715 /* make sure this doesn't mismatch. */
716 opt
.scope_netmask
= p
[3];
717 if (len
!= calc_len
|| memcmp(p
, &opt
, len
) != 0)
726 /* is addr in the non-globally-routed IP space? */
727 int private_net(struct in_addr addr
, int ban_localhost
)
729 in_addr_t ip_addr
= ntohl(addr
.s_addr
);
732 (((ip_addr
& 0xFF000000) == 0x7F000000) && ban_localhost
) /* 127.0.0.0/8 (loopback) */ ||
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) */ ;
739 static unsigned char *do_doctor(unsigned char *p
, int count
, struct dns_header
*header
, size_t qlen
, char *name
)
741 int i
, qtype
, qclass
, rdlen
;
743 for (i
= count
; i
!= 0; i
--)
745 if (name
&& option_bool(OPT_LOG
))
747 if (!extract_name(header
, qlen
, &p
, name
, 1, 10))
750 else if (!(p
= skip_name(p
, header
, qlen
, 10)))
751 return 0; /* bad packet */
758 if (qclass
== C_IN
&& qtype
== T_A
)
760 struct doctor
*doctor
;
763 if (!CHECK_LEN(header
, p
, qlen
, INADDRSZ
))
767 memcpy(&addr
, p
, INADDRSZ
);
769 for (doctor
= daemon
->doctors
; doctor
; doctor
= doctor
->next
)
771 if (doctor
->end
.s_addr
== 0)
773 if (!is_same_net(doctor
->in
, addr
, doctor
->mask
))
776 else if (ntohl(doctor
->in
.s_addr
) > ntohl(addr
.s_addr
) ||
777 ntohl(doctor
->end
.s_addr
) < ntohl(addr
.s_addr
))
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 */
783 header
->hb3
&= ~HB3_AA
;
784 memcpy(p
, &addr
, INADDRSZ
);
788 else if (qtype
== T_TXT
&& name
&& option_bool(OPT_LOG
))
790 unsigned char *p1
= p
;
791 if (!CHECK_LEN(header
, p1
, qlen
, rdlen
))
793 while ((p1
- p
) < rdlen
)
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
++)
800 if (!isprint((int)*(p2
+1)))
807 my_syslog(LOG_INFO
, "reply %s is %s", name
, p1
);
809 memmove(p1
+ 1, p1
, i
);
815 if (!ADD_RDLEN(header
, p
, qlen
, rdlen
))
816 return 0; /* bad packet */
822 static int find_soa(struct dns_header
*header
, size_t qlen
, char *name
)
825 int qtype
, qclass
, rdlen
;
826 unsigned long ttl
, minttl
= ULONG_MAX
;
827 int i
, found_soa
= 0;
829 /* first move to NS section and find TTL from any SOA section */
830 if (!(p
= skip_questions(header
, qlen
)) ||
831 !(p
= do_doctor(p
, ntohs(header
->ancount
), header
, qlen
, name
)))
832 return 0; /* bad packet */
834 for (i
= ntohs(header
->nscount
); i
!= 0; i
--)
836 if (!(p
= skip_name(p
, header
, qlen
, 10)))
837 return 0; /* bad packet */
844 if ((qclass
== C_IN
) && (qtype
== T_SOA
))
851 if (!(p
= skip_name(p
, header
, qlen
, 0)))
854 if (!(p
= skip_name(p
, header
, qlen
, 20)))
856 p
+= 16; /* SERIAL REFRESH RETRY EXPIRE */
858 GETLONG(ttl
, p
); /* minTTL */
862 else if (!ADD_RDLEN(header
, p
, qlen
, rdlen
))
863 return 0; /* bad packet */
866 /* rewrite addresses in additioal section too */
867 if (!do_doctor(p
, ntohs(header
->arcount
), header
, qlen
, NULL
))
871 minttl
= daemon
->neg_ttl
;
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
878 expired and cleaned out that way.
879 Return 1 if we reject an address because it look like part of dns-rebinding attack. */
880 int extract_addresses(struct dns_header
*header
, size_t qlen
, char *name
, time_t now
,
881 char **ipsets
, int is_sign
, int check_rebind
, int checking_disabled
)
883 unsigned char *p
, *p1
, *endrr
, *namep
;
884 int i
, j
, qtype
, qclass
, aqtype
, aqclass
, ardlen
, res
, searched_soa
= 0;
885 unsigned long ttl
= 0;
886 struct all_addr addr
;
890 (void)ipsets
; /* unused */
893 cache_start_insert();
895 /* find_soa is needed for dns_doctor and logging side-effects, so don't call it lazily if there are any. */
896 if (daemon
->doctors
|| option_bool(OPT_LOG
))
899 ttl
= find_soa(header
, qlen
, name
);
902 /* go through the questions. */
903 p
= (unsigned char *)(header
+1);
905 for (i
= ntohs(header
->qdcount
); i
!= 0; i
--)
907 int found
= 0, cname_count
= 5;
908 struct crec
*cpp
= NULL
;
909 int flags
= RCODE(header
) == NXDOMAIN
? F_NXDOMAIN
: 0;
910 unsigned long cttl
= ULONG_MAX
, attl
;
913 if (!extract_name(header
, qlen
, &p
, name
, 1, 4))
914 return 0; /* bad packet */
922 /* PTRs: we chase CNAMEs here, since we have no way to
923 represent them in the cache. */
926 int name_encoding
= in_arpa_name_2_addr(name
, &addr
);
931 if (!(flags
& F_NXDOMAIN
))
934 if (!(p1
= skip_questions(header
, qlen
)))
937 for (j
= ntohs(header
->ancount
); j
!= 0; j
--)
939 unsigned char *tmp
= namep
;
940 /* the loop body overwrites the original name, so get it back here. */
941 if (!extract_name(header
, qlen
, &tmp
, name
, 1, 0) ||
942 !(res
= extract_name(header
, qlen
, &p1
, name
, 0, 10)))
943 return 0; /* bad packet */
945 GETSHORT(aqtype
, p1
);
946 GETSHORT(aqclass
, p1
);
948 if ((daemon
->max_ttl
!= 0) && (attl
> daemon
->max_ttl
) && !is_sign
)
951 PUTLONG(daemon
->max_ttl
, p1
);
953 GETSHORT(ardlen
, p1
);
956 /* TTL of record is minimum of CNAMES and PTR */
960 if (aqclass
== C_IN
&& res
!= 2 && (aqtype
== T_CNAME
|| aqtype
== T_PTR
))
962 if (!extract_name(header
, qlen
, &p1
, name
, 1, 0))
965 if (aqtype
== T_CNAME
)
968 return 0; /* looped CNAMES */
972 cache_insert(name
, &addr
, now
, cttl
, name_encoding
| F_REVERSE
);
977 if (!CHECK_LEN(header
, p1
, qlen
, 0))
978 return 0; /* bad packet */
982 if (!found
&& !option_bool(OPT_NO_NEG
))
987 ttl
= find_soa(header
, qlen
, NULL
);
990 cache_insert(NULL
, &addr
, now
, ttl
, name_encoding
| F_REVERSE
| F_NEG
| flags
);
995 /* everything other than PTR */
1005 else if (qtype
== T_AAAA
)
1007 addrlen
= IN6ADDRSZ
;
1015 if (!(p1
= skip_questions(header
, qlen
)))
1018 for (j
= ntohs(header
->ancount
); j
!= 0; j
--)
1020 if (!(res
= extract_name(header
, qlen
, &p1
, name
, 0, 10)))
1021 return 0; /* bad packet */
1023 GETSHORT(aqtype
, p1
);
1024 GETSHORT(aqclass
, p1
);
1026 if ((daemon
->max_ttl
!= 0) && (attl
> daemon
->max_ttl
) && !is_sign
)
1029 PUTLONG(daemon
->max_ttl
, p1
);
1031 GETSHORT(ardlen
, p1
);
1034 if (aqclass
== C_IN
&& res
!= 2 && (aqtype
== T_CNAME
|| aqtype
== qtype
))
1036 if (aqtype
== T_CNAME
)
1039 return 0; /* looped CNAMES */
1040 newc
= cache_insert(name
, NULL
, now
, attl
, F_CNAME
| F_FORWARD
);
1043 newc
->addr
.cname
.target
.cache
= NULL
;
1046 cpp
->addr
.cname
.target
.cache
= newc
;
1047 cpp
->addr
.cname
.uid
= newc
->uid
;
1055 if (!extract_name(header
, qlen
, &p1
, name
, 1, 0))
1059 else if (!(flags
& F_NXDOMAIN
))
1063 /* copy address into aligned storage */
1064 if (!CHECK_LEN(header
, p1
, qlen
, addrlen
))
1065 return 0; /* bad packet */
1066 memcpy(&addr
, p1
, addrlen
);
1068 /* check for returned address in private space */
1071 private_net(addr
.addr
.addr4
, !option_bool(OPT_LOCAL_REBIND
)))
1075 if (ipsets
&& (flags
& (F_IPV4
| F_IPV6
)))
1077 ipsets_cur
= ipsets
;
1079 add_to_ipset(*ipsets_cur
++, &addr
, flags
, 0);
1083 newc
= cache_insert(name
, &addr
, now
, attl
, flags
| F_FORWARD
);
1086 cpp
->addr
.cname
.target
.cache
= newc
;
1087 cpp
->addr
.cname
.uid
= newc
->uid
;
1094 if (!CHECK_LEN(header
, p1
, qlen
, 0))
1095 return 0; /* bad packet */
1098 if (!found
&& !option_bool(OPT_NO_NEG
))
1103 ttl
= find_soa(header
, qlen
, NULL
);
1105 /* If there's no SOA to get the TTL from, but there is a CNAME
1106 pointing at this, inherit its TTL */
1109 newc
= cache_insert(name
, NULL
, now
, ttl
? ttl
: cttl
, F_FORWARD
| F_NEG
| flags
);
1112 cpp
->addr
.cname
.target
.cache
= newc
;
1113 cpp
->addr
.cname
.uid
= newc
->uid
;
1120 /* Don't put stuff from a truncated packet into the cache.
1121 Don't cache replies where DNSSEC validation was turned off, either
1122 the upstream server told us so, or the original query specified it.
1123 Don't cache replies from non-recursive nameservers, since we may get a
1124 reply containing a CNAME but not its target, even though the target
1126 if (!(header
->hb3
& HB3_TC
) &&
1127 !(header
->hb4
& HB4_CD
) &&
1128 (header
->hb4
& HB4_RA
) &&
1135 /* If the packet holds exactly one query
1136 return F_IPV4 or F_IPV6 and leave the name from the query in name */
1138 unsigned int extract_request(struct dns_header
*header
, size_t qlen
, char *name
, unsigned short *typep
)
1140 unsigned char *p
= (unsigned char *)(header
+1);
1146 if (ntohs(header
->qdcount
) != 1 || OPCODE(header
) != QUERY
)
1147 return 0; /* must be exactly one query. */
1149 if (!extract_name(header
, qlen
, &p
, name
, 1, 4))
1150 return 0; /* bad packet */
1153 GETSHORT(qclass
, p
);
1162 if (qtype
== T_AAAA
)
1165 return F_IPV4
| F_IPV6
;
1172 size_t setup_reply(struct dns_header
*header
, size_t qlen
,
1173 struct all_addr
*addrp
, unsigned int flags
, unsigned long ttl
)
1175 unsigned char *p
= skip_questions(header
, qlen
);
1177 /* clear authoritative and truncated flags, set QR flag */
1178 header
->hb3
= (header
->hb3
& ~(HB3_AA
| HB3_TC
)) | HB3_QR
;
1180 header
->hb4
|= HB4_RA
;
1182 header
->nscount
= htons(0);
1183 header
->arcount
= htons(0);
1184 header
->ancount
= htons(0); /* no answers unless changed below */
1186 SET_RCODE(header
, SERVFAIL
); /* couldn't get memory */
1187 else if (flags
== F_NOERR
)
1188 SET_RCODE(header
, NOERROR
); /* empty domain */
1189 else if (flags
== F_NXDOMAIN
)
1190 SET_RCODE(header
, NXDOMAIN
);
1191 else if (p
&& flags
== F_IPV4
)
1192 { /* we know the address */
1193 SET_RCODE(header
, NOERROR
);
1194 header
->ancount
= htons(1);
1195 header
->hb3
|= HB3_AA
;
1196 add_resource_record(header
, NULL
, NULL
, sizeof(struct dns_header
), &p
, ttl
, NULL
, T_A
, C_IN
, "4", addrp
);
1199 else if (p
&& flags
== F_IPV6
)
1201 SET_RCODE(header
, NOERROR
);
1202 header
->ancount
= htons(1);
1203 header
->hb3
|= HB3_AA
;
1204 add_resource_record(header
, NULL
, NULL
, sizeof(struct dns_header
), &p
, ttl
, NULL
, T_AAAA
, C_IN
, "6", addrp
);
1207 else /* nowhere to forward to */
1208 SET_RCODE(header
, REFUSED
);
1210 return p
- (unsigned char *)header
;
1213 /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
1214 int check_for_local_domain(char *name
, time_t now
)
1217 struct mx_srv_record
*mx
;
1218 struct txt_record
*txt
;
1219 struct interface_name
*intr
;
1220 struct ptr_record
*ptr
;
1221 struct naptr
*naptr
;
1223 if ((crecp
= cache_find_by_name(NULL
, name
, now
, F_IPV4
| F_IPV6
| F_CNAME
)) &&
1224 (crecp
->flags
& (F_HOSTS
| F_DHCP
)))
1227 for (naptr
= daemon
->naptr
; naptr
; naptr
= naptr
->next
)
1228 if (hostname_isequal(name
, naptr
->name
))
1231 for (mx
= daemon
->mxnames
; mx
; mx
= mx
->next
)
1232 if (hostname_isequal(name
, mx
->name
))
1235 for (txt
= daemon
->txt
; txt
; txt
= txt
->next
)
1236 if (hostname_isequal(name
, txt
->name
))
1239 for (intr
= daemon
->int_names
; intr
; intr
= intr
->next
)
1240 if (hostname_isequal(name
, intr
->name
))
1243 for (ptr
= daemon
->ptr
; ptr
; ptr
= ptr
->next
)
1244 if (hostname_isequal(name
, ptr
->name
))
1250 /* Is the packet a reply with the answer address equal to addr?
1251 If so mung is into an NXDOMAIN reply and also put that information
1253 int check_for_bogus_wildcard(struct dns_header
*header
, size_t qlen
, char *name
,
1254 struct bogus_addr
*baddr
, time_t now
)
1257 int i
, qtype
, qclass
, rdlen
;
1259 struct bogus_addr
*baddrp
;
1261 /* skip over questions */
1262 if (!(p
= skip_questions(header
, qlen
)))
1263 return 0; /* bad packet */
1265 for (i
= ntohs(header
->ancount
); i
!= 0; i
--)
1267 if (!extract_name(header
, qlen
, &p
, name
, 1, 10))
1268 return 0; /* bad packet */
1271 GETSHORT(qclass
, p
);
1275 if (qclass
== C_IN
&& qtype
== T_A
)
1277 if (!CHECK_LEN(header
, p
, qlen
, INADDRSZ
))
1280 for (baddrp
= baddr
; baddrp
; baddrp
= baddrp
->next
)
1281 if (memcmp(&baddrp
->addr
, p
, INADDRSZ
) == 0)
1283 /* Found a bogus address. Insert that info here, since there no SOA record
1284 to get the ttl from in the normal processing */
1285 cache_start_insert();
1286 cache_insert(name
, NULL
, now
, ttl
, F_IPV4
| F_FORWARD
| F_NEG
| F_NXDOMAIN
| F_CONFIG
);
1293 if (!ADD_RDLEN(header
, p
, qlen
, rdlen
))
1300 int add_resource_record(struct dns_header
*header
, char *limit
, int *truncp
, int nameoffset
, unsigned char **pp
,
1301 unsigned long ttl
, int *offset
, unsigned short type
, unsigned short class, char *format
, ...)
1304 unsigned char *sav
, *p
= *pp
;
1306 unsigned short usval
;
1310 if (truncp
&& *truncp
)
1313 va_start(ap
, format
); /* make ap point to 1st unamed argument */
1317 PUTSHORT(nameoffset
| 0xc000, p
);
1321 char *name
= va_arg(ap
, char *);
1323 p
= do_rfc1035_name(p
, name
);
1326 PUTSHORT(-nameoffset
| 0xc000, p
);
1334 PUTLONG(ttl
, p
); /* TTL */
1336 sav
= p
; /* Save pointer to RDLength field */
1337 PUTSHORT(0, p
); /* Placeholder RDLength */
1339 for (; *format
; format
++)
1344 sval
= va_arg(ap
, char *);
1345 memcpy(p
, sval
, IN6ADDRSZ
);
1351 sval
= va_arg(ap
, char *);
1352 memcpy(p
, sval
, INADDRSZ
);
1357 usval
= va_arg(ap
, int);
1362 lval
= va_arg(ap
, long);
1367 /* get domain-name answer arg and store it in RDATA field */
1369 *offset
= p
- (unsigned char *)header
;
1370 p
= do_rfc1035_name(p
, va_arg(ap
, char *));
1375 usval
= va_arg(ap
, int);
1376 sval
= va_arg(ap
, char *);
1378 memcpy(p
, sval
, usval
);
1383 sval
= va_arg(ap
, char *);
1384 usval
= sval
? strlen(sval
) : 0;
1387 *p
++ = (unsigned char)usval
;
1388 memcpy(p
, sval
, usval
);
1393 va_end(ap
); /* clean up variable argument pointer */
1396 PUTSHORT(j
, sav
); /* Now, store real RDLength */
1398 /* check for overflow of buffer */
1399 if (limit
&& ((unsigned char *)limit
- p
) < 0)
1410 static unsigned long crec_ttl(struct crec
*crecp
, time_t now
)
1412 /* Return 0 ttl for DHCP entries, which might change
1413 before the lease expires. */
1415 if (crecp
->flags
& (F_IMMORTAL
| F_DHCP
))
1416 return daemon
->local_ttl
;
1418 /* Return the Max TTL value if it is lower then the actual TTL */
1419 if (daemon
->max_ttl
== 0 || ((unsigned)(crecp
->ttd
- now
) < daemon
->max_ttl
))
1420 return crecp
->ttd
- now
;
1422 return daemon
->max_ttl
;
1426 /* return zero if we can't answer from cache, or packet size if we can */
1427 size_t answer_request(struct dns_header
*header
, char *limit
, size_t qlen
,
1428 struct in_addr local_addr
, struct in_addr local_netmask
, time_t now
)
1430 char *name
= daemon
->namebuff
;
1431 unsigned char *p
, *ansp
, *pheader
;
1433 struct all_addr addr
;
1435 unsigned short flag
;
1436 int q
, ans
, anscount
= 0, addncount
= 0;
1437 int dryrun
= 0, sec_reqd
= 0;
1440 int nxdomain
= 0, auth
= 1, trunc
= 0;
1441 struct mx_srv_record
*rec
;
1443 /* If there is an RFC2671 pseudoheader then it will be overwritten by
1444 partial replies, so we have to do a dry run to see if we can answer
1445 the query. We check to see if the do bit is set, if so we always
1446 forward rather than answering from the cache, which doesn't include
1447 security information. */
1449 if (find_pseudoheader(header
, qlen
, NULL
, &pheader
, &is_sign
))
1451 unsigned short udpsz
, flags
;
1452 unsigned char *psave
= pheader
;
1454 GETSHORT(udpsz
, pheader
);
1455 pheader
+= 2; /* ext_rcode */
1456 GETSHORT(flags
, pheader
);
1458 sec_reqd
= flags
& 0x8000; /* do bit */
1460 /* If our client is advertising a larger UDP packet size
1461 than we allow, trim it so that we don't get an overlarge
1462 response from upstream */
1464 if (!is_sign
&& (udpsz
> daemon
->edns_pktsz
))
1465 PUTSHORT(daemon
->edns_pktsz
, psave
);
1470 if (ntohs(header
->qdcount
) == 0 || OPCODE(header
) != QUERY
)
1473 for (rec
= daemon
->mxnames
; rec
; rec
= rec
->next
)
1477 /* determine end of question section (we put answers there) */
1478 if (!(ansp
= skip_questions(header
, qlen
)))
1479 return 0; /* bad packet */
1481 /* now process each question, answers go in RRs after the question */
1482 p
= (unsigned char *)(header
+1);
1484 for (q
= ntohs(header
->qdcount
); q
!= 0; q
--)
1486 /* save pointer to name for copying into answers */
1487 nameoffset
= p
- (unsigned char *)header
;
1489 /* now extract name as .-concatenated string into name */
1490 if (!extract_name(header
, qlen
, &p
, name
, 1, 4))
1491 return 0; /* bad packet */
1494 GETSHORT(qclass
, p
);
1496 ans
= 0; /* have we answered this question */
1498 if (qtype
== T_TXT
|| qtype
== T_ANY
)
1500 struct txt_record
*t
;
1501 for(t
= daemon
->txt
; t
; t
= t
->next
)
1503 if (t
->class == qclass
&& hostname_isequal(name
, t
->name
))
1508 log_query(F_CONFIG
| F_RRNAME
, name
, NULL
, "<TXT>");
1509 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1510 daemon
->local_ttl
, NULL
,
1511 T_TXT
, t
->class, "t", t
->len
, t
->txt
))
1521 struct txt_record
*t
;
1523 for (t
= daemon
->rr
; t
; t
= t
->next
)
1524 if ((t
->class == qtype
|| qtype
== T_ANY
) && hostname_isequal(name
, t
->name
))
1529 log_query(F_CONFIG
| F_RRNAME
, name
, NULL
, "<RR>");
1530 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1531 daemon
->local_ttl
, NULL
,
1532 t
->class, C_IN
, "t", t
->len
, t
->txt
))
1537 if (qtype
== T_PTR
|| qtype
== T_ANY
)
1539 /* see if it's w.z.y.z.in-addr.arpa format */
1540 int is_arpa
= in_arpa_name_2_addr(name
, &addr
);
1541 struct ptr_record
*ptr
;
1542 struct interface_name
* intr
= NULL
;
1544 for (ptr
= daemon
->ptr
; ptr
; ptr
= ptr
->next
)
1545 if (hostname_isequal(name
, ptr
->name
))
1548 if (is_arpa
== F_IPV4
)
1549 for (intr
= daemon
->int_names
; intr
; intr
= intr
->next
)
1551 struct addrlist
*addrlist
;
1553 for (addrlist
= intr
->addr4
; addrlist
; addrlist
= addrlist
->next
)
1554 if (addr
.addr
.addr4
.s_addr
== addrlist
->addr
.addr
.addr4
.s_addr
)
1560 while (intr
->next
&& strcmp(intr
->intr
, intr
->next
->intr
) == 0)
1564 else if (is_arpa
== F_IPV6
)
1565 for (intr
= daemon
->int_names
; intr
; intr
= intr
->next
)
1567 struct addrlist
*addrlist
;
1569 for (addrlist
= intr
->addr6
; addrlist
; addrlist
= addrlist
->next
)
1570 if (IN6_ARE_ADDR_EQUAL(&addr
.addr
.addr6
, &addrlist
->addr
.addr
.addr6
))
1576 while (intr
->next
&& strcmp(intr
->intr
, intr
->next
->intr
) == 0)
1586 log_query(is_arpa
| F_REVERSE
| F_CONFIG
, intr
->name
, &addr
, NULL
);
1587 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1588 daemon
->local_ttl
, NULL
,
1589 T_PTR
, C_IN
, "d", intr
->name
))
1598 log_query(F_CONFIG
| F_RRNAME
, name
, NULL
, "<PTR>");
1599 for (ptr
= daemon
->ptr
; ptr
; ptr
= ptr
->next
)
1600 if (hostname_isequal(name
, ptr
->name
) &&
1601 add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1602 daemon
->local_ttl
, NULL
,
1603 T_PTR
, C_IN
, "d", ptr
->ptr
))
1608 else if ((crecp
= cache_find_by_addr(NULL
, &addr
, now
, is_arpa
)))
1611 /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
1612 if (qtype
== T_ANY
&& !(crecp
->flags
& (F_HOSTS
| F_DHCP
)))
1615 if (crecp
->flags
& F_NEG
)
1619 if (crecp
->flags
& F_NXDOMAIN
)
1622 log_query(crecp
->flags
& ~F_FORWARD
, name
, &addr
, NULL
);
1624 else if ((crecp
->flags
& (F_HOSTS
| F_DHCP
)) || !sec_reqd
)
1627 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
)))
1631 log_query(crecp
->flags
& ~F_FORWARD
, cache_get_name(crecp
), &addr
,
1632 record_source(crecp
->uid
));
1634 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1635 crec_ttl(crecp
, now
), NULL
,
1636 T_PTR
, C_IN
, "d", cache_get_name(crecp
)))
1640 } while ((crecp
= cache_find_by_addr(crecp
, &addr
, now
, is_arpa
)));
1641 else if (is_rev_synth(is_arpa
, &addr
, name
))
1646 log_query(F_CONFIG
| F_REVERSE
| is_arpa
, name
, &addr
, NULL
);
1648 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1649 daemon
->local_ttl
, NULL
,
1650 T_PTR
, C_IN
, "d", name
))
1654 else if (is_arpa
== F_IPV4
&&
1655 option_bool(OPT_BOGUSPRIV
) &&
1656 private_net(addr
.addr
.addr4
, 1))
1658 /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
1662 log_query(F_CONFIG
| F_REVERSE
| F_IPV4
| F_NEG
| F_NXDOMAIN
,
1667 for (flag
= F_IPV4
; flag
; flag
= (flag
== F_IPV4
) ? F_IPV6
: 0)
1669 unsigned short type
= T_A
;
1670 struct interface_name
*intr
;
1679 if (qtype
!= type
&& qtype
!= T_ANY
)
1682 /* Check for "A for A" queries; be rather conservative
1683 about what looks like dotted-quad. */
1690 for (cp
= name
, i
= 0, a
= 0; *cp
; i
++)
1692 if (!isdigit((unsigned char)*cp
) || (x
= strtol(cp
, &cp
, 10)) > 255)
1709 addr
.addr
.addr4
.s_addr
= htonl(a
);
1710 log_query(F_FORWARD
| F_CONFIG
| F_IPV4
, name
, &addr
, NULL
);
1711 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1712 daemon
->local_ttl
, NULL
, type
, C_IN
, "4", &addr
))
1719 /* interface name stuff */
1721 for (intr
= daemon
->int_names
; intr
; intr
= intr
->next
)
1722 if (hostname_isequal(name
, intr
->name
))
1727 struct addrlist
*addrlist
;
1730 enumerate_interfaces(0);
1732 for (intr
= daemon
->int_names
; intr
; intr
= intr
->next
)
1733 if (hostname_isequal(name
, intr
->name
))
1735 addrlist
= intr
->addr4
;
1738 addrlist
= intr
->addr6
;
1746 for (; addrlist
; addrlist
= addrlist
->next
)
1748 log_query(F_FORWARD
| F_CONFIG
| flag
, name
, &addrlist
->addr
, NULL
);
1749 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1750 daemon
->local_ttl
, NULL
, type
, C_IN
,
1751 type
== T_A
? "4" : "6", &addrlist
->addr
))
1758 if (!dryrun
&& !gotit
)
1759 log_query(F_FORWARD
| F_CONFIG
| flag
| F_NEG
, name
, NULL
, NULL
);
1765 if ((crecp
= cache_find_by_name(NULL
, name
, now
, flag
| F_CNAME
)))
1769 /* See if a putative address is on the network from which we recieved
1770 the query, is so we'll filter other answers. */
1771 if (local_addr
.s_addr
!= 0 && option_bool(OPT_LOCALISE
) && flag
== F_IPV4
)
1773 struct crec
*save
= crecp
;
1775 if ((crecp
->flags
& F_HOSTS
) &&
1776 is_same_net(*((struct in_addr
*)&crecp
->addr
), local_addr
, local_netmask
))
1781 } while ((crecp
= cache_find_by_name(crecp
, name
, now
, flag
| F_CNAME
)));
1787 /* don't answer wildcard queries with data not from /etc/hosts
1789 if (qtype
== T_ANY
&& !(crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
)))
1792 if (crecp
->flags
& F_CNAME
)
1794 char *cname_target
= cache_get_cname_target(crecp
);
1798 log_query(crecp
->flags
, name
, NULL
, record_source(crecp
->uid
));
1799 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1800 crec_ttl(crecp
, now
), &nameoffset
,
1801 T_CNAME
, C_IN
, "d", cname_target
))
1805 strcpy(name
, cname_target
);
1806 /* check if target interface_name */
1807 if (crecp
->addr
.cname
.uid
== -1)
1808 goto intname_restart
;
1813 if (crecp
->flags
& F_NEG
)
1817 if (crecp
->flags
& F_NXDOMAIN
)
1820 log_query(crecp
->flags
, name
, NULL
, NULL
);
1822 else if ((crecp
->flags
& (F_HOSTS
| F_DHCP
)) || !sec_reqd
)
1824 /* If we are returning local answers depending on network,
1827 (crecp
->flags
& F_HOSTS
) &&
1828 !is_same_net(*((struct in_addr
*)&crecp
->addr
), local_addr
, local_netmask
))
1831 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
)))
1837 log_query(crecp
->flags
& ~F_REVERSE
, name
, &crecp
->addr
.addr
,
1838 record_source(crecp
->uid
));
1840 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1841 crec_ttl(crecp
, now
), NULL
, type
, C_IN
,
1842 type
== T_A
? "4" : "6", &crecp
->addr
))
1846 } while ((crecp
= cache_find_by_name(crecp
, name
, now
, flag
| F_CNAME
)));
1848 else if (is_name_synthetic(flag
, name
, &addr
))
1853 log_query(F_FORWARD
| F_CONFIG
| flag
, name
, &addr
, NULL
);
1854 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1855 daemon
->local_ttl
, NULL
, type
, C_IN
, type
== T_A
? "4" : "6", &addr
))
1861 if (qtype
== T_CNAME
|| qtype
== T_ANY
)
1863 if ((crecp
= cache_find_by_name(NULL
, name
, now
, F_CNAME
)) &&
1864 (qtype
== T_CNAME
|| (crecp
->flags
& (F_HOSTS
| F_DHCP
))))
1869 log_query(crecp
->flags
, name
, NULL
, record_source(crecp
->uid
));
1870 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
,
1871 crec_ttl(crecp
, now
), &nameoffset
,
1872 T_CNAME
, C_IN
, "d", cache_get_cname_target(crecp
)))
1878 if (qtype
== T_MX
|| qtype
== T_ANY
)
1881 for (rec
= daemon
->mxnames
; rec
; rec
= rec
->next
)
1882 if (!rec
->issrv
&& hostname_isequal(name
, rec
->name
))
1888 log_query(F_CONFIG
| F_RRNAME
, name
, NULL
, "<MX>");
1889 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
, daemon
->local_ttl
,
1890 &offset
, T_MX
, C_IN
, "sd", rec
->weight
, rec
->target
))
1894 rec
->offset
= offset
;
1899 if (!found
&& (option_bool(OPT_SELFMX
) || option_bool(OPT_LOCALMX
)) &&
1900 cache_find_by_name(NULL
, name
, now
, F_HOSTS
| F_DHCP
))
1905 log_query(F_CONFIG
| F_RRNAME
, name
, NULL
, "<MX>");
1906 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
, daemon
->local_ttl
, NULL
,
1907 T_MX
, C_IN
, "sd", 1,
1908 option_bool(OPT_SELFMX
) ? name
: daemon
->mxtarget
))
1914 if (qtype
== T_SRV
|| qtype
== T_ANY
)
1917 struct mx_srv_record
*move
= NULL
, **up
= &daemon
->mxnames
;
1919 for (rec
= daemon
->mxnames
; rec
; rec
= rec
->next
)
1920 if (rec
->issrv
&& hostname_isequal(name
, rec
->name
))
1926 log_query(F_CONFIG
| F_RRNAME
, name
, NULL
, "<SRV>");
1927 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
, daemon
->local_ttl
,
1928 &offset
, T_SRV
, C_IN
, "sssd",
1929 rec
->priority
, rec
->weight
, rec
->srvport
, rec
->target
))
1933 rec
->offset
= offset
;
1937 /* unlink first SRV record found */
1949 /* put first SRV record back at the end. */
1956 if (!found
&& option_bool(OPT_FILTER
) && (qtype
== T_SRV
|| (qtype
== T_ANY
&& strchr(name
, '_'))))
1960 log_query(F_CONFIG
| F_NEG
, name
, NULL
, NULL
);
1964 if (qtype
== T_NAPTR
|| qtype
== T_ANY
)
1967 for (na
= daemon
->naptr
; na
; na
= na
->next
)
1968 if (hostname_isequal(name
, na
->name
))
1973 log_query(F_CONFIG
| F_RRNAME
, name
, NULL
, "<NAPTR>");
1974 if (add_resource_record(header
, limit
, &trunc
, nameoffset
, &ansp
, daemon
->local_ttl
,
1975 NULL
, T_NAPTR
, C_IN
, "sszzzd",
1976 na
->order
, na
->pref
, na
->flags
, na
->services
, na
->regexp
, na
->replace
))
1982 if (qtype
== T_MAILB
)
1983 ans
= 1, nxdomain
= 1;
1985 if (qtype
== T_SOA
&& option_bool(OPT_FILTER
))
1989 log_query(F_CONFIG
| F_NEG
, name
, &addr
, NULL
);
1994 return 0; /* failed to answer a question */
2003 /* create an additional data section, for stuff in SRV and MX record replies. */
2004 for (rec
= daemon
->mxnames
; rec
; rec
= rec
->next
)
2005 if (rec
->offset
!= 0)
2008 struct mx_srv_record
*tmp
;
2009 for (tmp
= rec
->next
; tmp
; tmp
= tmp
->next
)
2010 if (tmp
->offset
!= 0 && hostname_isequal(rec
->target
, tmp
->target
))
2014 while ((crecp
= cache_find_by_name(crecp
, rec
->target
, now
, F_IPV4
| F_IPV6
)))
2017 int type
= crecp
->flags
& F_IPV4
? T_A
: T_AAAA
;
2021 if (crecp
->flags
& F_NEG
)
2024 if (add_resource_record(header
, limit
, NULL
, rec
->offset
, &ansp
,
2025 crec_ttl(crecp
, now
), NULL
, type
, C_IN
,
2026 crecp
->flags
& F_IPV4
? "4" : "6", &crecp
->addr
))
2031 /* done all questions, set up header and return length of result */
2032 /* clear authoritative and truncated flags, set QR flag */
2033 header
->hb3
= (header
->hb3
& ~(HB3_AA
| HB3_TC
)) | HB3_QR
;
2035 header
->hb4
|= HB4_RA
;
2037 /* authoritive - only hosts and DHCP derived names. */
2039 header
->hb3
|= HB3_AA
;
2043 header
->hb3
|= HB3_TC
;
2046 SET_RCODE(header
, NXDOMAIN
);
2048 SET_RCODE(header
, NOERROR
); /* no error */
2049 header
->ancount
= htons(anscount
);
2050 header
->nscount
= htons(0);
2051 header
->arcount
= htons(addncount
);
2052 return ansp
- (unsigned char *)header
;