File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / rfc1035.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 09:57:01 2016 UTC (7 years, 8 months ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v2_76p1, HEAD
dnsmasq 2.76

    1: /* dnsmasq is Copyright (c) 2000-2016 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: int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, 
   20: 		 char *name, int isExtract, int extrabytes)
   21: {
   22:   unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL;
   23:   unsigned int j, l, namelen = 0, hops = 0;
   24:   int retvalue = 1;
   25:   
   26:   if (isExtract)
   27:     *cp = 0;
   28: 
   29:   while (1)
   30:     { 
   31:       unsigned int label_type;
   32: 
   33:       if (!CHECK_LEN(header, p, plen, 1))
   34: 	return 0;
   35:       
   36:       if ((l = *p++) == 0) 
   37: 	/* end marker */
   38: 	{
   39: 	  /* check that there are the correct no of bytes after the name */
   40: 	  if (!CHECK_LEN(header, p, plen, extrabytes))
   41: 	    return 0;
   42: 	  
   43: 	  if (isExtract)
   44: 	    {
   45: 	      if (cp != (unsigned char *)name)
   46: 		cp--;
   47: 	      *cp = 0; /* terminate: lose final period */
   48: 	    }
   49: 	  else if (*cp != 0)
   50: 	    retvalue = 2;
   51: 	  
   52: 	  if (p1) /* we jumped via compression */
   53: 	    *pp = p1;
   54: 	  else
   55: 	    *pp = p;
   56: 	  
   57: 	  return retvalue;
   58: 	}
   59: 
   60:       label_type = l & 0xc0;
   61:       
   62:       if (label_type == 0xc0) /* pointer */
   63: 	{ 
   64: 	  if (!CHECK_LEN(header, p, plen, 1))
   65: 	    return 0;
   66: 	      
   67: 	  /* get offset */
   68: 	  l = (l&0x3f) << 8;
   69: 	  l |= *p++;
   70: 	  
   71: 	  if (!p1) /* first jump, save location to go back to */
   72: 	    p1 = p;
   73: 	      
   74: 	  hops++; /* break malicious infinite loops */
   75: 	  if (hops > 255)
   76: 	    return 0;
   77: 	  
   78: 	  p = l + (unsigned char *)header;
   79: 	}
   80:       else if (label_type == 0x00)
   81: 	{ /* label_type = 0 -> label. */
   82: 	  namelen += l + 1; /* include period */
   83: 	  if (namelen >= MAXDNAME)
   84: 	    return 0;
   85: 	  if (!CHECK_LEN(header, p, plen, l))
   86: 	    return 0;
   87: 	  
   88: 	  for(j=0; j<l; j++, p++)
   89: 	    if (isExtract)
   90: 	      {
   91: 		unsigned char c = *p;
   92: #ifdef HAVE_DNSSEC
   93: 		if (option_bool(OPT_DNSSEC_VALID))
   94: 		  {
   95: 		    if (c == 0 || c == '.' || c == NAME_ESCAPE)
   96: 		      {
   97: 			*cp++ = NAME_ESCAPE;
   98: 			*cp++ = c+1;
   99: 		      }
  100: 		    else
  101: 		      *cp++ = c; 
  102: 		  }
  103: 		else
  104: #endif
  105: 		if (c != 0 && c != '.')
  106: 		  *cp++ = c;
  107: 		else
  108: 		  return 0;
  109: 	      }
  110: 	    else 
  111: 	      {
  112: 		unsigned char c1 = *cp, c2 = *p;
  113: 		
  114: 		if (c1 == 0)
  115: 		  retvalue = 2;
  116: 		else 
  117: 		  {
  118: 		    cp++;
  119: 		    if (c1 >= 'A' && c1 <= 'Z')
  120: 		      c1 += 'a' - 'A';
  121: #ifdef HAVE_DNSSEC
  122: 		    if (option_bool(OPT_DNSSEC_VALID) && c1 == NAME_ESCAPE)
  123: 		      c1 = (*cp++)-1;
  124: #endif
  125: 		    
  126: 		    if (c2 >= 'A' && c2 <= 'Z')
  127: 		      c2 += 'a' - 'A';
  128: 		     
  129: 		    if (c1 != c2)
  130: 		      retvalue =  2;
  131: 		  }
  132: 	      }
  133: 	    
  134: 	  if (isExtract)
  135: 	    *cp++ = '.';
  136: 	  else if (*cp != 0 && *cp++ != '.')
  137: 	    retvalue = 2;
  138: 	}
  139:       else
  140: 	return 0; /* label types 0x40 and 0x80 not supported */
  141:     }
  142: }
  143:  
  144: /* Max size of input string (for IPv6) is 75 chars.) */
  145: #define MAXARPANAME 75
  146: int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
  147: {
  148:   int j;
  149:   char name[MAXARPANAME+1], *cp1;
  150:   unsigned char *addr = (unsigned char *)addrp;
  151:   char *lastchunk = NULL, *penchunk = NULL;
  152:   
  153:   if (strlen(namein) > MAXARPANAME)
  154:     return 0;
  155: 
  156:   memset(addrp, 0, sizeof(struct all_addr));
  157: 
  158:   /* turn name into a series of asciiz strings */
  159:   /* j counts no of labels */
  160:   for(j = 1,cp1 = name; *namein; cp1++, namein++)
  161:     if (*namein == '.')
  162:       {
  163: 	penchunk = lastchunk;
  164:         lastchunk = cp1 + 1;
  165: 	*cp1 = 0;
  166: 	j++;
  167:       }
  168:     else
  169:       *cp1 = *namein;
  170:   
  171:   *cp1 = 0;
  172: 
  173:   if (j<3)
  174:     return 0;
  175: 
  176:   if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr"))
  177:     {
  178:       /* IP v4 */
  179:       /* address arives as a name of the form
  180: 	 www.xxx.yyy.zzz.in-addr.arpa
  181: 	 some of the low order address octets might be missing
  182: 	 and should be set to zero. */
  183:       for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
  184: 	{
  185: 	  /* check for digits only (weeds out things like
  186: 	     50.0/24.67.28.64.in-addr.arpa which are used 
  187: 	     as CNAME targets according to RFC 2317 */
  188: 	  char *cp;
  189: 	  for (cp = cp1; *cp; cp++)
  190: 	    if (!isdigit((unsigned char)*cp))
  191: 	      return 0;
  192: 	  
  193: 	  addr[3] = addr[2];
  194: 	  addr[2] = addr[1];
  195: 	  addr[1] = addr[0];
  196: 	  addr[0] = atoi(cp1);
  197: 	}
  198: 
  199:       return F_IPV4;
  200:     }
  201: #ifdef HAVE_IPV6
  202:   else if (hostname_isequal(penchunk, "ip6") && 
  203: 	   (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa")))
  204:     {
  205:       /* IP v6:
  206:          Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
  207:     	 or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]
  208:       
  209: 	 Note that most of these the various reprentations are obsolete and 
  210: 	 left-over from the many DNS-for-IPv6 wars. We support all the formats
  211: 	 that we can since there is no reason not to.
  212:       */
  213: 
  214:       if (*name == '\\' && *(name+1) == '[' && 
  215: 	  (*(name+2) == 'x' || *(name+2) == 'X'))
  216: 	{	  
  217: 	  for (j = 0, cp1 = name+3; *cp1 && isxdigit((unsigned char) *cp1) && j < 32; cp1++, j++)
  218: 	    {
  219: 	      char xdig[2];
  220: 	      xdig[0] = *cp1;
  221: 	      xdig[1] = 0;
  222: 	      if (j%2)
  223: 		addr[j/2] |= strtol(xdig, NULL, 16);
  224: 	      else
  225: 		addr[j/2] = strtol(xdig, NULL, 16) << 4;
  226: 	    }
  227: 	  
  228: 	  if (*cp1 == '/' && j == 32)
  229: 	    return F_IPV6;
  230: 	}
  231:       else
  232: 	{
  233: 	  for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
  234: 	    {
  235: 	      if (*(cp1+1) || !isxdigit((unsigned char)*cp1))
  236: 		return 0;
  237: 	      
  238: 	      for (j = sizeof(struct all_addr)-1; j>0; j--)
  239: 		addr[j] = (addr[j] >> 4) | (addr[j-1] << 4);
  240: 	      addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
  241: 	    }
  242: 	  
  243: 	  return F_IPV6;
  244: 	}
  245:     }
  246: #endif
  247:   
  248:   return 0;
  249: }
  250: 
  251: unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes)
  252: {
  253:   while(1)
  254:     {
  255:       unsigned int label_type;
  256:       
  257:       if (!CHECK_LEN(header, ansp, plen, 1))
  258: 	return NULL;
  259:       
  260:       label_type = (*ansp) & 0xc0;
  261: 
  262:       if (label_type == 0xc0)
  263: 	{
  264: 	  /* pointer for compression. */
  265: 	  ansp += 2;	
  266: 	  break;
  267: 	}
  268:       else if (label_type == 0x80)
  269: 	return NULL; /* reserved */
  270:       else if (label_type == 0x40)
  271: 	{
  272: 	  /* Extended label type */
  273: 	  unsigned int count;
  274: 	  
  275: 	  if (!CHECK_LEN(header, ansp, plen, 2))
  276: 	    return NULL;
  277: 	  
  278: 	  if (((*ansp++) & 0x3f) != 1)
  279: 	    return NULL; /* we only understand bitstrings */
  280: 	  
  281: 	  count = *(ansp++); /* Bits in bitstring */
  282: 	  
  283: 	  if (count == 0) /* count == 0 means 256 bits */
  284: 	    ansp += 32;
  285: 	  else
  286: 	    ansp += ((count-1)>>3)+1;
  287: 	}
  288:       else
  289: 	{ /* label type == 0 Bottom six bits is length */
  290: 	  unsigned int len = (*ansp++) & 0x3f;
  291: 	  
  292: 	  if (!ADD_RDLEN(header, ansp, plen, len))
  293: 	    return NULL;
  294: 
  295: 	  if (len == 0)
  296: 	    break; /* zero length label marks the end. */
  297: 	}
  298:     }
  299: 
  300:   if (!CHECK_LEN(header, ansp, plen, extrabytes))
  301:     return NULL;
  302:   
  303:   return ansp;
  304: }
  305: 
  306: unsigned char *skip_questions(struct dns_header *header, size_t plen)
  307: {
  308:   int q;
  309:   unsigned char *ansp = (unsigned char *)(header+1);
  310: 
  311:   for (q = ntohs(header->qdcount); q != 0; q--)
  312:     {
  313:       if (!(ansp = skip_name(ansp, header, plen, 4)))
  314: 	return NULL;
  315:       ansp += 4; /* class and type */
  316:     }
  317:   
  318:   return ansp;
  319: }
  320: 
  321: unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen)
  322: {
  323:   int i, rdlen;
  324:   
  325:   for (i = 0; i < count; i++)
  326:     {
  327:       if (!(ansp = skip_name(ansp, header, plen, 10)))
  328: 	return NULL; 
  329:       ansp += 8; /* type, class, TTL */
  330:       GETSHORT(rdlen, ansp);
  331:       if (!ADD_RDLEN(header, ansp, plen, rdlen))
  332: 	return NULL;
  333:     }
  334: 
  335:   return ansp;
  336: }
  337: 
  338: /* CRC the question section. This is used to safely detect query 
  339:    retransmision and to detect answers to questions we didn't ask, which 
  340:    might be poisoning attacks. Note that we decode the name rather 
  341:    than CRC the raw bytes, since replies might be compressed differently. 
  342:    We ignore case in the names for the same reason. Return all-ones
  343:    if there is not question section. */
  344: #ifndef HAVE_DNSSEC
  345: unsigned int questions_crc(struct dns_header *header, size_t plen, char *name)
  346: {
  347:   int q;
  348:   unsigned int crc = 0xffffffff;
  349:   unsigned char *p1, *p = (unsigned char *)(header+1);
  350: 
  351:   for (q = ntohs(header->qdcount); q != 0; q--) 
  352:     {
  353:       if (!extract_name(header, plen, &p, name, 1, 4))
  354: 	return crc; /* bad packet */
  355:       
  356:       for (p1 = (unsigned char *)name; *p1; p1++)
  357: 	{
  358: 	  int i = 8;
  359: 	  char c = *p1;
  360: 
  361: 	  if (c >= 'A' && c <= 'Z')
  362: 	    c += 'a' - 'A';
  363: 
  364: 	  crc ^= c << 24;
  365: 	  while (i--)
  366: 	    crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
  367: 	}
  368:       
  369:       /* CRC the class and type as well */
  370:       for (p1 = p; p1 < p+4; p1++)
  371: 	{
  372: 	  int i = 8;
  373: 	  crc ^= *p1 << 24;
  374: 	  while (i--)
  375: 	    crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
  376: 	}
  377: 
  378:       p += 4;
  379:       if (!CHECK_LEN(header, p, plen, 0))
  380: 	return crc; /* bad packet */
  381:     }
  382: 
  383:   return crc;
  384: }
  385: #endif
  386: 
  387: size_t resize_packet(struct dns_header *header, size_t plen, unsigned char *pheader, size_t hlen)
  388: {
  389:   unsigned char *ansp = skip_questions(header, plen);
  390:     
  391:   /* if packet is malformed, just return as-is. */
  392:   if (!ansp)
  393:     return plen;
  394:   
  395:   if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
  396: 			    header, plen)))
  397:     return plen;
  398:     
  399:   /* restore pseudoheader */
  400:   if (pheader && ntohs(header->arcount) == 0)
  401:     {
  402:       /* must use memmove, may overlap */
  403:       memmove(ansp, pheader, hlen);
  404:       header->arcount = htons(1);
  405:       ansp += hlen;
  406:     }
  407: 
  408:   return ansp - (unsigned char *)header;
  409: }
  410: 
  411: /* is addr in the non-globally-routed IP space? */ 
  412: int private_net(struct in_addr addr, int ban_localhost) 
  413: {
  414:   in_addr_t ip_addr = ntohl(addr.s_addr);
  415: 
  416:   return
  417:     (((ip_addr & 0xFF000000) == 0x7F000000) && ban_localhost)  /* 127.0.0.0/8    (loopback) */ ||
  418:     ((ip_addr & 0xFF000000) == 0x00000000)  /* RFC 5735 section 3. "here" network */ ||
  419:     ((ip_addr & 0xFF000000) == 0x0A000000)  /* 10.0.0.0/8     (private)  */ ||
  420:     ((ip_addr & 0xFFF00000) == 0xAC100000)  /* 172.16.0.0/12  (private)  */ ||
  421:     ((ip_addr & 0xFFFF0000) == 0xC0A80000)  /* 192.168.0.0/16 (private)  */ ||
  422:     ((ip_addr & 0xFFFF0000) == 0xA9FE0000)  /* 169.254.0.0/16 (zeroconf) */ ||
  423:     ((ip_addr & 0xFFFFFF00) == 0xC0000200)  /* 192.0.2.0/24   (test-net) */ ||
  424:     ((ip_addr & 0xFFFFFF00) == 0xC6336400)  /* 198.51.100.0/24(test-net) */ ||
  425:     ((ip_addr & 0xFFFFFF00) == 0xCB007100)  /* 203.0.113.0/24 (test-net) */ ||
  426:     ((ip_addr & 0xFFFFFFFF) == 0xFFFFFFFF)  /* 255.255.255.255/32 (broadcast)*/ ;
  427: }
  428: 
  429: static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *header, size_t qlen, char *name, int *doctored)
  430: {
  431:   int i, qtype, qclass, rdlen;
  432: 
  433:   for (i = count; i != 0; i--)
  434:     {
  435:       if (name && option_bool(OPT_LOG))
  436: 	{
  437: 	  if (!extract_name(header, qlen, &p, name, 1, 10))
  438: 	    return 0;
  439: 	}
  440:       else if (!(p = skip_name(p, header, qlen, 10)))
  441: 	return 0; /* bad packet */
  442:       
  443:       GETSHORT(qtype, p); 
  444:       GETSHORT(qclass, p);
  445:       p += 4; /* ttl */
  446:       GETSHORT(rdlen, p);
  447:       
  448:       if (qclass == C_IN && qtype == T_A)
  449: 	{
  450: 	  struct doctor *doctor;
  451: 	  struct in_addr addr;
  452: 	  
  453: 	  if (!CHECK_LEN(header, p, qlen, INADDRSZ))
  454: 	    return 0;
  455: 	  
  456: 	  /* alignment */
  457: 	  memcpy(&addr, p, INADDRSZ);
  458: 	  
  459: 	  for (doctor = daemon->doctors; doctor; doctor = doctor->next)
  460: 	    {
  461: 	      if (doctor->end.s_addr == 0)
  462: 		{
  463: 		  if (!is_same_net(doctor->in, addr, doctor->mask))
  464: 		    continue;
  465: 		}
  466: 	      else if (ntohl(doctor->in.s_addr) > ntohl(addr.s_addr) || 
  467: 		       ntohl(doctor->end.s_addr) < ntohl(addr.s_addr))
  468: 		continue;
  469: 	      
  470: 	      addr.s_addr &= ~doctor->mask.s_addr;
  471: 	      addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
  472: 	      /* Since we munged the data, the server it came from is no longer authoritative */
  473: 	      header->hb3 &= ~HB3_AA;
  474: 	      *doctored = 1;
  475: 	      memcpy(p, &addr, INADDRSZ);
  476: 	      break;
  477: 	    }
  478: 	}
  479:       else if (qtype == T_TXT && name && option_bool(OPT_LOG))
  480: 	{
  481: 	  unsigned char *p1 = p;
  482: 	  if (!CHECK_LEN(header, p1, qlen, rdlen))
  483: 	    return 0;
  484: 	  while ((p1 - p) < rdlen)
  485: 	    {
  486: 	      unsigned int i, len = *p1;
  487: 	      unsigned char *p2 = p1;
  488: 	      /* make counted string zero-term  and sanitise */
  489: 	      for (i = 0; i < len; i++)
  490: 		{
  491: 		  if (!isprint((int)*(p2+1)))
  492: 		    break;
  493: 		  
  494: 		  *p2 = *(p2+1);
  495: 		  p2++;
  496: 		}
  497: 	      *p2 = 0;
  498: 	      my_syslog(LOG_INFO, "reply %s is %s", name, p1);
  499: 	      /* restore */
  500: 	      memmove(p1 + 1, p1, i);
  501: 	      *p1 = len;
  502: 	      p1 += len+1;
  503: 	    }
  504: 	}		  
  505:       
  506:       if (!ADD_RDLEN(header, p, qlen, rdlen))
  507: 	 return 0; /* bad packet */
  508:     }
  509:   
  510:   return p; 
  511: }
  512: 
  513: static int find_soa(struct dns_header *header, size_t qlen, char *name, int *doctored)
  514: {
  515:   unsigned char *p;
  516:   int qtype, qclass, rdlen;
  517:   unsigned long ttl, minttl = ULONG_MAX;
  518:   int i, found_soa = 0;
  519:   
  520:   /* first move to NS section and find TTL from any SOA section */
  521:   if (!(p = skip_questions(header, qlen)) ||
  522:       !(p = do_doctor(p, ntohs(header->ancount), header, qlen, name, doctored)))
  523:     return 0;  /* bad packet */
  524:   
  525:   for (i = ntohs(header->nscount); i != 0; i--)
  526:     {
  527:       if (!(p = skip_name(p, header, qlen, 10)))
  528: 	return 0; /* bad packet */
  529:       
  530:       GETSHORT(qtype, p); 
  531:       GETSHORT(qclass, p);
  532:       GETLONG(ttl, p);
  533:       GETSHORT(rdlen, p);
  534:       
  535:       if ((qclass == C_IN) && (qtype == T_SOA))
  536: 	{
  537: 	  found_soa = 1;
  538: 	  if (ttl < minttl)
  539: 	    minttl = ttl;
  540: 
  541: 	  /* MNAME */
  542: 	  if (!(p = skip_name(p, header, qlen, 0)))
  543: 	    return 0;
  544: 	  /* RNAME */
  545: 	  if (!(p = skip_name(p, header, qlen, 20)))
  546: 	    return 0;
  547: 	  p += 16; /* SERIAL REFRESH RETRY EXPIRE */
  548: 	  
  549: 	  GETLONG(ttl, p); /* minTTL */
  550: 	  if (ttl < minttl)
  551: 	    minttl = ttl;
  552: 	}
  553:       else if (!ADD_RDLEN(header, p, qlen, rdlen))
  554: 	return 0; /* bad packet */
  555:     }
  556:   
  557:   /* rewrite addresses in additional section too */
  558:   if (!do_doctor(p, ntohs(header->arcount), header, qlen, NULL, doctored))
  559:     return 0;
  560:   
  561:   if (!found_soa)
  562:     minttl = daemon->neg_ttl;
  563: 
  564:   return minttl;
  565: }
  566: 
  567: /* Note that the following code can create CNAME chains that don't point to a real record,
  568:    either because of lack of memory, or lack of SOA records.  These are treated by the cache code as 
  569:    expired and cleaned out that way. 
  570:    Return 1 if we reject an address because it look like part of dns-rebinding attack. */
  571: int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t now, 
  572: 		      char **ipsets, int is_sign, int check_rebind, int no_cache_dnssec, int secure, int *doctored)
  573: {
  574:   unsigned char *p, *p1, *endrr, *namep;
  575:   int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
  576:   unsigned long ttl = 0;
  577:   struct all_addr addr;
  578: #ifdef HAVE_IPSET
  579:   char **ipsets_cur;
  580: #else
  581:   (void)ipsets; /* unused */
  582: #endif
  583:   
  584:   cache_start_insert();
  585: 
  586:   /* find_soa is needed for dns_doctor and logging side-effects, so don't call it lazily if there are any. */
  587:   if (daemon->doctors || option_bool(OPT_LOG) || option_bool(OPT_DNSSEC_VALID))
  588:     {
  589:       searched_soa = 1;
  590:       ttl = find_soa(header, qlen, name, doctored);
  591: #ifdef HAVE_DNSSEC
  592:       if (*doctored && secure)
  593: 	return 0;
  594: #endif
  595:     }
  596:   
  597:   /* go through the questions. */
  598:   p = (unsigned char *)(header+1);
  599:   
  600:   for (i = ntohs(header->qdcount); i != 0; i--)
  601:     {
  602:       int found = 0, cname_count = CNAME_CHAIN;
  603:       struct crec *cpp = NULL;
  604:       int flags = RCODE(header) == NXDOMAIN ? F_NXDOMAIN : 0;
  605:       int secflag = secure ?  F_DNSSECOK : 0;
  606:       unsigned long cttl = ULONG_MAX, attl;
  607: 
  608:       namep = p;
  609:       if (!extract_name(header, qlen, &p, name, 1, 4))
  610: 	return 0; /* bad packet */
  611:            
  612:       GETSHORT(qtype, p); 
  613:       GETSHORT(qclass, p);
  614:       
  615:       if (qclass != C_IN)
  616: 	continue;
  617: 
  618:       /* PTRs: we chase CNAMEs here, since we have no way to 
  619: 	 represent them in the cache. */
  620:       if (qtype == T_PTR)
  621: 	{ 
  622: 	  int name_encoding = in_arpa_name_2_addr(name, &addr);
  623: 	  
  624: 	  if (!name_encoding)
  625: 	    continue;
  626: 
  627: 	  if (!(flags & F_NXDOMAIN))
  628: 	    {
  629: 	    cname_loop:
  630: 	      if (!(p1 = skip_questions(header, qlen)))
  631: 		return 0;
  632: 	      
  633: 	      for (j = ntohs(header->ancount); j != 0; j--) 
  634: 		{
  635: 		  unsigned char *tmp = namep;
  636: 		  /* the loop body overwrites the original name, so get it back here. */
  637: 		  if (!extract_name(header, qlen, &tmp, name, 1, 0) ||
  638: 		      !(res = extract_name(header, qlen, &p1, name, 0, 10)))
  639: 		    return 0; /* bad packet */
  640: 		  
  641: 		  GETSHORT(aqtype, p1); 
  642: 		  GETSHORT(aqclass, p1);
  643: 		  GETLONG(attl, p1);
  644: 		  if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
  645: 		    {
  646: 		      (p1) -= 4;
  647: 		      PUTLONG(daemon->max_ttl, p1);
  648: 		    }
  649: 		  GETSHORT(ardlen, p1);
  650: 		  endrr = p1+ardlen;
  651: 		  
  652: 		  /* TTL of record is minimum of CNAMES and PTR */
  653: 		  if (attl < cttl)
  654: 		    cttl = attl;
  655: 
  656: 		  if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
  657: 		    {
  658: 		      if (!extract_name(header, qlen, &p1, name, 1, 0))
  659: 			return 0;
  660: 		      
  661: 		      if (aqtype == T_CNAME)
  662: 			{
  663: 			  if (!cname_count-- || secure)
  664: 			    return 0; /* looped CNAMES, or DNSSEC, which we can't cache. */
  665: 			  goto cname_loop;
  666: 			}
  667: 		      
  668: 		      cache_insert(name, &addr, now, cttl, name_encoding | secflag | F_REVERSE);
  669: 		      found = 1; 
  670: 		    }
  671: 		  
  672: 		  p1 = endrr;
  673: 		  if (!CHECK_LEN(header, p1, qlen, 0))
  674: 		    return 0; /* bad packet */
  675: 		}
  676: 	    }
  677: 	  
  678: 	   if (!found && !option_bool(OPT_NO_NEG))
  679: 	    {
  680: 	      if (!searched_soa)
  681: 		{
  682: 		  searched_soa = 1;
  683: 		  ttl = find_soa(header, qlen, NULL, doctored);
  684: 		}
  685: 	      if (ttl)
  686: 		cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags | secflag);	
  687: 	    }
  688: 	}
  689:       else
  690: 	{
  691: 	  /* everything other than PTR */
  692: 	  struct crec *newc;
  693: 	  int addrlen;
  694: 
  695: 	  if (qtype == T_A)
  696: 	    {
  697: 	      addrlen = INADDRSZ;
  698: 	      flags |= F_IPV4;
  699: 	    }
  700: #ifdef HAVE_IPV6
  701: 	  else if (qtype == T_AAAA)
  702: 	    {
  703: 	      addrlen = IN6ADDRSZ;
  704: 	      flags |= F_IPV6;
  705: 	    }
  706: #endif
  707: 	  else 
  708: 	    continue;
  709: 	    
  710: 	cname_loop1:
  711: 	  if (!(p1 = skip_questions(header, qlen)))
  712: 	    return 0;
  713: 	  
  714: 	  for (j = ntohs(header->ancount); j != 0; j--) 
  715: 	    {
  716: 	      if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
  717: 		return 0; /* bad packet */
  718: 	      
  719: 	      GETSHORT(aqtype, p1); 
  720: 	      GETSHORT(aqclass, p1);
  721: 	      GETLONG(attl, p1);
  722: 	      if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
  723: 		{
  724: 		  (p1) -= 4;
  725: 		  PUTLONG(daemon->max_ttl, p1);
  726: 		}
  727: 	      GETSHORT(ardlen, p1);
  728: 	      endrr = p1+ardlen;
  729: 	      
  730: 	      if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
  731: 		{
  732: 		  if (aqtype == T_CNAME)
  733: 		    {
  734: 		      if (!cname_count--)
  735: 			return 0; /* looped CNAMES */
  736: 		      newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD | secflag);
  737: 		      if (newc)
  738: 			{
  739: 			  newc->addr.cname.target.cache = NULL;
  740: 			  /* anything other than zero, to avoid being mistaken for CNAME to interface-name */ 
  741: 			  newc->addr.cname.uid = 1; 
  742: 			  if (cpp)
  743: 			    {
  744: 			      cpp->addr.cname.target.cache = newc;
  745: 			      cpp->addr.cname.uid = newc->uid;
  746: 			    }
  747: 			}
  748: 		      
  749: 		      cpp = newc;
  750: 		      if (attl < cttl)
  751: 			cttl = attl;
  752: 		      
  753: 		      if (!extract_name(header, qlen, &p1, name, 1, 0))
  754: 			return 0;
  755: 		      goto cname_loop1;
  756: 		    }
  757: 		  else if (!(flags & F_NXDOMAIN))
  758: 		    {
  759: 		      found = 1;
  760: 		      
  761: 		      /* copy address into aligned storage */
  762: 		      if (!CHECK_LEN(header, p1, qlen, addrlen))
  763: 			return 0; /* bad packet */
  764: 		      memcpy(&addr, p1, addrlen);
  765: 		      
  766: 		      /* check for returned address in private space */
  767: 		      if (check_rebind)
  768: 			{
  769: 			  if ((flags & F_IPV4) &&
  770: 			      private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
  771: 			    return 1;
  772: 			  
  773: #ifdef HAVE_IPV6
  774: 			  if ((flags & F_IPV6) &&
  775: 			      IN6_IS_ADDR_V4MAPPED(&addr.addr.addr6))
  776: 			    {
  777: 			      struct in_addr v4;
  778: 			      v4.s_addr = ((const uint32_t *) (&addr.addr.addr6))[3];
  779: 			      if (private_net(v4, !option_bool(OPT_LOCAL_REBIND)))
  780: 				return 1;
  781: 			    }
  782: #endif
  783: 			}
  784: 		      
  785: #ifdef HAVE_IPSET
  786: 		      if (ipsets && (flags & (F_IPV4 | F_IPV6)))
  787: 			{
  788: 			  ipsets_cur = ipsets;
  789: 			  while (*ipsets_cur)
  790: 			    {
  791: 			      log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur);
  792: 			      add_to_ipset(*ipsets_cur++, &addr, flags, 0);
  793: 			    }
  794: 			}
  795: #endif
  796: 		      
  797: 		      newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD | secflag);
  798: 		      if (newc && cpp)
  799: 			{
  800: 			  cpp->addr.cname.target.cache = newc;
  801: 			  cpp->addr.cname.uid = newc->uid;
  802: 			}
  803: 		      cpp = NULL;
  804: 		    }
  805: 		}
  806: 	      
  807: 	      p1 = endrr;
  808: 	      if (!CHECK_LEN(header, p1, qlen, 0))
  809: 		return 0; /* bad packet */
  810: 	    }
  811: 	  
  812: 	  if (!found && !option_bool(OPT_NO_NEG))
  813: 	    {
  814: 	      if (!searched_soa)
  815: 		{
  816: 		  searched_soa = 1;
  817: 		  ttl = find_soa(header, qlen, NULL, doctored);
  818: 		}
  819: 	      /* If there's no SOA to get the TTL from, but there is a CNAME 
  820: 		 pointing at this, inherit its TTL */
  821: 	      if (ttl || cpp)
  822: 		{
  823: 		  newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | secflag);	
  824: 		  if (newc && cpp)
  825: 		    {
  826: 		      cpp->addr.cname.target.cache = newc;
  827: 		      cpp->addr.cname.uid = newc->uid;
  828: 		    }
  829: 		}
  830: 	    }
  831: 	}
  832:     }
  833:   
  834:   /* Don't put stuff from a truncated packet into the cache.
  835:      Don't cache replies from non-recursive nameservers, since we may get a 
  836:      reply containing a CNAME but not its target, even though the target 
  837:      does exist. */
  838:   if (!(header->hb3 & HB3_TC) && 
  839:       !(header->hb4 & HB4_CD) &&
  840:       (header->hb4 & HB4_RA) &&
  841:       !no_cache_dnssec)
  842:     cache_end_insert();
  843: 
  844:   return 0;
  845: }
  846: 
  847: /* If the packet holds exactly one query
  848:    return F_IPV4 or F_IPV6  and leave the name from the query in name */
  849: unsigned int extract_request(struct dns_header *header, size_t qlen, char *name, unsigned short *typep)
  850: {
  851:   unsigned char *p = (unsigned char *)(header+1);
  852:   int qtype, qclass;
  853: 
  854:   if (typep)
  855:     *typep = 0;
  856: 
  857:   if (ntohs(header->qdcount) != 1 || OPCODE(header) != QUERY)
  858:     return 0; /* must be exactly one query. */
  859:   
  860:   if (!extract_name(header, qlen, &p, name, 1, 4))
  861:     return 0; /* bad packet */
  862:    
  863:   GETSHORT(qtype, p); 
  864:   GETSHORT(qclass, p);
  865: 
  866:   if (typep)
  867:     *typep = qtype;
  868: 
  869:   if (qclass == C_IN)
  870:     {
  871:       if (qtype == T_A)
  872: 	return F_IPV4;
  873:       if (qtype == T_AAAA)
  874: 	return F_IPV6;
  875:       if (qtype == T_ANY)
  876: 	return  F_IPV4 | F_IPV6;
  877:     }
  878:   
  879:   return F_QUERY;
  880: }
  881: 
  882: 
  883: size_t setup_reply(struct dns_header *header, size_t qlen,
  884: 		struct all_addr *addrp, unsigned int flags, unsigned long ttl)
  885: {
  886:   unsigned char *p;
  887: 
  888:   if (!(p = skip_questions(header, qlen)))
  889:     return 0;
  890:   
  891:   /* clear authoritative and truncated flags, set QR flag */
  892:   header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
  893:   /* set RA flag */
  894:   header->hb4 |= HB4_RA;
  895: 
  896:   header->nscount = htons(0);
  897:   header->arcount = htons(0);
  898:   header->ancount = htons(0); /* no answers unless changed below */
  899:   if (flags == F_NOERR)
  900:     SET_RCODE(header, NOERROR); /* empty domain */
  901:   else if (flags == F_NXDOMAIN)
  902:     SET_RCODE(header, NXDOMAIN);
  903:   else if (flags == F_IPV4)
  904:     { /* we know the address */
  905:       SET_RCODE(header, NOERROR);
  906:       header->ancount = htons(1);
  907:       header->hb3 |= HB3_AA;
  908:       add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_A, C_IN, "4", addrp);
  909:     }
  910: #ifdef HAVE_IPV6
  911:   else if (flags == F_IPV6)
  912:     {
  913:       SET_RCODE(header, NOERROR);
  914:       header->ancount = htons(1);
  915:       header->hb3 |= HB3_AA;
  916:       add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
  917:     }
  918: #endif
  919:   else /* nowhere to forward to */
  920:     SET_RCODE(header, REFUSED);
  921:  
  922:   return p - (unsigned char *)header;
  923: }
  924: 
  925: /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
  926: int check_for_local_domain(char *name, time_t now)
  927: {
  928:   struct crec *crecp;
  929:   struct mx_srv_record *mx;
  930:   struct txt_record *txt;
  931:   struct interface_name *intr;
  932:   struct ptr_record *ptr;
  933:   struct naptr *naptr;
  934: 
  935:   /* Note: the call to cache_find_by_name is intended to find any record which matches
  936:      ie A, AAAA, CNAME. */
  937: 
  938:   if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME |F_NO_RR)) &&
  939:       (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
  940:     return 1;
  941:   
  942:   for (naptr = daemon->naptr; naptr; naptr = naptr->next)
  943:      if (hostname_isequal(name, naptr->name))
  944:       return 1;
  945: 
  946:    for (mx = daemon->mxnames; mx; mx = mx->next)
  947:     if (hostname_isequal(name, mx->name))
  948:       return 1;
  949: 
  950:   for (txt = daemon->txt; txt; txt = txt->next)
  951:     if (hostname_isequal(name, txt->name))
  952:       return 1;
  953: 
  954:   for (intr = daemon->int_names; intr; intr = intr->next)
  955:     if (hostname_isequal(name, intr->name))
  956:       return 1;
  957: 
  958:   for (ptr = daemon->ptr; ptr; ptr = ptr->next)
  959:     if (hostname_isequal(name, ptr->name))
  960:       return 1;
  961:  
  962:   return 0;
  963: }
  964: 
  965: /* Is the packet a reply with the answer address equal to addr?
  966:    If so mung is into an NXDOMAIN reply and also put that information
  967:    in the cache. */
  968: int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, 
  969: 			     struct bogus_addr *baddr, time_t now)
  970: {
  971:   unsigned char *p;
  972:   int i, qtype, qclass, rdlen;
  973:   unsigned long ttl;
  974:   struct bogus_addr *baddrp;
  975: 
  976:   /* skip over questions */
  977:   if (!(p = skip_questions(header, qlen)))
  978:     return 0; /* bad packet */
  979: 
  980:   for (i = ntohs(header->ancount); i != 0; i--)
  981:     {
  982:       if (!extract_name(header, qlen, &p, name, 1, 10))
  983: 	return 0; /* bad packet */
  984:   
  985:       GETSHORT(qtype, p); 
  986:       GETSHORT(qclass, p);
  987:       GETLONG(ttl, p);
  988:       GETSHORT(rdlen, p);
  989:       
  990:       if (qclass == C_IN && qtype == T_A)
  991: 	{
  992: 	  if (!CHECK_LEN(header, p, qlen, INADDRSZ))
  993: 	    return 0;
  994: 	  
  995: 	  for (baddrp = baddr; baddrp; baddrp = baddrp->next)
  996: 	    if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
  997: 	      {
  998: 		/* Found a bogus address. Insert that info here, since there no SOA record
  999: 		   to get the ttl from in the normal processing */
 1000: 		cache_start_insert();
 1001: 		cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
 1002: 		cache_end_insert();
 1003: 		
 1004: 		return 1;
 1005: 	      }
 1006: 	}
 1007:       
 1008:       if (!ADD_RDLEN(header, p, qlen, rdlen))
 1009: 	return 0;
 1010:     }
 1011:   
 1012:   return 0;
 1013: }
 1014: 
 1015: int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr)
 1016: {
 1017:   unsigned char *p;
 1018:   int i, qtype, qclass, rdlen;
 1019:   struct bogus_addr *baddrp;
 1020: 
 1021:   /* skip over questions */
 1022:   if (!(p = skip_questions(header, qlen)))
 1023:     return 0; /* bad packet */
 1024: 
 1025:   for (i = ntohs(header->ancount); i != 0; i--)
 1026:     {
 1027:       if (!(p = skip_name(p, header, qlen, 10)))
 1028: 	return 0; /* bad packet */
 1029:       
 1030:       GETSHORT(qtype, p); 
 1031:       GETSHORT(qclass, p);
 1032:       p += 4; /* TTL */
 1033:       GETSHORT(rdlen, p);
 1034:       
 1035:       if (qclass == C_IN && qtype == T_A)
 1036: 	{
 1037: 	  if (!CHECK_LEN(header, p, qlen, INADDRSZ))
 1038: 	    return 0;
 1039: 	  
 1040: 	  for (baddrp = baddr; baddrp; baddrp = baddrp->next)
 1041: 	    if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
 1042: 	      return 1;
 1043: 	}
 1044:       
 1045:       if (!ADD_RDLEN(header, p, qlen, rdlen))
 1046: 	return 0;
 1047:     }
 1048:   
 1049:   return 0;
 1050: }
 1051: 
 1052: int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp, 
 1053: 			unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
 1054: {
 1055:   va_list ap;
 1056:   unsigned char *sav, *p = *pp;
 1057:   int j;
 1058:   unsigned short usval;
 1059:   long lval;
 1060:   char *sval;
 1061: 
 1062:   if (truncp && *truncp)
 1063:     return 0;
 1064:  
 1065:   va_start(ap, format);   /* make ap point to 1st unamed argument */
 1066:   
 1067:   if (nameoffset > 0)
 1068:     {
 1069:       PUTSHORT(nameoffset | 0xc000, p);
 1070:     }
 1071:   else
 1072:     {
 1073:       char *name = va_arg(ap, char *);
 1074:       if (name)
 1075: 	p = do_rfc1035_name(p, name);
 1076:       if (nameoffset < 0)
 1077: 	{
 1078: 	  PUTSHORT(-nameoffset | 0xc000, p);
 1079: 	}
 1080:       else
 1081: 	*p++ = 0;
 1082:     }
 1083: 
 1084:   PUTSHORT(type, p);
 1085:   PUTSHORT(class, p);
 1086:   PUTLONG(ttl, p);      /* TTL */
 1087: 
 1088:   sav = p;              /* Save pointer to RDLength field */
 1089:   PUTSHORT(0, p);       /* Placeholder RDLength */
 1090: 
 1091:   for (; *format; format++)
 1092:     switch (*format)
 1093:       {
 1094: #ifdef HAVE_IPV6
 1095:       case '6':
 1096: 	sval = va_arg(ap, char *); 
 1097: 	memcpy(p, sval, IN6ADDRSZ);
 1098: 	p += IN6ADDRSZ;
 1099: 	break;
 1100: #endif
 1101: 	
 1102:       case '4':
 1103: 	sval = va_arg(ap, char *); 
 1104: 	memcpy(p, sval, INADDRSZ);
 1105: 	p += INADDRSZ;
 1106: 	break;
 1107: 	
 1108:       case 'b':
 1109: 	usval = va_arg(ap, int);
 1110: 	*p++ = usval;
 1111: 	break;
 1112: 	
 1113:       case 's':
 1114: 	usval = va_arg(ap, int);
 1115: 	PUTSHORT(usval, p);
 1116: 	break;
 1117: 	
 1118:       case 'l':
 1119: 	lval = va_arg(ap, long);
 1120: 	PUTLONG(lval, p);
 1121: 	break;
 1122: 	
 1123:       case 'd':
 1124: 	/* get domain-name answer arg and store it in RDATA field */
 1125: 	if (offset)
 1126: 	  *offset = p - (unsigned char *)header;
 1127: 	p = do_rfc1035_name(p, va_arg(ap, char *));
 1128: 	*p++ = 0;
 1129: 	break;
 1130: 	
 1131:       case 't':
 1132: 	usval = va_arg(ap, int);
 1133: 	sval = va_arg(ap, char *);
 1134: 	if (usval != 0)
 1135: 	  memcpy(p, sval, usval);
 1136: 	p += usval;
 1137: 	break;
 1138: 
 1139:       case 'z':
 1140: 	sval = va_arg(ap, char *);
 1141: 	usval = sval ? strlen(sval) : 0;
 1142: 	if (usval > 255)
 1143: 	  usval = 255;
 1144: 	*p++ = (unsigned char)usval;
 1145: 	memcpy(p, sval, usval);
 1146: 	p += usval;
 1147: 	break;
 1148:       }
 1149: 
 1150:   va_end(ap);	/* clean up variable argument pointer */
 1151:   
 1152:   j = p - sav - 2;
 1153:   PUTSHORT(j, sav);     /* Now, store real RDLength */
 1154:   
 1155:   /* check for overflow of buffer */
 1156:   if (limit && ((unsigned char *)limit - p) < 0)
 1157:     {
 1158:       if (truncp)
 1159: 	*truncp = 1;
 1160:       return 0;
 1161:     }
 1162:   
 1163:   *pp = p;
 1164:   return 1;
 1165: }
 1166: 
 1167: static unsigned long crec_ttl(struct crec *crecp, time_t now)
 1168: {
 1169:   /* Return 0 ttl for DHCP entries, which might change
 1170:      before the lease expires, unless configured otherwise. */
 1171: 
 1172:   if (crecp->flags & F_DHCP)
 1173:     {
 1174:       int conf_ttl = daemon->use_dhcp_ttl ? daemon->dhcp_ttl : daemon->local_ttl;
 1175:       
 1176:       /* Apply ceiling of actual lease length to configured TTL. */
 1177:       if (!(crecp->flags & F_IMMORTAL) && (crecp->ttd - now) < conf_ttl)
 1178: 	return crecp->ttd - now;
 1179:       
 1180:       return conf_ttl;
 1181:     }	  
 1182:   
 1183:   /* Immortal entries other than DHCP are local, and hold TTL in TTD field. */
 1184:   if (crecp->flags & F_IMMORTAL)
 1185:     return crecp->ttd;
 1186: 
 1187:   /* Return the Max TTL value if it is lower then the actual TTL */
 1188:   if (daemon->max_ttl == 0 || ((unsigned)(crecp->ttd - now) < daemon->max_ttl))
 1189:     return crecp->ttd - now;
 1190:   else
 1191:     return daemon->max_ttl;
 1192: }
 1193:   
 1194: 
 1195: /* return zero if we can't answer from cache, or packet size if we can */
 1196: size_t answer_request(struct dns_header *header, char *limit, size_t qlen,  
 1197: 		      struct in_addr local_addr, struct in_addr local_netmask, 
 1198: 		      time_t now, int ad_reqd, int do_bit, int have_pseudoheader) 
 1199: {
 1200:   char *name = daemon->namebuff;
 1201:   unsigned char *p, *ansp;
 1202:   unsigned int qtype, qclass;
 1203:   struct all_addr addr;
 1204:   int nameoffset;
 1205:   unsigned short flag;
 1206:   int q, ans, anscount = 0, addncount = 0;
 1207:   int dryrun = 0;
 1208:   struct crec *crecp;
 1209:   int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1;
 1210:   struct mx_srv_record *rec;
 1211:   size_t len;
 1212:   
 1213:   if (ntohs(header->ancount) != 0 ||
 1214:       ntohs(header->nscount) != 0 ||
 1215:       ntohs(header->qdcount) == 0 || 
 1216:       OPCODE(header) != QUERY )
 1217:     return 0;
 1218:   
 1219:   /* Don't return AD set if checking disabled. */
 1220:   if (header->hb4 & HB4_CD)
 1221:     sec_data = 0;
 1222:   
 1223:   /* If there is an  additional data section then it will be overwritten by
 1224:      partial replies, so we have to do a dry run to see if we can answer
 1225:      the query. */
 1226:   if (ntohs(header->arcount) != 0)
 1227:     dryrun = 1;
 1228: 
 1229:   for (rec = daemon->mxnames; rec; rec = rec->next)
 1230:     rec->offset = 0;
 1231:   
 1232:  rerun:
 1233:   /* determine end of question section (we put answers there) */
 1234:   if (!(ansp = skip_questions(header, qlen)))
 1235:     return 0; /* bad packet */
 1236:    
 1237:   /* now process each question, answers go in RRs after the question */
 1238:   p = (unsigned char *)(header+1);
 1239: 
 1240:   for (q = ntohs(header->qdcount); q != 0; q--)
 1241:     {
 1242:       /* save pointer to name for copying into answers */
 1243:       nameoffset = p - (unsigned char *)header;
 1244: 
 1245:       /* now extract name as .-concatenated string into name */
 1246:       if (!extract_name(header, qlen, &p, name, 1, 4))
 1247: 	return 0; /* bad packet */
 1248:             
 1249:       GETSHORT(qtype, p); 
 1250:       GETSHORT(qclass, p);
 1251: 
 1252:       ans = 0; /* have we answered this question */
 1253:       
 1254:       if (qtype == T_TXT || qtype == T_ANY)
 1255: 	{
 1256: 	  struct txt_record *t;
 1257: 	  for(t = daemon->txt; t ; t = t->next)
 1258: 	    {
 1259: 	      if (t->class == qclass && hostname_isequal(name, t->name))
 1260: 		{
 1261: 		  ans = 1;
 1262: 		  if (!dryrun)
 1263: 		    {
 1264: 		      unsigned long ttl = daemon->local_ttl;
 1265: 		      int ok = 1;
 1266: 		      log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
 1267: 		      /* Dynamically generate stat record */
 1268: 		      if (t->stat != 0)
 1269: 			{
 1270: 			  ttl = 0;
 1271: 			  if (!cache_make_stat(t))
 1272: 			    ok = 0;
 1273: 			}
 1274: 		      
 1275: 		      if (ok && add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1276: 						    ttl, NULL,
 1277: 						    T_TXT, t->class, "t", t->len, t->txt))
 1278: 			anscount++;
 1279: 
 1280: 		    }
 1281: 		}
 1282: 	    }
 1283: 	}
 1284: 
 1285:       if (qclass == C_IN)
 1286: 	{
 1287: 	  struct txt_record *t;
 1288: 
 1289: 	  for (t = daemon->rr; t; t = t->next)
 1290: 	    if ((t->class == qtype || qtype == T_ANY) && hostname_isequal(name, t->name))
 1291: 	      {
 1292: 		ans = 1;
 1293: 		sec_data = 0;
 1294: 		if (!dryrun)
 1295: 		  {
 1296: 		    log_query(F_CONFIG | F_RRNAME, name, NULL, "<RR>");
 1297: 		    if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1298: 					    daemon->local_ttl, NULL,
 1299: 					    t->class, C_IN, "t", t->len, t->txt))
 1300: 		      anscount ++;
 1301: 		  }
 1302: 	      }
 1303: 		
 1304: 	  if (qtype == T_PTR || qtype == T_ANY)
 1305: 	    {
 1306: 	      /* see if it's w.z.y.z.in-addr.arpa format */
 1307: 	      int is_arpa = in_arpa_name_2_addr(name, &addr);
 1308: 	      struct ptr_record *ptr;
 1309: 	      struct interface_name* intr = NULL;
 1310: 
 1311: 	      for (ptr = daemon->ptr; ptr; ptr = ptr->next)
 1312: 		if (hostname_isequal(name, ptr->name))
 1313: 		  break;
 1314: 
 1315: 	      if (is_arpa == F_IPV4)
 1316: 		for (intr = daemon->int_names; intr; intr = intr->next)
 1317: 		  {
 1318: 		    struct addrlist *addrlist;
 1319: 		    
 1320: 		    for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
 1321: 		      if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
 1322: 			break;
 1323: 		    
 1324: 		    if (addrlist)
 1325: 		      break;
 1326: 		    else
 1327: 		      while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
 1328: 			intr = intr->next;
 1329: 		  }
 1330: #ifdef HAVE_IPV6
 1331: 	      else if (is_arpa == F_IPV6)
 1332: 		for (intr = daemon->int_names; intr; intr = intr->next)
 1333: 		  {
 1334: 		    struct addrlist *addrlist;
 1335: 		    
 1336: 		    for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
 1337: 		      if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
 1338: 			break;
 1339: 		    
 1340: 		    if (addrlist)
 1341: 		      break;
 1342: 		    else
 1343: 		      while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
 1344: 			intr = intr->next;
 1345: 		  }
 1346: #endif
 1347: 	      
 1348: 	      if (intr)
 1349: 		{
 1350: 		  sec_data = 0;
 1351: 		  ans = 1;
 1352: 		  if (!dryrun)
 1353: 		    {
 1354: 		      log_query(is_arpa | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
 1355: 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1356: 					      daemon->local_ttl, NULL,
 1357: 					      T_PTR, C_IN, "d", intr->name))
 1358: 			anscount++;
 1359: 		    }
 1360: 		}
 1361: 	      else if (ptr)
 1362: 		{
 1363: 		  ans = 1;
 1364: 		  sec_data = 0;
 1365: 		  if (!dryrun)
 1366: 		    {
 1367: 		      log_query(F_CONFIG | F_RRNAME, name, NULL, "<PTR>");
 1368: 		      for (ptr = daemon->ptr; ptr; ptr = ptr->next)
 1369: 			if (hostname_isequal(name, ptr->name) &&
 1370: 			    add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1371: 						daemon->local_ttl, NULL,
 1372: 						T_PTR, C_IN, "d", ptr->ptr))
 1373: 			  anscount++;
 1374: 			 
 1375: 		    }
 1376: 		}
 1377: 	      else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
 1378: 		{
 1379: 		  /* Don't use cache when DNSSEC data required, unless we know that
 1380: 		     the zone is unsigned, which implies that we're doing
 1381: 		     validation. */
 1382: 		  if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || 
 1383: 		      !do_bit || 
 1384: 		      (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))
 1385: 		    {
 1386: 		      do 
 1387: 			{ 
 1388: 			  /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
 1389: 			  if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
 1390: 			    continue;
 1391: 			  
 1392: 			  if (!(crecp->flags & F_DNSSECOK))
 1393: 			    sec_data = 0;
 1394: 			   
 1395: 			  ans = 1;
 1396: 			   
 1397: 			  if (crecp->flags & F_NEG)
 1398: 			    {
 1399: 			      auth = 0;
 1400: 			      if (crecp->flags & F_NXDOMAIN)
 1401: 				nxdomain = 1;
 1402: 			      if (!dryrun)
 1403: 				log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
 1404: 			    }
 1405: 			  else
 1406: 			    {
 1407: 			      if (!(crecp->flags & (F_HOSTS | F_DHCP)))
 1408: 				auth = 0;
 1409: 			      if (!dryrun)
 1410: 				{
 1411: 				  log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr, 
 1412: 					    record_source(crecp->uid));
 1413: 				  
 1414: 				  if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1415: 							  crec_ttl(crecp, now), NULL,
 1416: 							  T_PTR, C_IN, "d", cache_get_name(crecp)))
 1417: 				    anscount++;
 1418: 				}
 1419: 			    }
 1420: 			} while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
 1421: 		    }
 1422: 		}
 1423: 	      else if (is_rev_synth(is_arpa, &addr, name))
 1424: 		{
 1425: 		  ans = 1;
 1426: 		  sec_data = 0;
 1427: 		  if (!dryrun)
 1428: 		    {
 1429: 		      log_query(F_CONFIG | F_REVERSE | is_arpa, name, &addr, NULL); 
 1430: 		      
 1431: 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1432: 					      daemon->local_ttl, NULL,
 1433: 					      T_PTR, C_IN, "d", name))
 1434: 			      anscount++;
 1435: 		    }
 1436: 		}
 1437: 	      else if (is_arpa == F_IPV4 && 
 1438: 		       option_bool(OPT_BOGUSPRIV) && 
 1439: 		       private_net(addr.addr.addr4, 1))
 1440: 		{
 1441: 		  /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
 1442: 		  ans = 1;
 1443: 		  sec_data = 0;
 1444: 		  nxdomain = 1;
 1445: 		  if (!dryrun)
 1446: 		    log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN, 
 1447: 			      name, &addr, NULL);
 1448: 		}
 1449: 	    }
 1450: 	    
 1451: 	  for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
 1452: 	    {
 1453: 	      unsigned short type = T_A;
 1454: 	      struct interface_name *intr;
 1455: 
 1456: 	      if (flag == F_IPV6)
 1457: #ifdef HAVE_IPV6
 1458: 		type = T_AAAA;
 1459: #else
 1460: 	        break;
 1461: #endif
 1462: 	      
 1463: 	      if (qtype != type && qtype != T_ANY)
 1464: 		continue;
 1465: 	      
 1466: 	      /* Check for "A for A"  queries; be rather conservative 
 1467: 		 about what looks like dotted-quad.  */
 1468: 	      if (qtype == T_A)
 1469: 		{
 1470: 		  char *cp;
 1471: 		  unsigned int i, a;
 1472: 		  int x;
 1473: 
 1474: 		  for (cp = name, i = 0, a = 0; *cp; i++)
 1475: 		    {
 1476: 		      if (!isdigit((unsigned char)*cp) || (x = strtol(cp, &cp, 10)) > 255) 
 1477: 			{
 1478: 			  i = 5;
 1479: 			  break;
 1480: 			}
 1481: 		      
 1482: 		      a = (a << 8) + x;
 1483: 		      
 1484: 		      if (*cp == '.') 
 1485: 			cp++;
 1486: 		    }
 1487: 		  
 1488: 		  if (i == 4)
 1489: 		    {
 1490: 		      ans = 1;
 1491: 		      sec_data = 0;
 1492: 		      if (!dryrun)
 1493: 			{
 1494: 			  addr.addr.addr4.s_addr = htonl(a);
 1495: 			  log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
 1496: 			  if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1497: 						  daemon->local_ttl, NULL, type, C_IN, "4", &addr))
 1498: 			    anscount++;
 1499: 			}
 1500: 		      continue;
 1501: 		    }
 1502: 		}
 1503: 
 1504: 	      /* interface name stuff */
 1505: 	    intname_restart:
 1506: 	      for (intr = daemon->int_names; intr; intr = intr->next)
 1507: 		if (hostname_isequal(name, intr->name))
 1508: 		  break;
 1509: 	      
 1510: 	      if (intr)
 1511: 		{
 1512: 		  struct addrlist *addrlist;
 1513: 		  int gotit = 0;
 1514: 
 1515: 		  enumerate_interfaces(0);
 1516: 		  
 1517: 		  for (intr = daemon->int_names; intr; intr = intr->next)
 1518: 		    if (hostname_isequal(name, intr->name))
 1519: 		      {
 1520: 			for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
 1521: #ifdef HAVE_IPV6
 1522: 			  if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
 1523: #endif
 1524: 			    {
 1525: #ifdef HAVE_IPV6
 1526: 			      if (addrlist->flags & ADDRLIST_REVONLY)
 1527: 				continue;
 1528: #endif	
 1529: 			      ans = 1;	
 1530: 			      sec_data = 0;
 1531: 			      if (!dryrun)
 1532: 				{
 1533: 				  gotit = 1;
 1534: 				  log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
 1535: 				  if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1536: 							  daemon->local_ttl, NULL, type, C_IN, 
 1537: 							  type == T_A ? "4" : "6", &addrlist->addr))
 1538: 				    anscount++;
 1539: 				}
 1540: 			    }
 1541: 		      }
 1542: 		  
 1543: 		  if (!dryrun && !gotit)
 1544: 		    log_query(F_FORWARD | F_CONFIG | flag | F_NEG, name, NULL, NULL);
 1545: 		     
 1546: 		  continue;
 1547: 		}
 1548: 
 1549: 	    cname_restart:
 1550: 	      if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME | (dryrun ? F_NO_RR : 0))))
 1551: 		{
 1552: 		  int localise = 0;
 1553: 		  
 1554: 		  /* See if a putative address is on the network from which we recieved
 1555: 		     the query, is so we'll filter other answers. */
 1556: 		  if (local_addr.s_addr != 0 && option_bool(OPT_LOCALISE) && flag == F_IPV4)
 1557: 		    {
 1558: 		      struct crec *save = crecp;
 1559: 		      do {
 1560: 			if ((crecp->flags & F_HOSTS) &&
 1561: 			    is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
 1562: 			  {
 1563: 			    localise = 1;
 1564: 			    break;
 1565: 			  } 
 1566: 			} while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
 1567: 		      crecp = save;
 1568: 		    }
 1569: 
 1570: 		  /* If the client asked for DNSSEC  don't use cached data. */
 1571: 		  if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !do_bit || !(crecp->flags & F_DNSSECOK))
 1572: 		    do
 1573: 		      { 
 1574: 			/* don't answer wildcard queries with data not from /etc/hosts
 1575: 			   or DHCP leases */
 1576: 			if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
 1577: 			  break;
 1578: 			
 1579: 			if (!(crecp->flags & F_DNSSECOK))
 1580: 			  sec_data = 0;
 1581: 			
 1582: 			if (crecp->flags & F_CNAME)
 1583: 			  {
 1584: 			    char *cname_target = cache_get_cname_target(crecp);
 1585: 			    
 1586: 			    if (!dryrun)
 1587: 			      {
 1588: 				log_query(crecp->flags, name, NULL, record_source(crecp->uid));
 1589: 				if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1590: 							crec_ttl(crecp, now), &nameoffset,
 1591: 							T_CNAME, C_IN, "d", cname_target))
 1592: 				  anscount++;
 1593: 			      }
 1594: 			    
 1595: 			    strcpy(name, cname_target);
 1596: 			    /* check if target interface_name */
 1597: 			    if (crecp->addr.cname.uid == SRC_INTERFACE)
 1598: 			      goto intname_restart;
 1599: 			    else
 1600: 			      goto cname_restart;
 1601: 			  }
 1602: 			
 1603: 			if (crecp->flags & F_NEG)
 1604: 			  {
 1605: 			    ans = 1;
 1606: 			    auth = 0;
 1607: 			    if (crecp->flags & F_NXDOMAIN)
 1608: 			      nxdomain = 1;
 1609: 			    if (!dryrun)
 1610: 			      log_query(crecp->flags, name, NULL, NULL);
 1611: 			  }
 1612: 			else 
 1613: 			  {
 1614: 			    /* If we are returning local answers depending on network,
 1615: 			       filter here. */
 1616: 			    if (localise && 
 1617: 				(crecp->flags & F_HOSTS) &&
 1618: 				!is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
 1619: 			      continue;
 1620: 			    
 1621: 			    if (!(crecp->flags & (F_HOSTS | F_DHCP)))
 1622: 			      auth = 0;
 1623: 			    
 1624: 			    ans = 1;
 1625: 			    if (!dryrun)
 1626: 			      {
 1627: 				log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
 1628: 					  record_source(crecp->uid));
 1629: 				
 1630: 				if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1631: 							crec_ttl(crecp, now), NULL, type, C_IN, 
 1632: 							type == T_A ? "4" : "6", &crecp->addr))
 1633: 				  anscount++;
 1634: 			      }
 1635: 			  }
 1636: 		      } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
 1637: 		}
 1638: 	      else if (is_name_synthetic(flag, name, &addr))
 1639: 		{
 1640: 		  ans = 1;
 1641: 		  if (!dryrun)
 1642: 		    {
 1643: 		      log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
 1644: 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1645: 					      daemon->local_ttl, NULL, type, C_IN, type == T_A ? "4" : "6", &addr))
 1646: 			anscount++;
 1647: 		    }
 1648: 		}
 1649: 	    }
 1650: 
 1651: 	  if (qtype == T_CNAME || qtype == T_ANY)
 1652: 	    {
 1653: 	      if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME)) &&
 1654: 		  (qtype == T_CNAME || (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG  | (dryrun ? F_NO_RR : 0)))))
 1655: 		{
 1656: 		  if (!(crecp->flags & F_DNSSECOK))
 1657: 		    sec_data = 0;
 1658: 		  
 1659: 		  ans = 1;
 1660: 		  if (!dryrun)
 1661: 		    {
 1662: 		      log_query(crecp->flags, name, NULL, record_source(crecp->uid));
 1663: 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1664: 					      crec_ttl(crecp, now), &nameoffset,
 1665: 					      T_CNAME, C_IN, "d", cache_get_cname_target(crecp)))
 1666: 			anscount++;
 1667: 		    }
 1668: 		}
 1669: 	    }
 1670: 
 1671: 	  if (qtype == T_MX || qtype == T_ANY)
 1672: 	    {
 1673: 	      int found = 0;
 1674: 	      for (rec = daemon->mxnames; rec; rec = rec->next)
 1675: 		if (!rec->issrv && hostname_isequal(name, rec->name))
 1676: 		  {
 1677: 		  ans = found = 1;
 1678: 		  if (!dryrun)
 1679: 		    {
 1680: 		      int offset;
 1681: 		      log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
 1682: 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
 1683: 					      &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
 1684: 			{
 1685: 			  anscount++;
 1686: 			  if (rec->target)
 1687: 			    rec->offset = offset;
 1688: 			}
 1689: 		    }
 1690: 		  }
 1691: 	      
 1692: 	      if (!found && (option_bool(OPT_SELFMX) || option_bool(OPT_LOCALMX)) && 
 1693: 		  cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP | F_NO_RR))
 1694: 		{ 
 1695: 		  ans = 1;
 1696: 		  if (!dryrun)
 1697: 		    {
 1698: 		      log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
 1699: 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL, 
 1700: 					      T_MX, C_IN, "sd", 1, 
 1701: 					      option_bool(OPT_SELFMX) ? name : daemon->mxtarget))
 1702: 			anscount++;
 1703: 		    }
 1704: 		}
 1705: 	    }
 1706: 	  	  
 1707: 	  if (qtype == T_SRV || qtype == T_ANY)
 1708: 	    {
 1709: 	      int found = 0;
 1710: 	      struct mx_srv_record *move = NULL, **up = &daemon->mxnames;
 1711: 
 1712: 	      for (rec = daemon->mxnames; rec; rec = rec->next)
 1713: 		if (rec->issrv && hostname_isequal(name, rec->name))
 1714: 		  {
 1715: 		    found = ans = 1;
 1716: 		    if (!dryrun)
 1717: 		      {
 1718: 			int offset;
 1719: 			log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>");
 1720: 			if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, 
 1721: 						&offset, T_SRV, C_IN, "sssd", 
 1722: 						rec->priority, rec->weight, rec->srvport, rec->target))
 1723: 			  {
 1724: 			    anscount++;
 1725: 			    if (rec->target)
 1726: 			      rec->offset = offset;
 1727: 			  }
 1728: 		      }
 1729: 		    
 1730: 		    /* unlink first SRV record found */
 1731: 		    if (!move)
 1732: 		      {
 1733: 			move = rec;
 1734: 			*up = rec->next;
 1735: 		      }
 1736: 		    else
 1737: 		      up = &rec->next;      
 1738: 		  }
 1739: 		else
 1740: 		  up = &rec->next;
 1741: 
 1742: 	      /* put first SRV record back at the end. */
 1743: 	      if (move)
 1744: 		{
 1745: 		  *up = move;
 1746: 		  move->next = NULL;
 1747: 		}
 1748: 	      
 1749: 	      if (!found && option_bool(OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
 1750: 		{
 1751: 		  ans = 1;
 1752: 		  if (!dryrun)
 1753: 		    log_query(F_CONFIG | F_NEG, name, NULL, NULL);
 1754: 		}
 1755: 	    }
 1756: 
 1757: 	  if (qtype == T_NAPTR || qtype == T_ANY)
 1758: 	    {
 1759: 	      struct naptr *na;
 1760: 	      for (na = daemon->naptr; na; na = na->next)
 1761: 		if (hostname_isequal(name, na->name))
 1762: 		  {
 1763: 		    ans = 1;
 1764: 		    if (!dryrun)
 1765: 		      {
 1766: 			log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>");
 1767: 			if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, 
 1768: 						NULL, T_NAPTR, C_IN, "sszzzd", 
 1769: 						na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
 1770: 			  anscount++;
 1771: 		      }
 1772: 		  }
 1773: 	    }
 1774: 	  
 1775: 	  if (qtype == T_MAILB)
 1776: 	    ans = 1, nxdomain = 1;
 1777: 
 1778: 	  if (qtype == T_SOA && option_bool(OPT_FILTER))
 1779: 	    {
 1780: 	      ans = 1; 
 1781: 	      if (!dryrun)
 1782: 		log_query(F_CONFIG | F_NEG, name, &addr, NULL);
 1783: 	    }
 1784: 	}
 1785: 
 1786:       if (!ans)
 1787: 	return 0; /* failed to answer a question */
 1788:     }
 1789:   
 1790:   if (dryrun)
 1791:     {
 1792:       dryrun = 0;
 1793:       goto rerun;
 1794:     }
 1795:   
 1796:   /* create an additional data section, for stuff in SRV and MX record replies. */
 1797:   for (rec = daemon->mxnames; rec; rec = rec->next)
 1798:     if (rec->offset != 0)
 1799:       {
 1800: 	/* squash dupes */
 1801: 	struct mx_srv_record *tmp;
 1802: 	for (tmp = rec->next; tmp; tmp = tmp->next)
 1803: 	  if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
 1804: 	    tmp->offset = 0;
 1805: 	
 1806: 	crecp = NULL;
 1807: 	while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
 1808: 	  {
 1809: #ifdef HAVE_IPV6
 1810: 	    int type =  crecp->flags & F_IPV4 ? T_A : T_AAAA;
 1811: #else
 1812: 	    int type = T_A;
 1813: #endif
 1814: 	    if (crecp->flags & F_NEG)
 1815: 	      continue;
 1816: 
 1817: 	    if (add_resource_record(header, limit, NULL, rec->offset, &ansp, 
 1818: 				    crec_ttl(crecp, now), NULL, type, C_IN, 
 1819: 				    crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
 1820: 	      addncount++;
 1821: 	  }
 1822:       }
 1823:   
 1824:   /* done all questions, set up header and return length of result */
 1825:   /* clear authoritative and truncated flags, set QR flag */
 1826:   header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
 1827:   /* set RA flag */
 1828:   header->hb4 |= HB4_RA;
 1829:    
 1830:   /* authoritive - only hosts and DHCP derived names. */
 1831:   if (auth)
 1832:     header->hb3 |= HB3_AA;
 1833:   
 1834:   /* truncation */
 1835:   if (trunc)
 1836:     header->hb3 |= HB3_TC;
 1837:   
 1838:   if (nxdomain)
 1839:     SET_RCODE(header, NXDOMAIN);
 1840:   else
 1841:     SET_RCODE(header, NOERROR); /* no error */
 1842:   header->ancount = htons(anscount);
 1843:   header->nscount = htons(0);
 1844:   header->arcount = htons(addncount);
 1845: 
 1846:   len = ansp - (unsigned char *)header;
 1847:   
 1848:   /* Advertise our packet size limit in our reply */
 1849:   if (have_pseudoheader)
 1850:     len = add_pseudoheader(header, len, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
 1851:   
 1852:   if (ad_reqd && sec_data)
 1853:     header->hb4 |= HB4_AD;
 1854:   else
 1855:     header->hb4 &= ~HB4_AD;
 1856:   
 1857:   return len;
 1858: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>