File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / rfc1035.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:56:46 2021 UTC (3 years, 4 months ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v2_84, HEAD
dnsmasq 2.84

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

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