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