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