• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* dnsmasq is Copyright (c) 2000-2009 Simon Kelley
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; version 2 dated June, 1991, or
6    (at your option) version 3 dated 29 June, 2007.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program.  If not, see <http://www.gnu.org/licenses/>.
15 */
16 
17 #include "dnsmasq.h"
18 
19 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, ...);
23 
24 #define CHECK_LEN(header, pp, plen, len) \
25     ((size_t)((pp) - (unsigned char *)(header) + (len)) <= (plen))
26 
27 #define ADD_RDLEN(header, pp, plen, len) \
28     (!CHECK_LEN(header, pp, plen, len) ? 0 : (long)((pp) += (len)), 1)
29 
extract_name(HEADER * header,size_t plen,unsigned char ** pp,char * name,int isExtract,int extrabytes)30 static int extract_name(HEADER *header, size_t plen, unsigned char **pp,
31 			char *name, int isExtract, int extrabytes)
32 {
33   unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL;
34   unsigned int j, l, hops = 0;
35   int retvalue = 1;
36 
37   if (isExtract)
38     *cp = 0;
39 
40   while (1)
41     {
42       unsigned int label_type;
43 
44       if (!CHECK_LEN(header, p, plen, 1))
45 	return 0;
46 
47       if ((l = *p++) == 0)
48 	/* end marker */
49 	{
50 	  /* check that there are the correct no of bytes after the name */
51 	  if (!CHECK_LEN(header, p1 ? p1 : p, plen, extrabytes))
52 	    return 0;
53 
54 	  if (isExtract)
55 	    {
56 	      if (cp != (unsigned char *)name)
57 		cp--;
58 	      *cp = 0; /* terminate: lose final period */
59 	    }
60 	  else if (*cp != 0)
61 	    retvalue = 2;
62 
63 	  if (p1) /* we jumped via compression */
64 	    *pp = p1;
65 	  else
66 	    *pp = p;
67 
68 	  return retvalue;
69 	}
70 
71       label_type = l & 0xc0;
72 
73       if (label_type == 0xc0) /* pointer */
74 	{
75 	  if (!CHECK_LEN(header, p, plen, 1))
76 	    return 0;
77 
78 	  /* get offset */
79 	  l = (l&0x3f) << 8;
80 	  l |= *p++;
81 
82 	  if (!p1) /* first jump, save location to go back to */
83 	    p1 = p;
84 
85 	  hops++; /* break malicious infinite loops */
86 	  if (hops > 255)
87 	    return 0;
88 
89 	  p = l + (unsigned char *)header;
90 	}
91       else if (label_type == 0x80)
92 	return 0; /* reserved */
93       else if (label_type == 0x40)
94 	{ /* ELT */
95 	  unsigned int count, digs;
96 
97 	  if ((l & 0x3f) != 1)
98 	    return 0; /* we only understand bitstrings */
99 
100 	  if (!isExtract)
101 	    return 0; /* Cannot compare bitsrings */
102 
103 	  count = *p++;
104 	  if (count == 0)
105 	    count = 256;
106 	  digs = ((count-1)>>2)+1;
107 
108 	  /* output is \[x<hex>/siz]. which is digs+9 chars */
109 	  if (cp - (unsigned char *)name + digs + 9 >= MAXDNAME)
110 	    return 0;
111 	  if (!CHECK_LEN(header, p, plen, (count-1)>>3))
112 	    return 0;
113 
114 	  *cp++ = '\\';
115 	  *cp++ = '[';
116 	  *cp++ = 'x';
117 	  for (j=0; j<digs; j++)
118 	    {
119 	      unsigned int dig;
120 	      if (j%2 == 0)
121 		dig = *p >> 4;
122 	      else
123 		dig = *p++ & 0x0f;
124 
125 	      *cp++ = dig < 10 ? dig + '0' : dig + 'A' - 10;
126 	    }
127 	  cp += sprintf((char *)cp, "/%d]", count);
128 	  /* do this here to overwrite the zero char from sprintf */
129 	  *cp++ = '.';
130 	}
131       else
132 	{ /* label_type = 0 -> label. */
133 	  if (cp - (unsigned char *)name + l + 1 >= MAXDNAME)
134 	    return 0;
135 	  if (!CHECK_LEN(header, p, plen, l))
136 	    return 0;
137 
138 	  for(j=0; j<l; j++, p++)
139 	    if (isExtract)
140 	      {
141 		unsigned char c = *p;
142 		if (isascii(c) && !iscntrl(c) && c != '.')
143 		  *cp++ = *p;
144 		else
145 		  return 0;
146 	      }
147 	    else
148 	      {
149 		unsigned char c1 = *cp, c2 = *p;
150 
151 		if (c1 == 0)
152 		  retvalue = 2;
153 		else
154 		  {
155 		    cp++;
156 		    if (c1 >= 'A' && c1 <= 'Z')
157 		      c1 += 'a' - 'A';
158 		    if (c2 >= 'A' && c2 <= 'Z')
159 		      c2 += 'a' - 'A';
160 
161 		    if (c1 != c2)
162 		      retvalue =  2;
163 		  }
164 	      }
165 
166 	  if (isExtract)
167 	    *cp++ = '.';
168 	  else if (*cp != 0 && *cp++ != '.')
169 	    retvalue = 2;
170 	}
171     }
172 }
173 
174 /* Max size of input string (for IPv6) is 75 chars.) */
175 #define MAXARPANAME 75
in_arpa_name_2_addr(char * namein,struct all_addr * addrp)176 static int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
177 {
178   int j;
179   char name[MAXARPANAME+1], *cp1;
180   unsigned char *addr = (unsigned char *)addrp;
181   char *lastchunk = NULL, *penchunk = NULL;
182 
183   if (strlen(namein) > MAXARPANAME)
184     return 0;
185 
186   memset(addrp, 0, sizeof(struct all_addr));
187 
188   /* turn name into a series of asciiz strings */
189   /* j counts no of labels */
190   for(j = 1,cp1 = name; *namein; cp1++, namein++)
191     if (*namein == '.')
192       {
193 	penchunk = lastchunk;
194         lastchunk = cp1 + 1;
195 	*cp1 = 0;
196 	j++;
197       }
198     else
199       *cp1 = *namein;
200 
201   *cp1 = 0;
202 
203   if (j<3)
204     return 0;
205 
206   if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr"))
207     {
208       /* IP v4 */
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)
214 	{
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 */
218 	  char *cp;
219 	  for (cp = cp1; *cp; cp++)
220 	    if (!isdigit((int)*cp))
221 	      return 0;
222 
223 	  addr[3] = addr[2];
224 	  addr[2] = addr[1];
225 	  addr[1] = addr[0];
226 	  addr[0] = atoi(cp1);
227 	}
228 
229       return F_IPV4;
230     }
231 #ifdef HAVE_IPV6
232   else if (hostname_isequal(penchunk, "ip6") &&
233 	   (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa")))
234     {
235       /* IP v6:
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]
238 
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.
242       */
243 
244       /* TODO: does this make sense? */
245 
246       if (*name == '\\' && *(name+1) == '[' &&
247 	  (*(name+2) == 'x' || *(name+2) == 'X'))
248 	{
249 	  for (j = 0, cp1 = name+3; *cp1 && isxdigit((int) *cp1) && j < 32; cp1++, j++)
250 	    {
251 	      char xdig[2];
252 	      xdig[0] = *cp1;
253 	      xdig[1] = 0;
254 	      if (j%2)
255 		addr[j/2] |= strtol(xdig, NULL, 16);
256 	      else
257 		addr[j/2] = strtol(xdig, NULL, 16) << 4;
258 	    }
259 
260 	  if (*cp1 == '/' && j == 32)
261 	    return F_IPV6;
262 	}
263       else
264 	{
265 	  for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
266 	    {
267 	      if (*(cp1+1) || !isxdigit((int)*cp1))
268 		return 0;
269 
270 	      for (j = sizeof(struct all_addr)-1; j>0; j--)
271 		addr[j] = (addr[j] >> 4) | (addr[j-1] << 4);
272 	      addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
273 	    }
274 
275 	  return F_IPV6;
276 	}
277     }
278 #endif
279 
280   return 0;
281 }
282 
skip_name(unsigned char * ansp,HEADER * header,size_t plen,int extrabytes)283 static unsigned char *skip_name(unsigned char *ansp, HEADER *header, size_t plen, int extrabytes)
284 {
285   while(1)
286     {
287       unsigned int label_type;
288 
289       if (!CHECK_LEN(header, ansp, plen, 1))
290 	return NULL;
291 
292       label_type = (*ansp) & 0xc0;
293 
294       if (label_type == 0xc0)
295 	{
296 	  /* pointer for compression. */
297 	  ansp += 2;
298 	  break;
299 	}
300       else if (label_type == 0x80)
301 	return NULL; /* reserved */
302       else if (label_type == 0x40)
303 	{
304 	  /* Extended label type */
305 	  unsigned int count;
306 
307 	  if (!CHECK_LEN(header, ansp, plen, 2))
308 	    return NULL;
309 
310 	  if (((*ansp++) & 0x3f) != 1)
311 	    return NULL; /* we only understand bitstrings */
312 
313 	  count = *(ansp++); /* Bits in bitstring */
314 
315 	  if (count == 0) /* count == 0 means 256 bits */
316 	    ansp += 32;
317 	  else
318 	    ansp += ((count-1)>>3)+1;
319 	}
320       else
321 	{ /* label type == 0 Bottom six bits is length */
322 	  unsigned int len = (*ansp++) & 0x3f;
323 
324 	  if (!ADD_RDLEN(header, ansp, plen, len))
325 	    return NULL;
326 
327 	  if (len == 0)
328 	    break; /* zero length label marks the end. */
329 	}
330     }
331 
332   if (!CHECK_LEN(header, ansp, plen, extrabytes))
333     return NULL;
334 
335   return ansp;
336 }
337 
skip_questions(HEADER * header,size_t plen)338 static unsigned char *skip_questions(HEADER *header, size_t plen)
339 {
340   int q;
341   unsigned char *ansp = (unsigned char *)(header+1);
342 
343   for (q = ntohs(header->qdcount); q != 0; q--)
344     {
345       if (!(ansp = skip_name(ansp, header, plen, 4)))
346 	return NULL;
347       ansp += 4; /* class and type */
348     }
349 
350   return ansp;
351 }
352 
skip_section(unsigned char * ansp,int count,HEADER * header,size_t plen)353 static unsigned char *skip_section(unsigned char *ansp, int count, HEADER *header, size_t plen)
354 {
355   int i, rdlen;
356 
357   for (i = 0; i < count; i++)
358     {
359       if (!(ansp = skip_name(ansp, header, plen, 10)))
360 	return NULL;
361       ansp += 8; /* type, class, TTL */
362       GETSHORT(rdlen, ansp);
363       if (!ADD_RDLEN(header, ansp, plen, rdlen))
364 	return NULL;
365     }
366 
367   return ansp;
368 }
369 
370 /* CRC the question section. This is used to safely detect query
371    retransmision and to detect answers to questions we didn't ask, which
372    might be poisoning attacks. Note that we decode the name rather
373    than CRC the raw bytes, since replies might be compressed differently.
374    We ignore case in the names for the same reason. Return all-ones
375    if there is not question section. */
questions_crc(HEADER * header,size_t plen,char * name)376 unsigned int questions_crc(HEADER *header, size_t plen, char *name)
377 {
378   int q;
379   unsigned int crc = 0xffffffff;
380   unsigned char *p1, *p = (unsigned char *)(header+1);
381 
382   for (q = ntohs(header->qdcount); q != 0; q--)
383     {
384       if (!extract_name(header, plen, &p, name, 1, 4))
385 	return crc; /* bad packet */
386 
387       for (p1 = (unsigned char *)name; *p1; p1++)
388 	{
389 	  int i = 8;
390 	  char c = *p1;
391 
392 	  if (c >= 'A' && c <= 'Z')
393 	    c += 'a' - 'A';
394 
395 	  crc ^= c << 24;
396 	  while (i--)
397 	    crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
398 	}
399 
400       /* CRC the class and type as well */
401       for (p1 = p; p1 < p+4; p1++)
402 	{
403 	  int i = 8;
404 	  crc ^= *p1 << 24;
405 	  while (i--)
406 	    crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
407 	}
408 
409       p += 4;
410       if (!CHECK_LEN(header, p, plen, 0))
411 	return crc; /* bad packet */
412     }
413 
414   return crc;
415 }
416 
417 
resize_packet(HEADER * header,size_t plen,unsigned char * pheader,size_t hlen)418 size_t resize_packet(HEADER *header, size_t plen, unsigned char *pheader, size_t hlen)
419 {
420   unsigned char *ansp = skip_questions(header, plen);
421 
422   /* if packet is malformed, just return as-is. */
423   if (!ansp)
424     return plen;
425 
426   if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
427 			    header, plen)))
428     return plen;
429 
430   /* restore pseudoheader */
431   if (pheader && ntohs(header->arcount) == 0)
432     {
433       /* must use memmove, may overlap */
434       memmove(ansp, pheader, hlen);
435       header->arcount = htons(1);
436       ansp += hlen;
437     }
438 
439   return ansp - (unsigned char *)header;
440 }
441 
find_pseudoheader(HEADER * header,size_t plen,size_t * len,unsigned char ** p,int * is_sign)442 unsigned char *find_pseudoheader(HEADER *header, size_t plen, size_t  *len, unsigned char **p, int *is_sign)
443 {
444   /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
445      also return length of pseudoheader in *len and pointer to the UDP size in *p
446      Finally, check to see if a packet is signed. If it is we cannot change a single bit before
447      forwarding. We look for SIG and TSIG in the addition section, and TKEY queries (for GSS-TSIG) */
448 
449   int i, arcount = ntohs(header->arcount);
450   unsigned char *ansp = (unsigned char *)(header+1);
451   unsigned short rdlen, type, class;
452   unsigned char *ret = NULL;
453 
454   if (is_sign)
455     {
456       *is_sign = 0;
457 
458       if (header->opcode == QUERY)
459 	{
460 	  for (i = ntohs(header->qdcount); i != 0; i--)
461 	    {
462 	      if (!(ansp = skip_name(ansp, header, plen, 4)))
463 		return NULL;
464 
465 	      GETSHORT(type, ansp);
466 	      GETSHORT(class, ansp);
467 
468 	      if (class == C_IN && type == T_TKEY)
469 		*is_sign = 1;
470 	    }
471 	}
472     }
473   else
474     {
475       if (!(ansp = skip_questions(header, plen)))
476 	return NULL;
477     }
478 
479   if (arcount == 0)
480     return NULL;
481 
482   if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount), header, plen)))
483     return NULL;
484 
485   for (i = 0; i < arcount; i++)
486     {
487       unsigned char *save, *start = ansp;
488       if (!(ansp = skip_name(ansp, header, plen, 10)))
489 	return NULL;
490 
491       GETSHORT(type, ansp);
492       save = ansp;
493       GETSHORT(class, ansp);
494       ansp += 4; /* TTL */
495       GETSHORT(rdlen, ansp);
496       if (!ADD_RDLEN(header, ansp, plen, rdlen))
497 	return NULL;
498       if (type == T_OPT)
499 	{
500 	  if (len)
501 	    *len = ansp - start;
502 	  if (p)
503 	    *p = save;
504 	  ret = start;
505 	}
506       else if (is_sign &&
507 	       i == arcount - 1 &&
508 	       class == C_ANY &&
509 	       (type == T_SIG || type == T_TSIG))
510 	*is_sign = 1;
511     }
512 
513   return ret;
514 }
515 
516 
517 /* is addr in the non-globally-routed IP space? */
private_net(struct in_addr addr)518 static int private_net(struct in_addr addr)
519 {
520   in_addr_t ip_addr = ntohl(addr.s_addr);
521 
522   return
523     ((ip_addr & 0xFF000000) == 0x7F000000)  /* 127.0.0.0/8    (loopback) */ ||
524     ((ip_addr & 0xFFFF0000) == 0xC0A80000)  /* 192.168.0.0/16 (private)  */ ||
525     ((ip_addr & 0xFF000000) == 0x0A000000)  /* 10.0.0.0/8     (private)  */ ||
526     ((ip_addr & 0xFFF00000) == 0xAC100000)  /* 172.16.0.0/12  (private)  */ ||
527     ((ip_addr & 0xFFFF0000) == 0xA9FE0000)  /* 169.254.0.0/16 (zeroconf) */ ;
528 }
529 
do_doctor(unsigned char * p,int count,HEADER * header,size_t qlen)530 static unsigned char *do_doctor(unsigned char *p, int count, HEADER *header, size_t qlen)
531 {
532   int i, qtype, qclass, rdlen;
533   unsigned long ttl;
534 
535   for (i = count; i != 0; i--)
536     {
537       if (!(p = skip_name(p, header, qlen, 10)))
538 	return 0; /* bad packet */
539 
540       GETSHORT(qtype, p);
541       GETSHORT(qclass, p);
542       GETLONG(ttl, p);
543       GETSHORT(rdlen, p);
544 
545       if ((qclass == C_IN) && (qtype == T_A))
546 	{
547 	  struct doctor *doctor;
548 	  struct in_addr addr;
549 
550 	  if (!CHECK_LEN(header, p, qlen, INADDRSZ))
551 	    return 0;
552 
553 	   /* alignment */
554 	  memcpy(&addr, p, INADDRSZ);
555 
556 	  for (doctor = daemon->doctors; doctor; doctor = doctor->next)
557 	    {
558 	      if (doctor->end.s_addr == 0)
559 		{
560 		  if (!is_same_net(doctor->in, addr, doctor->mask))
561 		    continue;
562 		}
563 	      else if (ntohl(doctor->in.s_addr) > ntohl(addr.s_addr) ||
564 		       ntohl(doctor->end.s_addr) < ntohl(addr.s_addr))
565 		continue;
566 
567 	      addr.s_addr &= ~doctor->mask.s_addr;
568 	      addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
569 	      /* Since we munged the data, the server it came from is no longer authoritative */
570 	      header->aa = 0;
571 	      memcpy(p, &addr, INADDRSZ);
572 	      break;
573 	    }
574 	}
575 
576       if (!ADD_RDLEN(header, p, qlen, rdlen))
577 	 return 0; /* bad packet */
578     }
579 
580   return p;
581 }
582 
find_soa(HEADER * header,size_t qlen)583 static int find_soa(HEADER *header, size_t qlen)
584 {
585   unsigned char *p;
586   int qtype, qclass, rdlen;
587   unsigned long ttl, minttl = ULONG_MAX;
588   int i, found_soa = 0;
589 
590   /* first move to NS section and find TTL from any SOA section */
591   if (!(p = skip_questions(header, qlen)) ||
592       !(p = do_doctor(p, ntohs(header->ancount), header, qlen)))
593     return 0;  /* bad packet */
594 
595   for (i = ntohs(header->nscount); i != 0; i--)
596     {
597       if (!(p = skip_name(p, header, qlen, 10)))
598 	return 0; /* bad packet */
599 
600       GETSHORT(qtype, p);
601       GETSHORT(qclass, p);
602       GETLONG(ttl, p);
603       GETSHORT(rdlen, p);
604 
605       if ((qclass == C_IN) && (qtype == T_SOA))
606 	{
607 	  found_soa = 1;
608 	  if (ttl < minttl)
609 	    minttl = ttl;
610 
611 	  /* MNAME */
612 	  if (!(p = skip_name(p, header, qlen, 0)))
613 	    return 0;
614 	  /* RNAME */
615 	  if (!(p = skip_name(p, header, qlen, 20)))
616 	    return 0;
617 	  p += 16; /* SERIAL REFRESH RETRY EXPIRE */
618 
619 	  GETLONG(ttl, p); /* minTTL */
620 	  if (ttl < minttl)
621 	    minttl = ttl;
622 	}
623       else if (!ADD_RDLEN(header, p, qlen, rdlen))
624 	return 0; /* bad packet */
625     }
626 
627   /* rewrite addresses in additioal section too */
628   if (!do_doctor(p, ntohs(header->arcount), header, qlen))
629     return 0;
630 
631   if (!found_soa)
632     minttl = daemon->neg_ttl;
633 
634   return minttl;
635 }
636 
637 /* Note that the following code can create CNAME chains that don't point to a real record,
638    either because of lack of memory, or lack of SOA records.  These are treated by the cache code as
639    expired and cleaned out that way.
640    Return 1 if we reject an address because it look like parct of dns-rebinding attack. */
extract_addresses(HEADER * header,size_t qlen,char * name,time_t now)641 int extract_addresses(HEADER *header, size_t qlen, char *name, time_t now)
642 {
643   unsigned char *p, *p1, *endrr, *namep;
644   int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
645   unsigned long ttl = 0;
646   struct all_addr addr;
647 
648   cache_start_insert();
649 
650   /* find_soa is needed for dns_doctor side-effects, so don't call it lazily if there are any. */
651   if (daemon->doctors)
652     {
653       searched_soa = 1;
654       ttl = find_soa(header, qlen);
655     }
656 
657   /* go through the questions. */
658   p = (unsigned char *)(header+1);
659 
660   for (i = ntohs(header->qdcount); i != 0; i--)
661     {
662       int found = 0, cname_count = 5;
663       struct crec *cpp = NULL;
664       int flags = header->rcode == NXDOMAIN ? F_NXDOMAIN : 0;
665       unsigned long cttl = ULONG_MAX, attl;
666 
667       namep = p;
668       if (!extract_name(header, qlen, &p, name, 1, 4))
669 	return 0; /* bad packet */
670 
671       GETSHORT(qtype, p);
672       GETSHORT(qclass, p);
673 
674       if (qclass != C_IN)
675 	continue;
676 
677       /* PTRs: we chase CNAMEs here, since we have no way to
678 	 represent them in the cache. */
679       if (qtype == T_PTR)
680 	{
681 	  int name_encoding = in_arpa_name_2_addr(name, &addr);
682 
683 	  if (!name_encoding)
684 	    continue;
685 
686 	  if (!(flags & F_NXDOMAIN))
687 	    {
688 	    cname_loop:
689 	      if (!(p1 = skip_questions(header, qlen)))
690 		return 0;
691 
692 	      for (j = ntohs(header->ancount); j != 0; j--)
693 		{
694 		  unsigned char *tmp = namep;
695 		  /* the loop body overwrites the original name, so get it back here. */
696 		  if (!extract_name(header, qlen, &tmp, name, 1, 0) ||
697 		      !(res = extract_name(header, qlen, &p1, name, 0, 10)))
698 		    return 0; /* bad packet */
699 
700 		  GETSHORT(aqtype, p1);
701 		  GETSHORT(aqclass, p1);
702 		  GETLONG(attl, p1);
703 		  GETSHORT(ardlen, p1);
704 		  endrr = p1+ardlen;
705 
706 		  /* TTL of record is minimum of CNAMES and PTR */
707 		  if (attl < cttl)
708 		    cttl = attl;
709 
710 		  if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
711 		    {
712 		      if (!extract_name(header, qlen, &p1, name, 1, 0))
713 			return 0;
714 
715 		      if (aqtype == T_CNAME)
716 			{
717 			  if (!cname_count--)
718 			    return 0; /* looped CNAMES */
719 			  goto cname_loop;
720 			}
721 
722 		      cache_insert(name, &addr, now, cttl, name_encoding | F_REVERSE);
723 		      found = 1;
724 		    }
725 
726 		  p1 = endrr;
727 		  if (!CHECK_LEN(header, p1, qlen, 0))
728 		    return 0; /* bad packet */
729 		}
730 	    }
731 
732 	   if (!found && !(daemon->options & OPT_NO_NEG))
733 	    {
734 	      if (!searched_soa)
735 		{
736 		  searched_soa = 1;
737 		  ttl = find_soa(header, qlen);
738 		}
739 	      if (ttl)
740 		cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags);
741 	    }
742 	}
743       else
744 	{
745 	  /* everything other than PTR */
746 	  struct crec *newc;
747 	  int addrlen;
748 
749 	  if (qtype == T_A)
750 	    {
751 	      addrlen = INADDRSZ;
752 	      flags |= F_IPV4;
753 	    }
754 #ifdef HAVE_IPV6
755 	  else if (qtype == T_AAAA)
756 	    {
757 	      addrlen = IN6ADDRSZ;
758 	      flags |= F_IPV6;
759 	    }
760 #endif
761 	  else
762 	    continue;
763 
764 	  if (!(flags & F_NXDOMAIN))
765 	    {
766 	    cname_loop1:
767 	      if (!(p1 = skip_questions(header, qlen)))
768 		return 0;
769 
770 	      for (j = ntohs(header->ancount); j != 0; j--)
771 		{
772 		  if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
773 		    return 0; /* bad packet */
774 
775 		  GETSHORT(aqtype, p1);
776 		  GETSHORT(aqclass, p1);
777 		  GETLONG(attl, p1);
778 		  GETSHORT(ardlen, p1);
779 		  endrr = p1+ardlen;
780 
781 		  if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
782 		    {
783 		      if (aqtype == T_CNAME)
784 			{
785 			  if (!cname_count--)
786 			    return 0; /* looped CNAMES */
787 			  newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD);
788 			  if (newc && cpp)
789 			    {
790 			      cpp->addr.cname.cache = newc;
791 			      cpp->addr.cname.uid = newc->uid;
792 			    }
793 
794 			  cpp = newc;
795 			  if (attl < cttl)
796 			    cttl = attl;
797 
798 			  if (!extract_name(header, qlen, &p1, name, 1, 0))
799 			    return 0;
800 			  goto cname_loop1;
801 			}
802 		      else
803 			{
804 			  found = 1;
805 
806 			  /* copy address into aligned storage */
807 			  if (!CHECK_LEN(header, p1, qlen, addrlen))
808 			    return 0; /* bad packet */
809 			  memcpy(&addr, p1, addrlen);
810 
811 			  /* check for returned address in private space */
812 			  if ((daemon->options & OPT_NO_REBIND) &&
813 			      (flags & F_IPV4) &&
814 			      private_net(addr.addr.addr4))
815 			    return 1;
816 
817 			  newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
818 			  if (newc && cpp)
819 			    {
820 			      cpp->addr.cname.cache = newc;
821 			      cpp->addr.cname.uid = newc->uid;
822 			    }
823 			  cpp = NULL;
824 			}
825 		    }
826 
827 		  p1 = endrr;
828 		  if (!CHECK_LEN(header, p1, qlen, 0))
829 		    return 0; /* bad packet */
830 		}
831 	    }
832 
833 	  if (!found && !(daemon->options & OPT_NO_NEG))
834 	    {
835 	      if (!searched_soa)
836 		{
837 		  searched_soa = 1;
838 		  ttl = find_soa(header, qlen);
839 		}
840 	      /* If there's no SOA to get the TTL from, but there is a CNAME
841 		 pointing at this, inherit its TTL */
842 	      if (ttl || cpp)
843 		{
844 		  newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags);
845 		  if (newc && cpp)
846 		    {
847 		      cpp->addr.cname.cache = newc;
848 		      cpp->addr.cname.uid = newc->uid;
849 		    }
850 		}
851 	    }
852 	}
853     }
854 
855   /* Don't put stuff from a truncated packet into the cache, but do everything else */
856   if (!header->tc)
857     cache_end_insert();
858 
859   return 0;
860 }
861 
862 /* If the packet holds exactly one query
863    return F_IPV4 or F_IPV6  and leave the name from the query in name.
864    Abuse F_BIGNAME to indicate an NS query - yuck. */
865 
extract_request(HEADER * header,size_t qlen,char * name,unsigned short * typep)866 unsigned short extract_request(HEADER *header, size_t qlen, char *name, unsigned short *typep)
867 {
868   unsigned char *p = (unsigned char *)(header+1);
869   int qtype, qclass;
870 
871   if (typep)
872     *typep = 0;
873 
874   if (ntohs(header->qdcount) != 1 || header->opcode != QUERY)
875     return 0; /* must be exactly one query. */
876 
877   if (!extract_name(header, qlen, &p, name, 1, 4))
878     return 0; /* bad packet */
879 
880   GETSHORT(qtype, p);
881   GETSHORT(qclass, p);
882 
883   if (typep)
884     *typep = qtype;
885 
886   if (qclass == C_IN)
887     {
888       if (qtype == T_A)
889 	return F_IPV4;
890       if (qtype == T_AAAA)
891 	return F_IPV6;
892       if (qtype == T_ANY)
893 	return  F_IPV4 | F_IPV6;
894       if (qtype == T_NS || qtype == T_SOA)
895 	return F_QUERY | F_BIGNAME;
896     }
897 
898   return F_QUERY;
899 }
900 
901 
setup_reply(HEADER * header,size_t qlen,struct all_addr * addrp,unsigned short flags,unsigned long ttl)902 size_t setup_reply(HEADER *header, size_t qlen,
903 		struct all_addr *addrp, unsigned short flags, unsigned long ttl)
904 {
905   unsigned char *p = skip_questions(header, qlen);
906 
907   header->qr = 1; /* response */
908   header->aa = 0; /* authoritive */
909   header->ra = 1; /* recursion if available */
910   header->tc = 0; /* not truncated */
911   header->nscount = htons(0);
912   header->arcount = htons(0);
913   header->ancount = htons(0); /* no answers unless changed below */
914   if (flags == F_NEG)
915     header->rcode = SERVFAIL; /* couldn't get memory */
916   else if (flags == F_NOERR)
917     header->rcode = NOERROR; /* empty domain */
918   else if (flags == F_NXDOMAIN)
919     header->rcode = NXDOMAIN;
920   else if (p && flags == F_IPV4)
921     { /* we know the address */
922       header->rcode = NOERROR;
923       header->ancount = htons(1);
924       header->aa = 1;
925       add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_A, C_IN, "4", addrp);
926     }
927 #ifdef HAVE_IPV6
928   else if (p && flags == F_IPV6)
929     {
930       header->rcode = NOERROR;
931       header->ancount = htons(1);
932       header->aa = 1;
933       add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
934     }
935 #endif
936   else /* nowhere to forward to */
937     header->rcode = REFUSED;
938 
939   return p - (unsigned char *)header;
940 }
941 
942 /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
check_for_local_domain(char * name,time_t now)943 int check_for_local_domain(char *name, time_t now)
944 {
945   struct crec *crecp;
946   struct mx_srv_record *mx;
947   struct txt_record *txt;
948   struct interface_name *intr;
949   struct ptr_record *ptr;
950 
951   if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)) &&
952       (crecp->flags & (F_HOSTS | F_DHCP)))
953     return 1;
954 
955   for (mx = daemon->mxnames; mx; mx = mx->next)
956     if (hostname_isequal(name, mx->name))
957       return 1;
958 
959   for (txt = daemon->txt; txt; txt = txt->next)
960     if (hostname_isequal(name, txt->name))
961       return 1;
962 
963   for (intr = daemon->int_names; intr; intr = intr->next)
964     if (hostname_isequal(name, intr->name))
965       return 1;
966 
967   for (ptr = daemon->ptr; ptr; ptr = ptr->next)
968     if (hostname_isequal(name, ptr->name))
969       return 1;
970 
971   return 0;
972 }
973 
974 /* Is the packet a reply with the answer address equal to addr?
975    If so mung is into an NXDOMAIN reply and also put that information
976    in the cache. */
check_for_bogus_wildcard(HEADER * header,size_t qlen,char * name,struct bogus_addr * baddr,time_t now)977 int check_for_bogus_wildcard(HEADER *header, size_t qlen, char *name,
978 			     struct bogus_addr *baddr, time_t now)
979 {
980   unsigned char *p;
981   int i, qtype, qclass, rdlen;
982   unsigned long ttl;
983   struct bogus_addr *baddrp;
984 
985   /* skip over questions */
986   if (!(p = skip_questions(header, qlen)))
987     return 0; /* bad packet */
988 
989   for (i = ntohs(header->ancount); i != 0; i--)
990     {
991       if (!extract_name(header, qlen, &p, name, 1, 10))
992 	return 0; /* bad packet */
993 
994       GETSHORT(qtype, p);
995       GETSHORT(qclass, p);
996       GETLONG(ttl, p);
997       GETSHORT(rdlen, p);
998 
999       if (qclass == C_IN && qtype == T_A)
1000 	{
1001 	  if (!CHECK_LEN(header, p, qlen, INADDRSZ))
1002 	    return 0;
1003 
1004 	  for (baddrp = baddr; baddrp; baddrp = baddrp->next)
1005 	    if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
1006 	      {
1007 		/* Found a bogus address. Insert that info here, since there no SOA record
1008 		   to get the ttl from in the normal processing */
1009 		cache_start_insert();
1010 		cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN | F_CONFIG);
1011 		cache_end_insert();
1012 
1013 		return 1;
1014 	      }
1015 	}
1016 
1017       if (!ADD_RDLEN(header, p, qlen, rdlen))
1018 	return 0;
1019     }
1020 
1021   return 0;
1022 }
1023 
add_resource_record(HEADER * header,char * limit,int * truncp,unsigned int nameoffset,unsigned char ** pp,unsigned long ttl,unsigned int * offset,unsigned short type,unsigned short class,char * format,...)1024 static int add_resource_record(HEADER *header, char *limit, int *truncp, unsigned int nameoffset, unsigned char **pp,
1025 			       unsigned long ttl, unsigned int *offset, unsigned short type, unsigned short class, char *format, ...)
1026 {
1027   va_list ap;
1028   unsigned char *sav, *p = *pp;
1029   int j;
1030   unsigned short usval;
1031   long lval;
1032   char *sval;
1033 
1034   if (truncp && *truncp)
1035     return 0;
1036 
1037   PUTSHORT(nameoffset | 0xc000, p);
1038   PUTSHORT(type, p);
1039   PUTSHORT(class, p);
1040   PUTLONG(ttl, p);      /* TTL */
1041 
1042   sav = p;              /* Save pointer to RDLength field */
1043   PUTSHORT(0, p);       /* Placeholder RDLength */
1044 
1045   va_start(ap, format);   /* make ap point to 1st unamed argument */
1046 
1047   for (; *format; format++)
1048     switch (*format)
1049       {
1050 #ifdef HAVE_IPV6
1051       case '6':
1052 	sval = va_arg(ap, char *);
1053 	memcpy(p, sval, IN6ADDRSZ);
1054 	p += IN6ADDRSZ;
1055 	break;
1056 #endif
1057 
1058       case '4':
1059 	sval = va_arg(ap, char *);
1060 	memcpy(p, sval, INADDRSZ);
1061 	p += INADDRSZ;
1062 	break;
1063 
1064       case 's':
1065 	usval = va_arg(ap, int);
1066 	PUTSHORT(usval, p);
1067 	break;
1068 
1069       case 'l':
1070 	lval = va_arg(ap, long);
1071 	PUTLONG(lval, p);
1072 	break;
1073 
1074       case 'd':
1075 	/* get domain-name answer arg and store it in RDATA field */
1076 	if (offset)
1077 	  *offset = p - (unsigned char *)header;
1078 	p = do_rfc1035_name(p, va_arg(ap, char *));
1079 	*p++ = 0;
1080 	break;
1081 
1082       case 't':
1083 	usval = va_arg(ap, int);
1084 	sval = va_arg(ap, char *);
1085 	memcpy(p, sval, usval);
1086 	p += usval;
1087 	break;
1088 
1089       case 'z':
1090 	sval = va_arg(ap, char *);
1091 	usval = sval ? strlen(sval) : 0;
1092 	if (usval > 255)
1093 	  usval = 255;
1094 	*p++ = (unsigned char)usval;
1095 	memcpy(p, sval, usval);
1096 	p += usval;
1097 	break;
1098       }
1099 
1100   va_end(ap);	/* clean up variable argument pointer */
1101 
1102   j = p - sav - 2;
1103   PUTSHORT(j, sav);     /* Now, store real RDLength */
1104 
1105   /* check for overflow of buffer */
1106   if (limit && ((unsigned char *)limit - p) < 0)
1107     {
1108       if (truncp)
1109 	*truncp = 1;
1110       return 0;
1111     }
1112 
1113   *pp = p;
1114   return 1;
1115 }
1116 
crec_ttl(struct crec * crecp,time_t now)1117 static unsigned long crec_ttl(struct crec *crecp, time_t now)
1118 {
1119   /* Return 0 ttl for DHCP entries, which might change
1120      before the lease expires. */
1121 
1122   if  (crecp->flags & (F_IMMORTAL | F_DHCP))
1123     return daemon->local_ttl;
1124 
1125   return crecp->ttd - now;
1126 }
1127 
1128 
1129 /* return zero if we can't answer from cache, or packet size if we can */
answer_request(HEADER * header,char * limit,size_t qlen,struct in_addr local_addr,struct in_addr local_netmask,time_t now)1130 size_t answer_request(HEADER *header, char *limit, size_t qlen,
1131 		      struct in_addr local_addr, struct in_addr local_netmask, time_t now)
1132 {
1133   char *name = daemon->namebuff;
1134   unsigned char *p, *ansp, *pheader;
1135   int qtype, qclass;
1136   struct all_addr addr;
1137   unsigned int nameoffset;
1138   unsigned short flag;
1139   int q, ans, anscount = 0, addncount = 0;
1140   int dryrun = 0, sec_reqd = 0;
1141   int is_sign;
1142   struct crec *crecp;
1143   int nxdomain = 0, auth = 1, trunc = 0;
1144   struct mx_srv_record *rec;
1145 
1146   // Make sure we do not underflow here too.
1147   if (qlen > (size_t)(limit - ((char *)header))) return 0;
1148 
1149   /* If there is an RFC2671 pseudoheader then it will be overwritten by
1150      partial replies, so we have to do a dry run to see if we can answer
1151      the query. We check to see if the do bit is set, if so we always
1152      forward rather than answering from the cache, which doesn't include
1153      security information. */
1154 
1155   if (find_pseudoheader(header, qlen, NULL, &pheader, &is_sign))
1156     {
1157       unsigned short udpsz, ext_rcode, flags;
1158       unsigned char *psave = pheader;
1159 
1160       GETSHORT(udpsz, pheader);
1161       GETSHORT(ext_rcode, pheader);
1162       GETSHORT(flags, pheader);
1163 
1164       sec_reqd = flags & 0x8000; /* do bit */
1165 
1166       /* If our client is advertising a larger UDP packet size
1167 	 than we allow, trim it so that we don't get an overlarge
1168 	 response from upstream */
1169 
1170       if (!is_sign && (udpsz > daemon->edns_pktsz))
1171 	PUTSHORT(daemon->edns_pktsz, psave);
1172 
1173       dryrun = 1;
1174     }
1175 
1176   if (ntohs(header->qdcount) == 0 || header->opcode != QUERY )
1177     return 0;
1178 
1179   for (rec = daemon->mxnames; rec; rec = rec->next)
1180     rec->offset = 0;
1181 
1182  rerun:
1183   /* determine end of question section (we put answers there) */
1184   if (!(ansp = skip_questions(header, qlen)))
1185     return 0; /* bad packet */
1186 
1187   /* now process each question, answers go in RRs after the question */
1188   p = (unsigned char *)(header+1);
1189 
1190   for (q = ntohs(header->qdcount); q != 0; q--)
1191     {
1192       /* save pointer to name for copying into answers */
1193       nameoffset = p - (unsigned char *)header;
1194 
1195       /* now extract name as .-concatenated string into name */
1196       if (!extract_name(header, qlen, &p, name, 1, 4))
1197 	return 0; /* bad packet */
1198 
1199       GETSHORT(qtype, p);
1200       GETSHORT(qclass, p);
1201 
1202       ans = 0; /* have we answered this question */
1203 
1204       if (qtype == T_TXT || qtype == T_ANY)
1205 	{
1206 	  struct txt_record *t;
1207 	  for(t = daemon->txt; t ; t = t->next)
1208 	    {
1209 	      if (t->class == qclass && hostname_isequal(name, t->name))
1210 		{
1211 		  ans = 1;
1212 		  if (!dryrun)
1213 		    {
1214 		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<TXT>");
1215 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1216 					      daemon->local_ttl, NULL,
1217 					      T_TXT, t->class, "t", t->len, t->txt))
1218 			anscount++;
1219 
1220 		    }
1221 		}
1222 	    }
1223 	}
1224 
1225       if (qclass == C_IN)
1226 	{
1227 	  if (qtype == T_PTR || qtype == T_ANY)
1228 	    {
1229 	      /* see if it's w.z.y.z.in-addr.arpa format */
1230 	      int is_arpa = in_arpa_name_2_addr(name, &addr);
1231 	      struct ptr_record *ptr;
1232 	      struct interface_name* intr = NULL;
1233 
1234 	      for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1235 		if (hostname_isequal(name, ptr->name))
1236 		  break;
1237 
1238 	      if (is_arpa == F_IPV4)
1239 		for (intr = daemon->int_names; intr; intr = intr->next)
1240 		  {
1241 		    if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr)
1242 		      break;
1243 		    else
1244 		      while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1245 			intr = intr->next;
1246 		  }
1247 
1248 	      if (intr)
1249 		{
1250 		  ans = 1;
1251 		  if (!dryrun)
1252 		    {
1253 		      log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
1254 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1255 					      daemon->local_ttl, NULL,
1256 					      T_PTR, C_IN, "d", intr->name))
1257 			anscount++;
1258 		    }
1259 		}
1260 	      else if (ptr)
1261 		{
1262 		  ans = 1;
1263 		  if (!dryrun)
1264 		    {
1265 		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<PTR>");
1266 		      for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1267 			if (hostname_isequal(name, ptr->name) &&
1268 			    add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1269 						daemon->local_ttl, NULL,
1270 						T_PTR, C_IN, "d", ptr->ptr))
1271 			  anscount++;
1272 
1273 		    }
1274 		}
1275 	      else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
1276 		do
1277 		  {
1278 		    /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
1279 		    if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1280 		      continue;
1281 
1282 		    if (crecp->flags & F_NEG)
1283 		      {
1284 			ans = 1;
1285 			auth = 0;
1286 			if (crecp->flags & F_NXDOMAIN)
1287 			  nxdomain = 1;
1288 			if (!dryrun)
1289 			  log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
1290 		      }
1291 		    else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
1292 		      {
1293 			ans = 1;
1294 			if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1295 			  auth = 0;
1296 			if (!dryrun)
1297 			  {
1298 			    log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
1299 				      record_source(crecp->uid));
1300 
1301 			    if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1302 						    crec_ttl(crecp, now), NULL,
1303 						    T_PTR, C_IN, "d", cache_get_name(crecp)))
1304 			      anscount++;
1305 			  }
1306 		      }
1307 		  } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
1308 	      else if (is_arpa == F_IPV4 &&
1309 		       (daemon->options & OPT_BOGUSPRIV) &&
1310 		       private_net(addr.addr.addr4))
1311 		{
1312 		  /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
1313 		  ans = 1;
1314 		  nxdomain = 1;
1315 		  if (!dryrun)
1316 		    log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN,
1317 			      name, &addr, NULL);
1318 		}
1319 	    }
1320 
1321 	  for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
1322 	    {
1323 	      unsigned short type = T_A;
1324 
1325 	      if (flag == F_IPV6)
1326 #ifdef HAVE_IPV6
1327 		type = T_AAAA;
1328 #else
1329 	        break;
1330 #endif
1331 
1332 	      if (qtype != type && qtype != T_ANY)
1333 		continue;
1334 
1335 	      /* Check for "A for A"  queries */
1336 	      if (qtype == T_A && (addr.addr.addr4.s_addr = inet_addr(name)) != (in_addr_t) -1)
1337 		{
1338 		  ans = 1;
1339 		  if (!dryrun)
1340 		    {
1341 		      log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
1342 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1343 					      daemon->local_ttl, NULL, type, C_IN, "4", &addr))
1344 			anscount++;
1345 		    }
1346 		  continue;
1347 		}
1348 
1349 	      /* interface name stuff */
1350 	      if (qtype == T_A)
1351 		{
1352 		  struct interface_name *intr;
1353 
1354 		  for (intr = daemon->int_names; intr; intr = intr->next)
1355 		    if (hostname_isequal(name, intr->name))
1356 		      break;
1357 
1358 		  if (intr)
1359 		    {
1360 		      ans = 1;
1361 		      if (!dryrun)
1362 			{
1363 			  if ((addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr == (in_addr_t) -1)
1364 			    log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, NULL);
1365 			  else
1366 			    {
1367 			      log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
1368 			      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1369 						      daemon->local_ttl, NULL, type, C_IN, "4", &addr))
1370 				anscount++;
1371 			    }
1372 			}
1373 		      continue;
1374 		    }
1375 		}
1376 
1377 	    cname_restart:
1378 	      if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME)))
1379 		{
1380 		  int localise = 0;
1381 
1382 		  /* See if a putative address is on the network from which we recieved
1383 		     the query, is so we'll filter other answers. */
1384 		  if (local_addr.s_addr != 0 && (daemon->options & OPT_LOCALISE) && flag == F_IPV4)
1385 		    {
1386 		      struct crec *save = crecp;
1387 		      do {
1388 			if ((crecp->flags & F_HOSTS) &&
1389 			    is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1390 			  {
1391 			    localise = 1;
1392 			    break;
1393 			  }
1394 			} while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
1395 		      crecp = save;
1396 		    }
1397 
1398 		  do
1399 		    {
1400 		      /* don't answer wildcard queries with data not from /etc/hosts
1401 			 or DHCP leases */
1402 		      if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1403 			break;
1404 
1405 		      if (crecp->flags & F_CNAME)
1406 			{
1407 			  if (!dryrun)
1408 			    {
1409 			      log_query(crecp->flags, name, NULL, record_source(crecp->uid));
1410 			      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1411 						      crec_ttl(crecp, now), &nameoffset,
1412 						      T_CNAME, C_IN, "d", cache_get_name(crecp->addr.cname.cache)))
1413 				anscount++;
1414 			    }
1415 
1416 			  strcpy(name, cache_get_name(crecp->addr.cname.cache));
1417 			  goto cname_restart;
1418 			}
1419 
1420 		      if (crecp->flags & F_NEG)
1421 			{
1422 			  ans = 1;
1423 			  auth = 0;
1424 			  if (crecp->flags & F_NXDOMAIN)
1425 			    nxdomain = 1;
1426 			  if (!dryrun)
1427 			    log_query(crecp->flags, name, NULL, NULL);
1428 			}
1429 		      else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
1430 			{
1431 			  /* If we are returning local answers depending on network,
1432 			     filter here. */
1433 			  if (localise &&
1434 			      (crecp->flags & F_HOSTS) &&
1435 			      !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1436 			    continue;
1437 
1438 			  if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1439 			    auth = 0;
1440 
1441 			  ans = 1;
1442 			  if (!dryrun)
1443 			    {
1444 			      log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
1445 					record_source(crecp->uid));
1446 
1447 			      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1448 						      crec_ttl(crecp, now), NULL, type, C_IN,
1449 						      type == T_A ? "4" : "6", &crecp->addr))
1450 				anscount++;
1451 			    }
1452 			}
1453 		    } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
1454 		}
1455 	    }
1456 
1457 	  if (qtype == T_MX || qtype == T_ANY)
1458 	    {
1459 	      int found = 0;
1460 	      for (rec = daemon->mxnames; rec; rec = rec->next)
1461 		if (!rec->issrv && hostname_isequal(name, rec->name))
1462 		  {
1463 		  ans = found = 1;
1464 		  if (!dryrun)
1465 		    {
1466 		      unsigned int offset;
1467 		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>");
1468 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1469 					      &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
1470 			{
1471 			  anscount++;
1472 			  if (rec->target)
1473 			    rec->offset = offset;
1474 			}
1475 		    }
1476 		  }
1477 
1478 	      if (!found && (daemon->options & (OPT_SELFMX | OPT_LOCALMX)) &&
1479 		  cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP))
1480 		{
1481 		  ans = 1;
1482 		  if (!dryrun)
1483 		    {
1484 		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>");
1485 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
1486 					      T_MX, C_IN, "sd", 1,
1487 					      (daemon->options & OPT_SELFMX) ? name : daemon->mxtarget))
1488 			anscount++;
1489 		    }
1490 		}
1491 	    }
1492 
1493 	  if (qtype == T_SRV || qtype == T_ANY)
1494 	    {
1495 	      int found = 0;
1496 
1497 	      for (rec = daemon->mxnames; rec; rec = rec->next)
1498 		if (rec->issrv && hostname_isequal(name, rec->name))
1499 		  {
1500 		    found = ans = 1;
1501 		    if (!dryrun)
1502 		      {
1503 			unsigned int offset;
1504 			log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<SRV>");
1505 			if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1506 						&offset, T_SRV, C_IN, "sssd",
1507 						rec->priority, rec->weight, rec->srvport, rec->target))
1508 			  {
1509 			    anscount++;
1510 			    if (rec->target)
1511 			      rec->offset = offset;
1512 			  }
1513 		      }
1514 		  }
1515 
1516 	      if (!found && (daemon->options & OPT_FILTER) &&  (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
1517 		{
1518 		  ans = 1;
1519 		  if (!dryrun)
1520 		    log_query(F_CONFIG | F_NEG, name, NULL, NULL);
1521 		}
1522 	    }
1523 
1524 	  if (qtype == T_NAPTR || qtype == T_ANY)
1525 	    {
1526 	      struct naptr *na;
1527 	      for (na = daemon->naptr; na; na = na->next)
1528 		if (hostname_isequal(name, na->name))
1529 		  {
1530 		    ans = 1;
1531 		    if (!dryrun)
1532 		      {
1533 			log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<NAPTR>");
1534 			if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1535 						NULL, T_NAPTR, C_IN, "sszzzd",
1536 						na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
1537 			  anscount++;
1538 		      }
1539 		  }
1540 	    }
1541 
1542 	  if (qtype == T_MAILB)
1543 	    ans = 1, nxdomain = 1;
1544 
1545 	  if (qtype == T_SOA && (daemon->options & OPT_FILTER))
1546 	    {
1547 	      ans = 1;
1548 	      if (!dryrun)
1549 		log_query(F_CONFIG | F_NEG, name, &addr, NULL);
1550 	    }
1551 	}
1552 
1553       if (!ans)
1554 	return 0; /* failed to answer a question */
1555     }
1556 
1557   if (dryrun)
1558     {
1559       dryrun = 0;
1560       goto rerun;
1561     }
1562 
1563   /* create an additional data section, for stuff in SRV and MX record replies. */
1564   for (rec = daemon->mxnames; rec; rec = rec->next)
1565     if (rec->offset != 0)
1566       {
1567 	/* squash dupes */
1568 	struct mx_srv_record *tmp;
1569 	for (tmp = rec->next; tmp; tmp = tmp->next)
1570 	  if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
1571 	    tmp->offset = 0;
1572 
1573 	crecp = NULL;
1574 	while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
1575 	  {
1576 #ifdef HAVE_IPV6
1577 	    int type =  crecp->flags & F_IPV4 ? T_A : T_AAAA;
1578 #else
1579 	    int type = T_A;
1580 #endif
1581 	    if (crecp->flags & F_NEG)
1582 	      continue;
1583 
1584 	    if (add_resource_record(header, limit, NULL, rec->offset, &ansp,
1585 				    crec_ttl(crecp, now), NULL, type, C_IN,
1586 				    crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
1587 	      addncount++;
1588 	  }
1589       }
1590 
1591   /* done all questions, set up header and return length of result */
1592   header->qr = 1; /* response */
1593   header->aa = auth; /* authoritive - only hosts and DHCP derived names. */
1594   header->ra = 1; /* recursion if available */
1595   header->tc = trunc; /* truncation */
1596   if (anscount == 0 && nxdomain)
1597     header->rcode = NXDOMAIN;
1598   else
1599     header->rcode = NOERROR; /* no error */
1600   header->ancount = htons(anscount);
1601   header->nscount = htons(0);
1602   header->arcount = htons(addncount);
1603   return ansp - (unsigned char *)header;
1604 }
1605 
1606 
1607 
1608 
1609 
1610