Home | History | Annotate | Download | only in src
      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 
     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
    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 
    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 
    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 
    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. */
    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 
    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 
    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? */
    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 
    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 
    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. */
    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 
    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 
    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;
    906 
    907   if (!(p = skip_questions(header, qlen)))
    908     return 0;
    909 
    910   header->qr = 1; /* response */
    911   header->aa = 0; /* authoritive */
    912   header->ra = 1; /* recursion if available */
    913   header->tc = 0; /* not truncated */
    914   header->nscount = htons(0);
    915   header->arcount = htons(0);
    916   header->ancount = htons(0); /* no answers unless changed below */
    917   if (flags == F_NEG)
    918     header->rcode = SERVFAIL; /* couldn't get memory */
    919   else if (flags == F_NOERR)
    920     header->rcode = NOERROR; /* empty domain */
    921   else if (flags == F_NXDOMAIN)
    922     header->rcode = NXDOMAIN;
    923   else if (flags == F_IPV4)
    924     { /* we know the address */
    925       header->rcode = NOERROR;
    926       header->ancount = htons(1);
    927       header->aa = 1;
    928       add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_A, C_IN, "4", addrp);
    929     }
    930 #ifdef HAVE_IPV6
    931   else if (flags == F_IPV6)
    932     {
    933       header->rcode = NOERROR;
    934       header->ancount = htons(1);
    935       header->aa = 1;
    936       add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
    937     }
    938 #endif
    939   else /* nowhere to forward to */
    940     header->rcode = REFUSED;
    941 
    942   return p - (unsigned char *)header;
    943 }
    944 
    945 /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
    946 int check_for_local_domain(char *name, time_t now)
    947 {
    948   struct crec *crecp;
    949   struct mx_srv_record *mx;
    950   struct txt_record *txt;
    951   struct interface_name *intr;
    952   struct ptr_record *ptr;
    953 
    954   if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)) &&
    955       (crecp->flags & (F_HOSTS | F_DHCP)))
    956     return 1;
    957 
    958   for (mx = daemon->mxnames; mx; mx = mx->next)
    959     if (hostname_isequal(name, mx->name))
    960       return 1;
    961 
    962   for (txt = daemon->txt; txt; txt = txt->next)
    963     if (hostname_isequal(name, txt->name))
    964       return 1;
    965 
    966   for (intr = daemon->int_names; intr; intr = intr->next)
    967     if (hostname_isequal(name, intr->name))
    968       return 1;
    969 
    970   for (ptr = daemon->ptr; ptr; ptr = ptr->next)
    971     if (hostname_isequal(name, ptr->name))
    972       return 1;
    973 
    974   return 0;
    975 }
    976 
    977 /* Is the packet a reply with the answer address equal to addr?
    978    If so mung is into an NXDOMAIN reply and also put that information
    979    in the cache. */
    980 int check_for_bogus_wildcard(HEADER *header, size_t qlen, char *name,
    981 			     struct bogus_addr *baddr, time_t now)
    982 {
    983   unsigned char *p;
    984   int i, qtype, qclass, rdlen;
    985   unsigned long ttl;
    986   struct bogus_addr *baddrp;
    987 
    988   /* skip over questions */
    989   if (!(p = skip_questions(header, qlen)))
    990     return 0; /* bad packet */
    991 
    992   for (i = ntohs(header->ancount); i != 0; i--)
    993     {
    994       if (!extract_name(header, qlen, &p, name, 1, 10))
    995 	return 0; /* bad packet */
    996 
    997       GETSHORT(qtype, p);
    998       GETSHORT(qclass, p);
    999       GETLONG(ttl, p);
   1000       GETSHORT(rdlen, p);
   1001 
   1002       if (qclass == C_IN && qtype == T_A)
   1003 	{
   1004 	  if (!CHECK_LEN(header, p, qlen, INADDRSZ))
   1005 	    return 0;
   1006 
   1007 	  for (baddrp = baddr; baddrp; baddrp = baddrp->next)
   1008 	    if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
   1009 	      {
   1010 		/* Found a bogus address. Insert that info here, since there no SOA record
   1011 		   to get the ttl from in the normal processing */
   1012 		cache_start_insert();
   1013 		cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN | F_CONFIG);
   1014 		cache_end_insert();
   1015 
   1016 		return 1;
   1017 	      }
   1018 	}
   1019 
   1020       if (!ADD_RDLEN(header, p, qlen, rdlen))
   1021 	return 0;
   1022     }
   1023 
   1024   return 0;
   1025 }
   1026 
   1027 static int add_resource_record(HEADER *header, char *limit, int *truncp, unsigned int nameoffset, unsigned char **pp,
   1028 			       unsigned long ttl, unsigned int *offset, unsigned short type, unsigned short class, char *format, ...)
   1029 {
   1030   va_list ap;
   1031   unsigned char *sav, *p = *pp;
   1032   int j;
   1033   unsigned short usval;
   1034   long lval;
   1035   char *sval;
   1036 
   1037   if (truncp && *truncp)
   1038     return 0;
   1039 
   1040   PUTSHORT(nameoffset | 0xc000, p);
   1041   PUTSHORT(type, p);
   1042   PUTSHORT(class, p);
   1043   PUTLONG(ttl, p);      /* TTL */
   1044 
   1045   sav = p;              /* Save pointer to RDLength field */
   1046   PUTSHORT(0, p);       /* Placeholder RDLength */
   1047 
   1048   va_start(ap, format);   /* make ap point to 1st unamed argument */
   1049 
   1050   for (; *format; format++)
   1051     switch (*format)
   1052       {
   1053 #ifdef HAVE_IPV6
   1054       case '6':
   1055 	sval = va_arg(ap, char *);
   1056 	memcpy(p, sval, IN6ADDRSZ);
   1057 	p += IN6ADDRSZ;
   1058 	break;
   1059 #endif
   1060 
   1061       case '4':
   1062 	sval = va_arg(ap, char *);
   1063 	memcpy(p, sval, INADDRSZ);
   1064 	p += INADDRSZ;
   1065 	break;
   1066 
   1067       case 's':
   1068 	usval = va_arg(ap, int);
   1069 	PUTSHORT(usval, p);
   1070 	break;
   1071 
   1072       case 'l':
   1073 	lval = va_arg(ap, long);
   1074 	PUTLONG(lval, p);
   1075 	break;
   1076 
   1077       case 'd':
   1078 	/* get domain-name answer arg and store it in RDATA field */
   1079 	if (offset)
   1080 	  *offset = p - (unsigned char *)header;
   1081 	p = do_rfc1035_name(p, va_arg(ap, char *));
   1082 	*p++ = 0;
   1083 	break;
   1084 
   1085       case 't':
   1086 	usval = va_arg(ap, int);
   1087 	sval = va_arg(ap, char *);
   1088 	memcpy(p, sval, usval);
   1089 	p += usval;
   1090 	break;
   1091 
   1092       case 'z':
   1093 	sval = va_arg(ap, char *);
   1094 	usval = sval ? strlen(sval) : 0;
   1095 	if (usval > 255)
   1096 	  usval = 255;
   1097 	*p++ = (unsigned char)usval;
   1098 	memcpy(p, sval, usval);
   1099 	p += usval;
   1100 	break;
   1101       }
   1102 
   1103   va_end(ap);	/* clean up variable argument pointer */
   1104 
   1105   j = p - sav - 2;
   1106   PUTSHORT(j, sav);     /* Now, store real RDLength */
   1107 
   1108   /* check for overflow of buffer */
   1109   if (limit && ((unsigned char *)limit - p) < 0)
   1110     {
   1111       if (truncp)
   1112 	*truncp = 1;
   1113       return 0;
   1114     }
   1115 
   1116   *pp = p;
   1117   return 1;
   1118 }
   1119 
   1120 static unsigned long crec_ttl(struct crec *crecp, time_t now)
   1121 {
   1122   /* Return 0 ttl for DHCP entries, which might change
   1123      before the lease expires. */
   1124 
   1125   if  (crecp->flags & (F_IMMORTAL | F_DHCP))
   1126     return daemon->local_ttl;
   1127 
   1128   return crecp->ttd - now;
   1129 }
   1130 
   1131 
   1132 /* return zero if we can't answer from cache, or packet size if we can */
   1133 size_t answer_request(HEADER *header, char *limit, size_t qlen,
   1134 		      struct in_addr local_addr, struct in_addr local_netmask, time_t now)
   1135 {
   1136   char *name = daemon->namebuff;
   1137   unsigned char *p, *ansp, *pheader;
   1138   int qtype, qclass;
   1139   struct all_addr addr;
   1140   unsigned int nameoffset;
   1141   unsigned short flag;
   1142   int q, ans, anscount = 0, addncount = 0;
   1143   int dryrun = 0, sec_reqd = 0;
   1144   int is_sign;
   1145   struct crec *crecp;
   1146   int nxdomain = 0, auth = 1, trunc = 0;
   1147   struct mx_srv_record *rec;
   1148 
   1149   // Make sure we do not underflow here too.
   1150   if (qlen > (size_t)(limit - ((char *)header))) return 0;
   1151 
   1152   /* If there is an RFC2671 pseudoheader then it will be overwritten by
   1153      partial replies, so we have to do a dry run to see if we can answer
   1154      the query. We check to see if the do bit is set, if so we always
   1155      forward rather than answering from the cache, which doesn't include
   1156      security information. */
   1157 
   1158   if (find_pseudoheader(header, qlen, NULL, &pheader, &is_sign))
   1159     {
   1160       unsigned short udpsz, ext_rcode, flags;
   1161       unsigned char *psave = pheader;
   1162 
   1163       GETSHORT(udpsz, pheader);
   1164       GETSHORT(ext_rcode, pheader);
   1165       GETSHORT(flags, pheader);
   1166 
   1167       sec_reqd = flags & 0x8000; /* do bit */
   1168 
   1169       /* If our client is advertising a larger UDP packet size
   1170 	 than we allow, trim it so that we don't get an overlarge
   1171 	 response from upstream */
   1172 
   1173       if (!is_sign && (udpsz > daemon->edns_pktsz))
   1174 	PUTSHORT(daemon->edns_pktsz, psave);
   1175 
   1176       dryrun = 1;
   1177     }
   1178 
   1179   if (ntohs(header->qdcount) == 0 || header->opcode != QUERY )
   1180     return 0;
   1181 
   1182   for (rec = daemon->mxnames; rec; rec = rec->next)
   1183     rec->offset = 0;
   1184 
   1185  rerun:
   1186   /* determine end of question section (we put answers there) */
   1187   if (!(ansp = skip_questions(header, qlen)))
   1188     return 0; /* bad packet */
   1189 
   1190   /* now process each question, answers go in RRs after the question */
   1191   p = (unsigned char *)(header+1);
   1192 
   1193   for (q = ntohs(header->qdcount); q != 0; q--)
   1194     {
   1195       /* save pointer to name for copying into answers */
   1196       nameoffset = p - (unsigned char *)header;
   1197 
   1198       /* now extract name as .-concatenated string into name */
   1199       if (!extract_name(header, qlen, &p, name, 1, 4))
   1200 	return 0; /* bad packet */
   1201 
   1202       GETSHORT(qtype, p);
   1203       GETSHORT(qclass, p);
   1204 
   1205       ans = 0; /* have we answered this question */
   1206 
   1207       if (qtype == T_TXT || qtype == T_ANY)
   1208 	{
   1209 	  struct txt_record *t;
   1210 	  for(t = daemon->txt; t ; t = t->next)
   1211 	    {
   1212 	      if (t->class == qclass && hostname_isequal(name, t->name))
   1213 		{
   1214 		  ans = 1;
   1215 		  if (!dryrun)
   1216 		    {
   1217 		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<TXT>");
   1218 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1219 					      daemon->local_ttl, NULL,
   1220 					      T_TXT, t->class, "t", t->len, t->txt))
   1221 			anscount++;
   1222 
   1223 		    }
   1224 		}
   1225 	    }
   1226 	}
   1227 
   1228       if (qclass == C_IN)
   1229 	{
   1230 	  if (qtype == T_PTR || qtype == T_ANY)
   1231 	    {
   1232 	      /* see if it's w.z.y.z.in-addr.arpa format */
   1233 	      int is_arpa = in_arpa_name_2_addr(name, &addr);
   1234 	      struct ptr_record *ptr;
   1235 	      struct interface_name* intr = NULL;
   1236 
   1237 	      for (ptr = daemon->ptr; ptr; ptr = ptr->next)
   1238 		if (hostname_isequal(name, ptr->name))
   1239 		  break;
   1240 
   1241 	      if (is_arpa == F_IPV4)
   1242 		for (intr = daemon->int_names; intr; intr = intr->next)
   1243 		  {
   1244 		    if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr)
   1245 		      break;
   1246 		    else
   1247 		      while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
   1248 			intr = intr->next;
   1249 		  }
   1250 
   1251 	      if (intr)
   1252 		{
   1253 		  ans = 1;
   1254 		  if (!dryrun)
   1255 		    {
   1256 		      log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
   1257 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1258 					      daemon->local_ttl, NULL,
   1259 					      T_PTR, C_IN, "d", intr->name))
   1260 			anscount++;
   1261 		    }
   1262 		}
   1263 	      else if (ptr)
   1264 		{
   1265 		  ans = 1;
   1266 		  if (!dryrun)
   1267 		    {
   1268 		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<PTR>");
   1269 		      for (ptr = daemon->ptr; ptr; ptr = ptr->next)
   1270 			if (hostname_isequal(name, ptr->name) &&
   1271 			    add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1272 						daemon->local_ttl, NULL,
   1273 						T_PTR, C_IN, "d", ptr->ptr))
   1274 			  anscount++;
   1275 
   1276 		    }
   1277 		}
   1278 	      else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
   1279 		do
   1280 		  {
   1281 		    /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
   1282 		    if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
   1283 		      continue;
   1284 
   1285 		    if (crecp->flags & F_NEG)
   1286 		      {
   1287 			ans = 1;
   1288 			auth = 0;
   1289 			if (crecp->flags & F_NXDOMAIN)
   1290 			  nxdomain = 1;
   1291 			if (!dryrun)
   1292 			  log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
   1293 		      }
   1294 		    else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
   1295 		      {
   1296 			ans = 1;
   1297 			if (!(crecp->flags & (F_HOSTS | F_DHCP)))
   1298 			  auth = 0;
   1299 			if (!dryrun)
   1300 			  {
   1301 			    log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
   1302 				      record_source(crecp->uid));
   1303 
   1304 			    if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1305 						    crec_ttl(crecp, now), NULL,
   1306 						    T_PTR, C_IN, "d", cache_get_name(crecp)))
   1307 			      anscount++;
   1308 			  }
   1309 		      }
   1310 		  } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
   1311 	      else if (is_arpa == F_IPV4 &&
   1312 		       (daemon->options & OPT_BOGUSPRIV) &&
   1313 		       private_net(addr.addr.addr4))
   1314 		{
   1315 		  /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
   1316 		  ans = 1;
   1317 		  nxdomain = 1;
   1318 		  if (!dryrun)
   1319 		    log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN,
   1320 			      name, &addr, NULL);
   1321 		}
   1322 	    }
   1323 
   1324 	  for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
   1325 	    {
   1326 	      unsigned short type = T_A;
   1327 
   1328 	      if (flag == F_IPV6)
   1329 #ifdef HAVE_IPV6
   1330 		type = T_AAAA;
   1331 #else
   1332 	        break;
   1333 #endif
   1334 
   1335 	      if (qtype != type && qtype != T_ANY)
   1336 		continue;
   1337 
   1338 	      /* Check for "A for A"  queries */
   1339 	      if (qtype == T_A && (addr.addr.addr4.s_addr = inet_addr(name)) != (in_addr_t) -1)
   1340 		{
   1341 		  ans = 1;
   1342 		  if (!dryrun)
   1343 		    {
   1344 		      log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
   1345 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1346 					      daemon->local_ttl, NULL, type, C_IN, "4", &addr))
   1347 			anscount++;
   1348 		    }
   1349 		  continue;
   1350 		}
   1351 
   1352 	      /* interface name stuff */
   1353 	      if (qtype == T_A)
   1354 		{
   1355 		  struct interface_name *intr;
   1356 
   1357 		  for (intr = daemon->int_names; intr; intr = intr->next)
   1358 		    if (hostname_isequal(name, intr->name))
   1359 		      break;
   1360 
   1361 		  if (intr)
   1362 		    {
   1363 		      ans = 1;
   1364 		      if (!dryrun)
   1365 			{
   1366 			  if ((addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr == (in_addr_t) -1)
   1367 			    log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, NULL);
   1368 			  else
   1369 			    {
   1370 			      log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
   1371 			      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1372 						      daemon->local_ttl, NULL, type, C_IN, "4", &addr))
   1373 				anscount++;
   1374 			    }
   1375 			}
   1376 		      continue;
   1377 		    }
   1378 		}
   1379 
   1380 	    cname_restart:
   1381 	      if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME)))
   1382 		{
   1383 		  int localise = 0;
   1384 
   1385 		  /* See if a putative address is on the network from which we recieved
   1386 		     the query, is so we'll filter other answers. */
   1387 		  if (local_addr.s_addr != 0 && (daemon->options & OPT_LOCALISE) && flag == F_IPV4)
   1388 		    {
   1389 		      struct crec *save = crecp;
   1390 		      do {
   1391 			if ((crecp->flags & F_HOSTS) &&
   1392 			    is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
   1393 			  {
   1394 			    localise = 1;
   1395 			    break;
   1396 			  }
   1397 			} while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
   1398 		      crecp = save;
   1399 		    }
   1400 
   1401 		  do
   1402 		    {
   1403 		      /* don't answer wildcard queries with data not from /etc/hosts
   1404 			 or DHCP leases */
   1405 		      if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
   1406 			break;
   1407 
   1408 		      if (crecp->flags & F_CNAME)
   1409 			{
   1410 			  if (!dryrun)
   1411 			    {
   1412 			      log_query(crecp->flags, name, NULL, record_source(crecp->uid));
   1413 			      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1414 						      crec_ttl(crecp, now), &nameoffset,
   1415 						      T_CNAME, C_IN, "d", cache_get_name(crecp->addr.cname.cache)))
   1416 				anscount++;
   1417 			    }
   1418 
   1419 			  strcpy(name, cache_get_name(crecp->addr.cname.cache));
   1420 			  goto cname_restart;
   1421 			}
   1422 
   1423 		      if (crecp->flags & F_NEG)
   1424 			{
   1425 			  ans = 1;
   1426 			  auth = 0;
   1427 			  if (crecp->flags & F_NXDOMAIN)
   1428 			    nxdomain = 1;
   1429 			  if (!dryrun)
   1430 			    log_query(crecp->flags, name, NULL, NULL);
   1431 			}
   1432 		      else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
   1433 			{
   1434 			  /* If we are returning local answers depending on network,
   1435 			     filter here. */
   1436 			  if (localise &&
   1437 			      (crecp->flags & F_HOSTS) &&
   1438 			      !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
   1439 			    continue;
   1440 
   1441 			  if (!(crecp->flags & (F_HOSTS | F_DHCP)))
   1442 			    auth = 0;
   1443 
   1444 			  ans = 1;
   1445 			  if (!dryrun)
   1446 			    {
   1447 			      log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
   1448 					record_source(crecp->uid));
   1449 
   1450 			      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1451 						      crec_ttl(crecp, now), NULL, type, C_IN,
   1452 						      type == T_A ? "4" : "6", &crecp->addr))
   1453 				anscount++;
   1454 			    }
   1455 			}
   1456 		    } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
   1457 		}
   1458 	    }
   1459 
   1460 	  if (qtype == T_MX || qtype == T_ANY)
   1461 	    {
   1462 	      int found = 0;
   1463 	      for (rec = daemon->mxnames; rec; rec = rec->next)
   1464 		if (!rec->issrv && hostname_isequal(name, rec->name))
   1465 		  {
   1466 		  ans = found = 1;
   1467 		  if (!dryrun)
   1468 		    {
   1469 		      unsigned int offset;
   1470 		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>");
   1471 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
   1472 					      &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
   1473 			{
   1474 			  anscount++;
   1475 			  if (rec->target)
   1476 			    rec->offset = offset;
   1477 			}
   1478 		    }
   1479 		  }
   1480 
   1481 	      if (!found && (daemon->options & (OPT_SELFMX | OPT_LOCALMX)) &&
   1482 		  cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP))
   1483 		{
   1484 		  ans = 1;
   1485 		  if (!dryrun)
   1486 		    {
   1487 		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>");
   1488 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
   1489 					      T_MX, C_IN, "sd", 1,
   1490 					      (daemon->options & OPT_SELFMX) ? name : daemon->mxtarget))
   1491 			anscount++;
   1492 		    }
   1493 		}
   1494 	    }
   1495 
   1496 	  if (qtype == T_SRV || qtype == T_ANY)
   1497 	    {
   1498 	      int found = 0;
   1499 
   1500 	      for (rec = daemon->mxnames; rec; rec = rec->next)
   1501 		if (rec->issrv && hostname_isequal(name, rec->name))
   1502 		  {
   1503 		    found = ans = 1;
   1504 		    if (!dryrun)
   1505 		      {
   1506 			unsigned int offset;
   1507 			log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<SRV>");
   1508 			if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
   1509 						&offset, T_SRV, C_IN, "sssd",
   1510 						rec->priority, rec->weight, rec->srvport, rec->target))
   1511 			  {
   1512 			    anscount++;
   1513 			    if (rec->target)
   1514 			      rec->offset = offset;
   1515 			  }
   1516 		      }
   1517 		  }
   1518 
   1519 	      if (!found && (daemon->options & OPT_FILTER) &&  (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
   1520 		{
   1521 		  ans = 1;
   1522 		  if (!dryrun)
   1523 		    log_query(F_CONFIG | F_NEG, name, NULL, NULL);
   1524 		}
   1525 	    }
   1526 
   1527 	  if (qtype == T_NAPTR || qtype == T_ANY)
   1528 	    {
   1529 	      struct naptr *na;
   1530 	      for (na = daemon->naptr; na; na = na->next)
   1531 		if (hostname_isequal(name, na->name))
   1532 		  {
   1533 		    ans = 1;
   1534 		    if (!dryrun)
   1535 		      {
   1536 			log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<NAPTR>");
   1537 			if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
   1538 						NULL, T_NAPTR, C_IN, "sszzzd",
   1539 						na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
   1540 			  anscount++;
   1541 		      }
   1542 		  }
   1543 	    }
   1544 
   1545 	  if (qtype == T_MAILB)
   1546 	    ans = 1, nxdomain = 1;
   1547 
   1548 	  if (qtype == T_SOA && (daemon->options & OPT_FILTER))
   1549 	    {
   1550 	      ans = 1;
   1551 	      if (!dryrun)
   1552 		log_query(F_CONFIG | F_NEG, name, &addr, NULL);
   1553 	    }
   1554 	}
   1555 
   1556       if (!ans)
   1557 	return 0; /* failed to answer a question */
   1558     }
   1559 
   1560   if (dryrun)
   1561     {
   1562       dryrun = 0;
   1563       goto rerun;
   1564     }
   1565 
   1566   /* create an additional data section, for stuff in SRV and MX record replies. */
   1567   for (rec = daemon->mxnames; rec; rec = rec->next)
   1568     if (rec->offset != 0)
   1569       {
   1570 	/* squash dupes */
   1571 	struct mx_srv_record *tmp;
   1572 	for (tmp = rec->next; tmp; tmp = tmp->next)
   1573 	  if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
   1574 	    tmp->offset = 0;
   1575 
   1576 	crecp = NULL;
   1577 	while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
   1578 	  {
   1579 #ifdef HAVE_IPV6
   1580 	    int type =  crecp->flags & F_IPV4 ? T_A : T_AAAA;
   1581 #else
   1582 	    int type = T_A;
   1583 #endif
   1584 	    if (crecp->flags & F_NEG)
   1585 	      continue;
   1586 
   1587 	    if (add_resource_record(header, limit, NULL, rec->offset, &ansp,
   1588 				    crec_ttl(crecp, now), NULL, type, C_IN,
   1589 				    crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
   1590 	      addncount++;
   1591 	  }
   1592       }
   1593 
   1594   /* done all questions, set up header and return length of result */
   1595   header->qr = 1; /* response */
   1596   header->aa = auth; /* authoritive - only hosts and DHCP derived names. */
   1597   header->ra = 1; /* recursion if available */
   1598   header->tc = trunc; /* truncation */
   1599   if (anscount == 0 && nxdomain)
   1600     header->rcode = NXDOMAIN;
   1601   else
   1602     header->rcode = NOERROR; /* no error */
   1603   header->ancount = htons(anscount);
   1604   header->nscount = htons(0);
   1605   header->arcount = htons(addncount);
   1606   return ansp - (unsigned char *)header;
   1607 }
   1608 
   1609 
   1610 
   1611 
   1612 
   1613