File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / rfc1035.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:31:38 2014 UTC (10 years, 1 month ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v2_71, HEAD
dnsmasq 2.71

    1: /* dnsmasq is Copyright (c) 2000-2014 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, 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 == 0x80)
   81: 	return 0; /* reserved */
   82:       else if (label_type == 0x40)
   83: 	{ /* ELT */
   84: 	  unsigned int count, digs;
   85: 	  
   86: 	  if ((l & 0x3f) != 1)
   87: 	    return 0; /* we only understand bitstrings */
   88: 
   89: 	  if (!isExtract)
   90: 	    return 0; /* Cannot compare bitsrings */
   91: 	  
   92: 	  count = *p++;
   93: 	  if (count == 0)
   94: 	    count = 256;
   95: 	  digs = ((count-1)>>2)+1;
   96: 	  
   97: 	  /* output is \[x<hex>/siz]. which is digs+9 chars */
   98: 	  if (cp - (unsigned char *)name + digs + 9 >= MAXDNAME)
   99: 	    return 0;
  100: 	  if (!CHECK_LEN(header, p, plen, (count-1)>>3))
  101: 	    return 0;
  102: 
  103: 	  *cp++ = '\\';
  104: 	  *cp++ = '[';
  105: 	  *cp++ = 'x';
  106: 	  for (j=0; j<digs; j++)
  107: 	    {
  108: 	      unsigned int dig;
  109: 	      if (j%2 == 0)
  110: 		dig = *p >> 4;
  111: 	      else
  112: 		dig = *p++ & 0x0f;
  113: 	      
  114: 	      *cp++ = dig < 10 ? dig + '0' : dig + 'A' - 10;
  115: 	    } 
  116: 	  cp += sprintf((char *)cp, "/%d]", count);
  117: 	  /* do this here to overwrite the zero char from sprintf */
  118: 	  *cp++ = '.';
  119: 	}
  120:       else 
  121: 	{ /* label_type = 0 -> label. */
  122: 	  if (cp - (unsigned char *)name + l + 1 >= MAXDNAME)
  123: 	    return 0;
  124: 	  if (!CHECK_LEN(header, p, plen, l))
  125: 	    return 0;
  126: 	  
  127: 	  for(j=0; j<l; j++, p++)
  128: 	    if (isExtract)
  129: 	      {
  130: 		unsigned char c = *p;
  131: 		if (isascii(c) && !iscntrl(c) && c != '.')
  132: 		  *cp++ = *p;
  133: 		else
  134: 		  return 0;
  135: 	      }
  136: 	    else 
  137: 	      {
  138: 		unsigned char c1 = *cp, c2 = *p;
  139: 		
  140: 		if (c1 == 0)
  141: 		  retvalue = 2;
  142: 		else 
  143: 		  {
  144: 		    cp++;
  145: 		    if (c1 >= 'A' && c1 <= 'Z')
  146: 		      c1 += 'a' - 'A';
  147: 		    if (c2 >= 'A' && c2 <= 'Z')
  148: 		      c2 += 'a' - 'A';
  149: 		    
  150: 		    if (c1 != c2)
  151: 		      retvalue =  2;
  152: 		  }
  153: 	      }
  154: 	  
  155: 	  if (isExtract)
  156: 	    *cp++ = '.';
  157: 	  else if (*cp != 0 && *cp++ != '.')
  158: 	    retvalue = 2;
  159: 	}
  160:     }
  161: }
  162:  
  163: /* Max size of input string (for IPv6) is 75 chars.) */
  164: #define MAXARPANAME 75
  165: int in_arpa_name_2_addr(char *namein, struct all_addr *addrp)
  166: {
  167:   int j;
  168:   char name[MAXARPANAME+1], *cp1;
  169:   unsigned char *addr = (unsigned char *)addrp;
  170:   char *lastchunk = NULL, *penchunk = NULL;
  171:   
  172:   if (strlen(namein) > MAXARPANAME)
  173:     return 0;
  174: 
  175:   memset(addrp, 0, sizeof(struct all_addr));
  176: 
  177:   /* turn name into a series of asciiz strings */
  178:   /* j counts no of labels */
  179:   for(j = 1,cp1 = name; *namein; cp1++, namein++)
  180:     if (*namein == '.')
  181:       {
  182: 	penchunk = lastchunk;
  183:         lastchunk = cp1 + 1;
  184: 	*cp1 = 0;
  185: 	j++;
  186:       }
  187:     else
  188:       *cp1 = *namein;
  189:   
  190:   *cp1 = 0;
  191: 
  192:   if (j<3)
  193:     return 0;
  194: 
  195:   if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr"))
  196:     {
  197:       /* IP v4 */
  198:       /* address arives as a name of the form
  199: 	 www.xxx.yyy.zzz.in-addr.arpa
  200: 	 some of the low order address octets might be missing
  201: 	 and should be set to zero. */
  202:       for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
  203: 	{
  204: 	  /* check for digits only (weeds out things like
  205: 	     50.0/24.67.28.64.in-addr.arpa which are used 
  206: 	     as CNAME targets according to RFC 2317 */
  207: 	  char *cp;
  208: 	  for (cp = cp1; *cp; cp++)
  209: 	    if (!isdigit((unsigned char)*cp))
  210: 	      return 0;
  211: 	  
  212: 	  addr[3] = addr[2];
  213: 	  addr[2] = addr[1];
  214: 	  addr[1] = addr[0];
  215: 	  addr[0] = atoi(cp1);
  216: 	}
  217: 
  218:       return F_IPV4;
  219:     }
  220: #ifdef HAVE_IPV6
  221:   else if (hostname_isequal(penchunk, "ip6") && 
  222: 	   (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa")))
  223:     {
  224:       /* IP v6:
  225:          Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
  226:     	 or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]
  227:       
  228: 	 Note that most of these the various reprentations are obsolete and 
  229: 	 left-over from the many DNS-for-IPv6 wars. We support all the formats
  230: 	 that we can since there is no reason not to.
  231:       */
  232: 
  233:       if (*name == '\\' && *(name+1) == '[' && 
  234: 	  (*(name+2) == 'x' || *(name+2) == 'X'))
  235: 	{	  
  236: 	  for (j = 0, cp1 = name+3; *cp1 && isxdigit((unsigned char) *cp1) && j < 32; cp1++, j++)
  237: 	    {
  238: 	      char xdig[2];
  239: 	      xdig[0] = *cp1;
  240: 	      xdig[1] = 0;
  241: 	      if (j%2)
  242: 		addr[j/2] |= strtol(xdig, NULL, 16);
  243: 	      else
  244: 		addr[j/2] = strtol(xdig, NULL, 16) << 4;
  245: 	    }
  246: 	  
  247: 	  if (*cp1 == '/' && j == 32)
  248: 	    return F_IPV6;
  249: 	}
  250:       else
  251: 	{
  252: 	  for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1)
  253: 	    {
  254: 	      if (*(cp1+1) || !isxdigit((unsigned char)*cp1))
  255: 		return 0;
  256: 	      
  257: 	      for (j = sizeof(struct all_addr)-1; j>0; j--)
  258: 		addr[j] = (addr[j] >> 4) | (addr[j-1] << 4);
  259: 	      addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
  260: 	    }
  261: 	  
  262: 	  return F_IPV6;
  263: 	}
  264:     }
  265: #endif
  266:   
  267:   return 0;
  268: }
  269: 
  270: unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes)
  271: {
  272:   while(1)
  273:     {
  274:       unsigned int label_type;
  275:       
  276:       if (!CHECK_LEN(header, ansp, plen, 1))
  277: 	return NULL;
  278:       
  279:       label_type = (*ansp) & 0xc0;
  280: 
  281:       if (label_type == 0xc0)
  282: 	{
  283: 	  /* pointer for compression. */
  284: 	  ansp += 2;	
  285: 	  break;
  286: 	}
  287:       else if (label_type == 0x80)
  288: 	return NULL; /* reserved */
  289:       else if (label_type == 0x40)
  290: 	{
  291: 	  /* Extended label type */
  292: 	  unsigned int count;
  293: 	  
  294: 	  if (!CHECK_LEN(header, ansp, plen, 2))
  295: 	    return NULL;
  296: 	  
  297: 	  if (((*ansp++) & 0x3f) != 1)
  298: 	    return NULL; /* we only understand bitstrings */
  299: 	  
  300: 	  count = *(ansp++); /* Bits in bitstring */
  301: 	  
  302: 	  if (count == 0) /* count == 0 means 256 bits */
  303: 	    ansp += 32;
  304: 	  else
  305: 	    ansp += ((count-1)>>3)+1;
  306: 	}
  307:       else
  308: 	{ /* label type == 0 Bottom six bits is length */
  309: 	  unsigned int len = (*ansp++) & 0x3f;
  310: 	  
  311: 	  if (!ADD_RDLEN(header, ansp, plen, len))
  312: 	    return NULL;
  313: 
  314: 	  if (len == 0)
  315: 	    break; /* zero length label marks the end. */
  316: 	}
  317:     }
  318: 
  319:   if (!CHECK_LEN(header, ansp, plen, extrabytes))
  320:     return NULL;
  321:   
  322:   return ansp;
  323: }
  324: 
  325: unsigned char *skip_questions(struct dns_header *header, size_t plen)
  326: {
  327:   int q;
  328:   unsigned char *ansp = (unsigned char *)(header+1);
  329: 
  330:   for (q = ntohs(header->qdcount); q != 0; q--)
  331:     {
  332:       if (!(ansp = skip_name(ansp, header, plen, 4)))
  333: 	return NULL;
  334:       ansp += 4; /* class and type */
  335:     }
  336:   
  337:   return ansp;
  338: }
  339: 
  340: unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen)
  341: {
  342:   int i, rdlen;
  343:   
  344:   for (i = 0; i < count; i++)
  345:     {
  346:       if (!(ansp = skip_name(ansp, header, plen, 10)))
  347: 	return NULL; 
  348:       ansp += 8; /* type, class, TTL */
  349:       GETSHORT(rdlen, ansp);
  350:       if (!ADD_RDLEN(header, ansp, plen, rdlen))
  351: 	return NULL;
  352:     }
  353: 
  354:   return ansp;
  355: }
  356: 
  357: /* CRC the question section. This is used to safely detect query 
  358:    retransmision and to detect answers to questions we didn't ask, which 
  359:    might be poisoning attacks. Note that we decode the name rather 
  360:    than CRC the raw bytes, since replies might be compressed differently. 
  361:    We ignore case in the names for the same reason. Return all-ones
  362:    if there is not question section. */
  363: #ifndef HAVE_DNSSEC
  364: unsigned int questions_crc(struct dns_header *header, size_t plen, char *name)
  365: {
  366:   int q;
  367:   unsigned int crc = 0xffffffff;
  368:   unsigned char *p1, *p = (unsigned char *)(header+1);
  369: 
  370:   for (q = ntohs(header->qdcount); q != 0; q--) 
  371:     {
  372:       if (!extract_name(header, plen, &p, name, 1, 4))
  373: 	return crc; /* bad packet */
  374:       
  375:       for (p1 = (unsigned char *)name; *p1; p1++)
  376: 	{
  377: 	  int i = 8;
  378: 	  char c = *p1;
  379: 
  380: 	  if (c >= 'A' && c <= 'Z')
  381: 	    c += 'a' - 'A';
  382: 
  383: 	  crc ^= c << 24;
  384: 	  while (i--)
  385: 	    crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
  386: 	}
  387:       
  388:       /* CRC the class and type as well */
  389:       for (p1 = p; p1 < p+4; p1++)
  390: 	{
  391: 	  int i = 8;
  392: 	  crc ^= *p1 << 24;
  393: 	  while (i--)
  394: 	    crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
  395: 	}
  396: 
  397:       p += 4;
  398:       if (!CHECK_LEN(header, p, plen, 0))
  399: 	return crc; /* bad packet */
  400:     }
  401: 
  402:   return crc;
  403: }
  404: #endif
  405: 
  406: size_t resize_packet(struct dns_header *header, size_t plen, unsigned char *pheader, size_t hlen)
  407: {
  408:   unsigned char *ansp = skip_questions(header, plen);
  409:     
  410:   /* if packet is malformed, just return as-is. */
  411:   if (!ansp)
  412:     return plen;
  413:   
  414:   if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
  415: 			    header, plen)))
  416:     return plen;
  417:     
  418:   /* restore pseudoheader */
  419:   if (pheader && ntohs(header->arcount) == 0)
  420:     {
  421:       /* must use memmove, may overlap */
  422:       memmove(ansp, pheader, hlen);
  423:       header->arcount = htons(1);
  424:       ansp += hlen;
  425:     }
  426: 
  427:   return ansp - (unsigned char *)header;
  428: }
  429: 
  430: unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, size_t  *len, unsigned char **p, int *is_sign)
  431: {
  432:   /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it. 
  433:      also return length of pseudoheader in *len and pointer to the UDP size in *p
  434:      Finally, check to see if a packet is signed. If it is we cannot change a single bit before
  435:      forwarding. We look for SIG and TSIG in the addition section, and TKEY queries (for GSS-TSIG) */
  436:   
  437:   int i, arcount = ntohs(header->arcount);
  438:   unsigned char *ansp = (unsigned char *)(header+1);
  439:   unsigned short rdlen, type, class;
  440:   unsigned char *ret = NULL;
  441: 
  442:   if (is_sign)
  443:     {
  444:       *is_sign = 0;
  445: 
  446:       if (OPCODE(header) == QUERY)
  447: 	{
  448: 	  for (i = ntohs(header->qdcount); i != 0; i--)
  449: 	    {
  450: 	      if (!(ansp = skip_name(ansp, header, plen, 4)))
  451: 		return NULL;
  452: 	      
  453: 	      GETSHORT(type, ansp); 
  454: 	      GETSHORT(class, ansp);
  455: 	      
  456: 	      if (class == C_IN && type == T_TKEY)
  457: 		*is_sign = 1;
  458: 	    }
  459: 	}
  460:     }
  461:   else
  462:     {
  463:       if (!(ansp = skip_questions(header, plen)))
  464: 	return NULL;
  465:     }
  466:     
  467:   if (arcount == 0)
  468:     return NULL;
  469:   
  470:   if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount), header, plen)))
  471:     return NULL; 
  472:   
  473:   for (i = 0; i < arcount; i++)
  474:     {
  475:       unsigned char *save, *start = ansp;
  476:       if (!(ansp = skip_name(ansp, header, plen, 10)))
  477: 	return NULL; 
  478: 
  479:       GETSHORT(type, ansp);
  480:       save = ansp;
  481:       GETSHORT(class, ansp);
  482:       ansp += 4; /* TTL */
  483:       GETSHORT(rdlen, ansp);
  484:       if (!ADD_RDLEN(header, ansp, plen, rdlen))
  485: 	return NULL;
  486:       if (type == T_OPT)
  487: 	{
  488: 	  if (len)
  489: 	    *len = ansp - start;
  490: 	  if (p)
  491: 	    *p = save;
  492: 	  ret = start;
  493: 	}
  494:       else if (is_sign && 
  495: 	       i == arcount - 1 && 
  496: 	       class == C_ANY && 
  497: 	       type == T_TSIG)
  498: 	*is_sign = 1;
  499:     }
  500:   
  501:   return ret;
  502: }
  503: 
  504: struct macparm {
  505:   unsigned char *limit;
  506:   struct dns_header *header;
  507:   size_t plen;
  508:   union mysockaddr *l3;
  509: };
  510:  
  511: static size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit, 
  512: 			       int optno, unsigned char *opt, size_t optlen, int set_do)
  513: { 
  514:   unsigned char *lenp, *datap, *p;
  515:   int rdlen, is_sign;
  516:   
  517:   if (!(p = find_pseudoheader(header, plen, NULL, NULL, &is_sign)))
  518:     {
  519:       if (is_sign)
  520: 	return plen;
  521: 
  522:       /* We are adding the pseudoheader */
  523:       if (!(p = skip_questions(header, plen)) ||
  524: 	  !(p = skip_section(p, 
  525: 			     ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount), 
  526: 			     header, plen)))
  527: 	return plen;
  528:       *p++ = 0; /* empty name */
  529:       PUTSHORT(T_OPT, p);
  530:       PUTSHORT(daemon->edns_pktsz, p); /* max packet length */
  531:       PUTSHORT(0, p);    /* extended RCODE and version */
  532:       PUTSHORT(set_do ? 0x8000 : 0, p); /* DO flag */
  533:       lenp = p;
  534:       PUTSHORT(0, p);    /* RDLEN */
  535:       rdlen = 0;
  536:       if (((ssize_t)optlen) > (limit - (p + 4)))
  537: 	return plen; /* Too big */
  538:       header->arcount = htons(ntohs(header->arcount) + 1);
  539:       datap = p;
  540:     }
  541:   else
  542:     {
  543:       int i;
  544:       unsigned short code, len, flags;
  545:       
  546:       /* Must be at the end, if exists */
  547:       if (ntohs(header->arcount) != 1 ||
  548: 	  is_sign ||
  549: 	  (!(p = skip_name(p, header, plen, 10))))
  550: 	return plen;
  551:       
  552:       p += 6; /* skip UDP length and RCODE */
  553:       GETSHORT(flags, p);
  554:       if (set_do)
  555: 	{
  556: 	  p -=2;
  557: 	  PUTSHORT(flags | 0x8000, p);
  558: 	}
  559: 
  560:       lenp = p;
  561:       GETSHORT(rdlen, p);
  562:       if (!CHECK_LEN(header, p, plen, rdlen))
  563: 	return plen; /* bad packet */
  564:       datap = p;
  565: 
  566:        /* no option to add */
  567:       if (optno == 0)
  568: 	return plen;
  569:       	  
  570:       /* check if option already there */
  571:       for (i = 0; i + 4 < rdlen; i += len + 4)
  572: 	{
  573: 	  GETSHORT(code, p);
  574: 	  GETSHORT(len, p);
  575: 	  if (code == optno)
  576: 	    return plen;
  577: 	  p += len;
  578: 	}
  579:       
  580:       if (((ssize_t)optlen) > (limit - (p + 4)))
  581: 	return plen; /* Too big */
  582:     }
  583:   
  584:   if (optno != 0)
  585:     {
  586:       PUTSHORT(optno, p);
  587:       PUTSHORT(optlen, p);
  588:       memcpy(p, opt, optlen);
  589:       p += optlen;  
  590:     }
  591: 
  592:   PUTSHORT(p - datap, lenp);
  593:   return p - (unsigned char *)header;
  594:   
  595: }
  596: 
  597: static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *parmv)
  598: {
  599:   struct macparm *parm = parmv;
  600:   int match = 0;
  601:     
  602:   if (family == parm->l3->sa.sa_family)
  603:     {
  604:       if (family == AF_INET && memcmp(&parm->l3->in.sin_addr, addrp, INADDRSZ) == 0)
  605: 	match = 1;
  606: #ifdef HAVE_IPV6
  607:       else
  608: 	if (family == AF_INET6 && memcmp(&parm->l3->in6.sin6_addr, addrp, IN6ADDRSZ) == 0)
  609: 	  match = 1;
  610: #endif
  611:     }
  612:  
  613:   if (!match)
  614:     return 1; /* continue */
  615: 
  616:   parm->plen = add_pseudoheader(parm->header, parm->plen, parm->limit,  EDNS0_OPTION_MAC, (unsigned char *)mac, maclen, 0);
  617:   
  618:   return 0; /* done */
  619: }	      
  620:      
  621: size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysockaddr *l3)
  622: {
  623:   struct macparm parm;
  624:      
  625: /* Must have an existing pseudoheader as the only ar-record, 
  626:    or have no ar-records. Must also not be signed */
  627:    
  628:   if (ntohs(header->arcount) > 1)
  629:     return plen;
  630: 
  631:   parm.header = header;
  632:   parm.limit = (unsigned char *)limit;
  633:   parm.plen = plen;
  634:   parm.l3 = l3;
  635: 
  636:   iface_enumerate(AF_UNSPEC, &parm, filter_mac);
  637:   
  638:   return parm.plen; 
  639: }
  640: 
  641: struct subnet_opt {
  642:   u16 family;
  643:   u8 source_netmask, scope_netmask;
  644: #ifdef HAVE_IPV6 
  645:   u8 addr[IN6ADDRSZ];
  646: #else
  647:   u8 addr[INADDRSZ];
  648: #endif
  649: };
  650: 
  651: static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
  652: {
  653:   /* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
  654:   
  655:   int len;
  656:   void *addrp;
  657: 
  658: #ifdef HAVE_IPV6
  659:   if (source->sa.sa_family == AF_INET6)
  660:     {
  661:       opt->family = htons(2);
  662:       opt->source_netmask = daemon->addr6_netmask;
  663:       addrp = &source->in6.sin6_addr;
  664:     }
  665:   else
  666: #endif
  667:     {
  668:       opt->family = htons(1);
  669:       opt->source_netmask = daemon->addr4_netmask;
  670:       addrp = &source->in.sin_addr;
  671:     }
  672:   
  673:   opt->scope_netmask = 0;
  674:   len = 0;
  675:   
  676:   if (opt->source_netmask != 0)
  677:     {
  678:       len = ((opt->source_netmask - 1) >> 3) + 1;
  679:       memcpy(opt->addr, addrp, len);
  680:       if (opt->source_netmask & 7)
  681: 	opt->addr[len-1] &= 0xff << (8 - (opt->source_netmask & 7));
  682:     }
  683: 
  684:   return len + 4;
  685: }
  686:  
  687: size_t add_source_addr(struct dns_header *header, size_t plen, char *limit, union mysockaddr *source)
  688: {
  689:   /* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
  690:   
  691:   int len;
  692:   struct subnet_opt opt;
  693:   
  694:   len = calc_subnet_opt(&opt, source);
  695:   return add_pseudoheader(header, plen, (unsigned char *)limit, EDNS0_OPTION_CLIENT_SUBNET, (unsigned char *)&opt, len, 0);
  696: }
  697: 
  698: #ifdef HAVE_DNSSEC
  699: size_t add_do_bit(struct dns_header *header, size_t plen, char *limit)
  700: {
  701:   return add_pseudoheader(header, plen, (unsigned char *)limit, 0, NULL, 0, 1);
  702: }
  703: #endif
  704: 
  705: int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer)
  706: {
  707:   /* Section 9.2, Check that subnet option in reply matches. */
  708: 
  709: 
  710:  int len, calc_len;
  711:   struct subnet_opt opt;
  712:   unsigned char *p;
  713:   int code, i, rdlen;
  714:   
  715:    calc_len = calc_subnet_opt(&opt, peer);
  716:    
  717:    if (!(p = skip_name(pseudoheader, header, plen, 10)))
  718:      return 1;
  719:    
  720:    p += 8; /* skip UDP length and RCODE */
  721:    
  722:    GETSHORT(rdlen, p);
  723:    if (!CHECK_LEN(header, p, plen, rdlen))
  724:      return 1; /* bad packet */
  725:    
  726:    /* check if option there */
  727:    for (i = 0; i + 4 < rdlen; i += len + 4)
  728:      {
  729:        GETSHORT(code, p);
  730:        GETSHORT(len, p);
  731:        if (code == EDNS0_OPTION_CLIENT_SUBNET)
  732: 	 {
  733: 	   /* make sure this doesn't mismatch. */
  734: 	   opt.scope_netmask = p[3];
  735: 	   if (len != calc_len || memcmp(p, &opt, len) != 0)
  736: 	     return 0;
  737: 	 }
  738:        p += len;
  739:      }
  740:    
  741:    return 1;
  742: }
  743: 
  744: /* is addr in the non-globally-routed IP space? */ 
  745: int private_net(struct in_addr addr, int ban_localhost) 
  746: {
  747:   in_addr_t ip_addr = ntohl(addr.s_addr);
  748: 
  749:   return
  750:     (((ip_addr & 0xFF000000) == 0x7F000000) && ban_localhost)  /* 127.0.0.0/8    (loopback) */ || 
  751:     ((ip_addr & 0xFFFF0000) == 0xC0A80000)  /* 192.168.0.0/16 (private)  */ ||
  752:     ((ip_addr & 0xFF000000) == 0x0A000000)  /* 10.0.0.0/8     (private)  */ ||
  753:     ((ip_addr & 0xFFF00000) == 0xAC100000)  /* 172.16.0.0/12  (private)  */ ||
  754:     ((ip_addr & 0xFFFF0000) == 0xA9FE0000)  /* 169.254.0.0/16 (zeroconf) */ ;
  755: }
  756: 
  757: static unsigned char *do_doctor(unsigned char *p, int count, struct dns_header *header, size_t qlen, char *name, int *doctored)
  758: {
  759:   int i, qtype, qclass, rdlen;
  760: 
  761:   for (i = count; i != 0; i--)
  762:     {
  763:       if (name && option_bool(OPT_LOG))
  764: 	{
  765: 	  if (!extract_name(header, qlen, &p, name, 1, 10))
  766: 	    return 0;
  767: 	}
  768:       else if (!(p = skip_name(p, header, qlen, 10)))
  769: 	return 0; /* bad packet */
  770:       
  771:       GETSHORT(qtype, p); 
  772:       GETSHORT(qclass, p);
  773:       p += 4; /* ttl */
  774:       GETSHORT(rdlen, p);
  775:       
  776:       if (qclass == C_IN && qtype == T_A)
  777: 	{
  778: 	  struct doctor *doctor;
  779: 	  struct in_addr addr;
  780: 	  
  781: 	  if (!CHECK_LEN(header, p, qlen, INADDRSZ))
  782: 	    return 0;
  783: 	  
  784: 	  /* alignment */
  785: 	  memcpy(&addr, p, INADDRSZ);
  786: 	  
  787: 	  for (doctor = daemon->doctors; doctor; doctor = doctor->next)
  788: 	    {
  789: 	      if (doctor->end.s_addr == 0)
  790: 		{
  791: 		  if (!is_same_net(doctor->in, addr, doctor->mask))
  792: 		    continue;
  793: 		}
  794: 	      else if (ntohl(doctor->in.s_addr) > ntohl(addr.s_addr) || 
  795: 		       ntohl(doctor->end.s_addr) < ntohl(addr.s_addr))
  796: 		continue;
  797: 	      
  798: 	      addr.s_addr &= ~doctor->mask.s_addr;
  799: 	      addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
  800: 	      /* Since we munged the data, the server it came from is no longer authoritative */
  801: 	      header->hb3 &= ~HB3_AA;
  802: 	      *doctored = 1;
  803: 	      memcpy(p, &addr, INADDRSZ);
  804: 	      break;
  805: 	    }
  806: 	}
  807:       else if (qtype == T_TXT && name && option_bool(OPT_LOG))
  808: 	{
  809: 	  unsigned char *p1 = p;
  810: 	  if (!CHECK_LEN(header, p1, qlen, rdlen))
  811: 	    return 0;
  812: 	  while ((p1 - p) < rdlen)
  813: 	    {
  814: 	      unsigned int i, len = *p1;
  815: 	      unsigned char *p2 = p1;
  816: 	      /* make counted string zero-term  and sanitise */
  817: 	      for (i = 0; i < len; i++)
  818: 		{
  819: 		  if (!isprint((int)*(p2+1)))
  820: 		    break;
  821: 		  
  822: 		  *p2 = *(p2+1);
  823: 		  p2++;
  824: 		}
  825: 	      *p2 = 0;
  826: 	      my_syslog(LOG_INFO, "reply %s is %s", name, p1);
  827: 	      /* restore */
  828: 	      memmove(p1 + 1, p1, i);
  829: 	      *p1 = len;
  830: 	      p1 += len+1;
  831: 	    }
  832: 	}		  
  833:       
  834:       if (!ADD_RDLEN(header, p, qlen, rdlen))
  835: 	 return 0; /* bad packet */
  836:     }
  837:   
  838:   return p; 
  839: }
  840: 
  841: static int find_soa(struct dns_header *header, size_t qlen, char *name, int *doctored)
  842: {
  843:   unsigned char *p;
  844:   int qtype, qclass, rdlen;
  845:   unsigned long ttl, minttl = ULONG_MAX;
  846:   int i, found_soa = 0;
  847:   
  848:   /* first move to NS section and find TTL from any SOA section */
  849:   if (!(p = skip_questions(header, qlen)) ||
  850:       !(p = do_doctor(p, ntohs(header->ancount), header, qlen, name, doctored)))
  851:     return 0;  /* bad packet */
  852:   
  853:   for (i = ntohs(header->nscount); i != 0; i--)
  854:     {
  855:       if (!(p = skip_name(p, header, qlen, 10)))
  856: 	return 0; /* bad packet */
  857:       
  858:       GETSHORT(qtype, p); 
  859:       GETSHORT(qclass, p);
  860:       GETLONG(ttl, p);
  861:       GETSHORT(rdlen, p);
  862:       
  863:       if ((qclass == C_IN) && (qtype == T_SOA))
  864: 	{
  865: 	  found_soa = 1;
  866: 	  if (ttl < minttl)
  867: 	    minttl = ttl;
  868: 
  869: 	  /* MNAME */
  870: 	  if (!(p = skip_name(p, header, qlen, 0)))
  871: 	    return 0;
  872: 	  /* RNAME */
  873: 	  if (!(p = skip_name(p, header, qlen, 20)))
  874: 	    return 0;
  875: 	  p += 16; /* SERIAL REFRESH RETRY EXPIRE */
  876: 	  
  877: 	  GETLONG(ttl, p); /* minTTL */
  878: 	  if (ttl < minttl)
  879: 	    minttl = ttl;
  880: 	}
  881:       else if (!ADD_RDLEN(header, p, qlen, rdlen))
  882: 	return 0; /* bad packet */
  883:     }
  884:   
  885:   /* rewrite addresses in additional section too */
  886:   if (!do_doctor(p, ntohs(header->arcount), header, qlen, NULL, doctored))
  887:     return 0;
  888:   
  889:   if (!found_soa)
  890:     minttl = daemon->neg_ttl;
  891: 
  892:   return minttl;
  893: }
  894: 
  895: /* Note that the following code can create CNAME chains that don't point to a real record,
  896:    either because of lack of memory, or lack of SOA records.  These are treated by the cache code as 
  897:    expired and cleaned out that way. 
  898:    Return 1 if we reject an address because it look like part of dns-rebinding attack. */
  899: int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t now, 
  900: 		      char **ipsets, int is_sign, int check_rebind, int no_cache_dnssec, int secure, int *doctored)
  901: {
  902:   unsigned char *p, *p1, *endrr, *namep;
  903:   int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
  904:   unsigned long ttl = 0;
  905:   struct all_addr addr;
  906: #ifdef HAVE_IPSET
  907:   char **ipsets_cur;
  908: #else
  909:   (void)ipsets; /* unused */
  910: #endif
  911:   
  912:   cache_start_insert();
  913: 
  914:   /* find_soa is needed for dns_doctor and logging side-effects, so don't call it lazily if there are any. */
  915:   if (daemon->doctors || option_bool(OPT_LOG) || option_bool(OPT_DNSSEC_VALID))
  916:     {
  917:       searched_soa = 1;
  918:       ttl = find_soa(header, qlen, name, doctored);
  919: #ifdef HAVE_DNSSEC
  920:       if (*doctored && secure)
  921: 	return 0;
  922: #endif
  923:     }
  924:   
  925:   /* go through the questions. */
  926:   p = (unsigned char *)(header+1);
  927:   
  928:   for (i = ntohs(header->qdcount); i != 0; i--)
  929:     {
  930:       int found = 0, cname_count = CNAME_CHAIN;
  931:       struct crec *cpp = NULL;
  932:       int flags = RCODE(header) == NXDOMAIN ? F_NXDOMAIN : 0;
  933:       int secflag = secure ?  F_DNSSECOK : 0;
  934:       unsigned long cttl = ULONG_MAX, attl;
  935: 
  936:       namep = p;
  937:       if (!extract_name(header, qlen, &p, name, 1, 4))
  938: 	return 0; /* bad packet */
  939:            
  940:       GETSHORT(qtype, p); 
  941:       GETSHORT(qclass, p);
  942:       
  943:       if (qclass != C_IN)
  944: 	continue;
  945: 
  946:       /* PTRs: we chase CNAMEs here, since we have no way to 
  947: 	 represent them in the cache. */
  948:       if (qtype == T_PTR)
  949: 	{ 
  950: 	  int name_encoding = in_arpa_name_2_addr(name, &addr);
  951: 	  
  952: 	  if (!name_encoding)
  953: 	    continue;
  954: 
  955: 	  if (!(flags & F_NXDOMAIN))
  956: 	    {
  957: 	    cname_loop:
  958: 	      if (!(p1 = skip_questions(header, qlen)))
  959: 		return 0;
  960: 	      
  961: 	      for (j = ntohs(header->ancount); j != 0; j--) 
  962: 		{
  963: 		  unsigned char *tmp = namep;
  964: 		  /* the loop body overwrites the original name, so get it back here. */
  965: 		  if (!extract_name(header, qlen, &tmp, name, 1, 0) ||
  966: 		      !(res = extract_name(header, qlen, &p1, name, 0, 10)))
  967: 		    return 0; /* bad packet */
  968: 		  
  969: 		  GETSHORT(aqtype, p1); 
  970: 		  GETSHORT(aqclass, p1);
  971: 		  GETLONG(attl, p1);
  972: 		  if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
  973: 		    {
  974: 		      (p1) -= 4;
  975: 		      PUTLONG(daemon->max_ttl, p1);
  976: 		    }
  977: 		  GETSHORT(ardlen, p1);
  978: 		  endrr = p1+ardlen;
  979: 		  
  980: 		  /* TTL of record is minimum of CNAMES and PTR */
  981: 		  if (attl < cttl)
  982: 		    cttl = attl;
  983: 
  984: 		  if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR))
  985: 		    {
  986: 		      if (!extract_name(header, qlen, &p1, name, 1, 0))
  987: 			return 0;
  988: 		      
  989: 		      if (aqtype == T_CNAME)
  990: 			{
  991: 			  if (!cname_count-- || secure)
  992: 			    return 0; /* looped CNAMES, or DNSSEC, which we can't cache. */
  993: 			  goto cname_loop;
  994: 			}
  995: 		      
  996: 		      cache_insert(name, &addr, now, cttl, name_encoding | secflag | F_REVERSE);
  997: 		      found = 1; 
  998: 		    }
  999: 		  
 1000: 		  p1 = endrr;
 1001: 		  if (!CHECK_LEN(header, p1, qlen, 0))
 1002: 		    return 0; /* bad packet */
 1003: 		}
 1004: 	    }
 1005: 	  
 1006: 	   if (!found && !option_bool(OPT_NO_NEG))
 1007: 	    {
 1008: 	      if (!searched_soa)
 1009: 		{
 1010: 		  searched_soa = 1;
 1011: 		  ttl = find_soa(header, qlen, NULL, doctored);
 1012: 		}
 1013: 	      if (ttl)
 1014: 		cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags | secflag);	
 1015: 	    }
 1016: 	}
 1017:       else
 1018: 	{
 1019: 	  /* everything other than PTR */
 1020: 	  struct crec *newc;
 1021: 	  int addrlen;
 1022: 
 1023: 	  if (qtype == T_A)
 1024: 	    {
 1025: 	      addrlen = INADDRSZ;
 1026: 	      flags |= F_IPV4;
 1027: 	    }
 1028: #ifdef HAVE_IPV6
 1029: 	  else if (qtype == T_AAAA)
 1030: 	    {
 1031: 	      addrlen = IN6ADDRSZ;
 1032: 	      flags |= F_IPV6;
 1033: 	    }
 1034: #endif
 1035: 	  else 
 1036: 	    continue;
 1037: 	    
 1038: 	cname_loop1:
 1039: 	  if (!(p1 = skip_questions(header, qlen)))
 1040: 	    return 0;
 1041: 	  
 1042: 	  for (j = ntohs(header->ancount); j != 0; j--) 
 1043: 	    {
 1044: 	      if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
 1045: 		return 0; /* bad packet */
 1046: 	      
 1047: 	      GETSHORT(aqtype, p1); 
 1048: 	      GETSHORT(aqclass, p1);
 1049: 	      GETLONG(attl, p1);
 1050: 	      if ((daemon->max_ttl != 0) && (attl > daemon->max_ttl) && !is_sign)
 1051: 		{
 1052: 		  (p1) -= 4;
 1053: 		  PUTLONG(daemon->max_ttl, p1);
 1054: 		}
 1055: 	      GETSHORT(ardlen, p1);
 1056: 	      endrr = p1+ardlen;
 1057: 	      
 1058: 	      if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype))
 1059: 		{
 1060: 		  if (aqtype == T_CNAME)
 1061: 		    {
 1062: 		      if (!cname_count--)
 1063: 			return 0; /* looped CNAMES */
 1064: 		      newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD | secflag);
 1065: 		      if (newc)
 1066: 			{
 1067: 			  newc->addr.cname.target.cache = NULL;
 1068: 			  /* anything other than zero, to avoid being mistaken for CNAME to interface-name */ 
 1069: 			  newc->addr.cname.uid = 1; 
 1070: 			  if (cpp)
 1071: 			    {
 1072: 			      cpp->addr.cname.target.cache = newc;
 1073: 			      cpp->addr.cname.uid = newc->uid;
 1074: 			    }
 1075: 			}
 1076: 		      
 1077: 		      cpp = newc;
 1078: 		      if (attl < cttl)
 1079: 			cttl = attl;
 1080: 		      
 1081: 		      if (!extract_name(header, qlen, &p1, name, 1, 0))
 1082: 			return 0;
 1083: 		      goto cname_loop1;
 1084: 		    }
 1085: 		  else if (!(flags & F_NXDOMAIN))
 1086: 		    {
 1087: 		      found = 1;
 1088: 		      
 1089: 		      /* copy address into aligned storage */
 1090: 		      if (!CHECK_LEN(header, p1, qlen, addrlen))
 1091: 			return 0; /* bad packet */
 1092: 		      memcpy(&addr, p1, addrlen);
 1093: 		      
 1094: 		      /* check for returned address in private space */
 1095: 		      if (check_rebind &&
 1096: 			  (flags & F_IPV4) &&
 1097: 			  private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
 1098: 			return 1;
 1099: 		      
 1100: #ifdef HAVE_IPSET
 1101: 		      if (ipsets && (flags & (F_IPV4 | F_IPV6)))
 1102: 			{
 1103: 			  ipsets_cur = ipsets;
 1104: 			  while (*ipsets_cur)
 1105: 			    {
 1106: 			      log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur);
 1107: 			      add_to_ipset(*ipsets_cur++, &addr, flags, 0);
 1108: 			    }
 1109: 			}
 1110: #endif
 1111: 		      
 1112: 		      newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD | secflag);
 1113: 		      if (newc && cpp)
 1114: 			{
 1115: 			  cpp->addr.cname.target.cache = newc;
 1116: 			  cpp->addr.cname.uid = newc->uid;
 1117: 			}
 1118: 		      cpp = NULL;
 1119: 		    }
 1120: 		}
 1121: 	      
 1122: 	      p1 = endrr;
 1123: 	      if (!CHECK_LEN(header, p1, qlen, 0))
 1124: 		return 0; /* bad packet */
 1125: 	    }
 1126: 	  
 1127: 	  if (!found && !option_bool(OPT_NO_NEG))
 1128: 	    {
 1129: 	      if (!searched_soa)
 1130: 		{
 1131: 		  searched_soa = 1;
 1132: 		  ttl = find_soa(header, qlen, NULL, doctored);
 1133: 		}
 1134: 	      /* If there's no SOA to get the TTL from, but there is a CNAME 
 1135: 		 pointing at this, inherit its TTL */
 1136: 	      if (ttl || cpp)
 1137: 		{
 1138: 		  newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | secflag);	
 1139: 		  if (newc && cpp)
 1140: 		    {
 1141: 		      cpp->addr.cname.target.cache = newc;
 1142: 		      cpp->addr.cname.uid = newc->uid;
 1143: 		    }
 1144: 		}
 1145: 	    }
 1146: 	}
 1147:     }
 1148:   
 1149:   /* Don't put stuff from a truncated packet into the cache.
 1150:      Don't cache replies from non-recursive nameservers, since we may get a 
 1151:      reply containing a CNAME but not its target, even though the target 
 1152:      does exist. */
 1153:   if (!(header->hb3 & HB3_TC) && 
 1154:       !(header->hb4 & HB4_CD) &&
 1155:       (header->hb4 & HB4_RA) &&
 1156:       !no_cache_dnssec)
 1157:     cache_end_insert();
 1158: 
 1159:   return 0;
 1160: }
 1161: 
 1162: /* If the packet holds exactly one query
 1163:    return F_IPV4 or F_IPV6  and leave the name from the query in name */
 1164: unsigned int extract_request(struct dns_header *header, size_t qlen, char *name, unsigned short *typep)
 1165: {
 1166:   unsigned char *p = (unsigned char *)(header+1);
 1167:   int qtype, qclass;
 1168: 
 1169:   if (typep)
 1170:     *typep = 0;
 1171: 
 1172:   if (ntohs(header->qdcount) != 1 || OPCODE(header) != QUERY)
 1173:     return 0; /* must be exactly one query. */
 1174:   
 1175:   if (!extract_name(header, qlen, &p, name, 1, 4))
 1176:     return 0; /* bad packet */
 1177:    
 1178:   GETSHORT(qtype, p); 
 1179:   GETSHORT(qclass, p);
 1180: 
 1181:   if (typep)
 1182:     *typep = qtype;
 1183: 
 1184:   if (qclass == C_IN)
 1185:     {
 1186:       if (qtype == T_A)
 1187: 	return F_IPV4;
 1188:       if (qtype == T_AAAA)
 1189: 	return F_IPV6;
 1190:       if (qtype == T_ANY)
 1191: 	return  F_IPV4 | F_IPV6;
 1192:     }
 1193:   
 1194:   return F_QUERY;
 1195: }
 1196: 
 1197: 
 1198: size_t setup_reply(struct dns_header *header, size_t qlen,
 1199: 		struct all_addr *addrp, unsigned int flags, unsigned long ttl)
 1200: {
 1201:   unsigned char *p = skip_questions(header, qlen);
 1202:   
 1203:   /* clear authoritative and truncated flags, set QR flag */
 1204:   header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
 1205:   /* set RA flag */
 1206:   header->hb4 |= HB4_RA;
 1207: 
 1208:   header->nscount = htons(0);
 1209:   header->arcount = htons(0);
 1210:   header->ancount = htons(0); /* no answers unless changed below */
 1211:   if (flags == F_NEG)
 1212:     SET_RCODE(header, SERVFAIL); /* couldn't get memory */
 1213:   else if (flags == F_NOERR)
 1214:     SET_RCODE(header, NOERROR); /* empty domain */
 1215:   else if (flags == F_NXDOMAIN)
 1216:     SET_RCODE(header, NXDOMAIN);
 1217:   else if (p && flags == F_IPV4)
 1218:     { /* we know the address */
 1219:       SET_RCODE(header, NOERROR);
 1220:       header->ancount = htons(1);
 1221:       header->hb3 |= HB3_AA;
 1222:       add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_A, C_IN, "4", addrp);
 1223:     }
 1224: #ifdef HAVE_IPV6
 1225:   else if (p && flags == F_IPV6)
 1226:     {
 1227:       SET_RCODE(header, NOERROR);
 1228:       header->ancount = htons(1);
 1229:       header->hb3 |= HB3_AA;
 1230:       add_resource_record(header, NULL, NULL, sizeof(struct dns_header), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
 1231:     }
 1232: #endif
 1233:   else /* nowhere to forward to */
 1234:     SET_RCODE(header, REFUSED);
 1235:  
 1236:   return p - (unsigned char *)header;
 1237: }
 1238: 
 1239: /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
 1240: int check_for_local_domain(char *name, time_t now)
 1241: {
 1242:   struct crec *crecp;
 1243:   struct mx_srv_record *mx;
 1244:   struct txt_record *txt;
 1245:   struct interface_name *intr;
 1246:   struct ptr_record *ptr;
 1247:   struct naptr *naptr;
 1248: 
 1249:   if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME | F_DS | F_NO_RR)) &&
 1250:       (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
 1251:     return 1;
 1252:   
 1253:   for (naptr = daemon->naptr; naptr; naptr = naptr->next)
 1254:      if (hostname_isequal(name, naptr->name))
 1255:       return 1;
 1256: 
 1257:    for (mx = daemon->mxnames; mx; mx = mx->next)
 1258:     if (hostname_isequal(name, mx->name))
 1259:       return 1;
 1260: 
 1261:   for (txt = daemon->txt; txt; txt = txt->next)
 1262:     if (hostname_isequal(name, txt->name))
 1263:       return 1;
 1264: 
 1265:   for (intr = daemon->int_names; intr; intr = intr->next)
 1266:     if (hostname_isequal(name, intr->name))
 1267:       return 1;
 1268: 
 1269:   for (ptr = daemon->ptr; ptr; ptr = ptr->next)
 1270:     if (hostname_isequal(name, ptr->name))
 1271:       return 1;
 1272:  
 1273:   return 0;
 1274: }
 1275: 
 1276: /* Is the packet a reply with the answer address equal to addr?
 1277:    If so mung is into an NXDOMAIN reply and also put that information
 1278:    in the cache. */
 1279: int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name, 
 1280: 			     struct bogus_addr *baddr, time_t now)
 1281: {
 1282:   unsigned char *p;
 1283:   int i, qtype, qclass, rdlen;
 1284:   unsigned long ttl;
 1285:   struct bogus_addr *baddrp;
 1286: 
 1287:   /* skip over questions */
 1288:   if (!(p = skip_questions(header, qlen)))
 1289:     return 0; /* bad packet */
 1290: 
 1291:   for (i = ntohs(header->ancount); i != 0; i--)
 1292:     {
 1293:       if (!extract_name(header, qlen, &p, name, 1, 10))
 1294: 	return 0; /* bad packet */
 1295:   
 1296:       GETSHORT(qtype, p); 
 1297:       GETSHORT(qclass, p);
 1298:       GETLONG(ttl, p);
 1299:       GETSHORT(rdlen, p);
 1300:       
 1301:       if (qclass == C_IN && qtype == T_A)
 1302: 	{
 1303: 	  if (!CHECK_LEN(header, p, qlen, INADDRSZ))
 1304: 	    return 0;
 1305: 	  
 1306: 	  for (baddrp = baddr; baddrp; baddrp = baddrp->next)
 1307: 	    if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
 1308: 	      {
 1309: 		/* Found a bogus address. Insert that info here, since there no SOA record
 1310: 		   to get the ttl from in the normal processing */
 1311: 		cache_start_insert();
 1312: 		cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
 1313: 		cache_end_insert();
 1314: 		
 1315: 		return 1;
 1316: 	      }
 1317: 	}
 1318:       
 1319:       if (!ADD_RDLEN(header, p, qlen, rdlen))
 1320: 	return 0;
 1321:     }
 1322:   
 1323:   return 0;
 1324: }
 1325: 
 1326: int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp, 
 1327: 			unsigned long ttl, int *offset, unsigned short type, unsigned short class, char *format, ...)
 1328: {
 1329:   va_list ap;
 1330:   unsigned char *sav, *p = *pp;
 1331:   int j;
 1332:   unsigned short usval;
 1333:   long lval;
 1334:   char *sval;
 1335: 
 1336:   if (truncp && *truncp)
 1337:     return 0;
 1338:  
 1339:   va_start(ap, format);   /* make ap point to 1st unamed argument */
 1340:   
 1341:   if (nameoffset > 0)
 1342:     {
 1343:       PUTSHORT(nameoffset | 0xc000, p);
 1344:     }
 1345:   else
 1346:     {
 1347:       char *name = va_arg(ap, char *);
 1348:       if (name)
 1349: 	p = do_rfc1035_name(p, name);
 1350:       if (nameoffset < 0)
 1351: 	{
 1352: 	  PUTSHORT(-nameoffset | 0xc000, p);
 1353: 	}
 1354:       else
 1355: 	*p++ = 0;
 1356:     }
 1357: 
 1358:   PUTSHORT(type, p);
 1359:   PUTSHORT(class, p);
 1360:   PUTLONG(ttl, p);      /* TTL */
 1361: 
 1362:   sav = p;              /* Save pointer to RDLength field */
 1363:   PUTSHORT(0, p);       /* Placeholder RDLength */
 1364: 
 1365:   for (; *format; format++)
 1366:     switch (*format)
 1367:       {
 1368: #ifdef HAVE_IPV6
 1369:       case '6':
 1370: 	sval = va_arg(ap, char *); 
 1371: 	memcpy(p, sval, IN6ADDRSZ);
 1372: 	p += IN6ADDRSZ;
 1373: 	break;
 1374: #endif
 1375: 	
 1376:       case '4':
 1377: 	sval = va_arg(ap, char *); 
 1378: 	memcpy(p, sval, INADDRSZ);
 1379: 	p += INADDRSZ;
 1380: 	break;
 1381: 	
 1382:       case 'b':
 1383: 	usval = va_arg(ap, int);
 1384: 	*p++ = usval;
 1385: 	break;
 1386: 	
 1387:       case 's':
 1388: 	usval = va_arg(ap, int);
 1389: 	PUTSHORT(usval, p);
 1390: 	break;
 1391: 	
 1392:       case 'l':
 1393: 	lval = va_arg(ap, long);
 1394: 	PUTLONG(lval, p);
 1395: 	break;
 1396: 	
 1397:       case 'd':
 1398: 	/* get domain-name answer arg and store it in RDATA field */
 1399: 	if (offset)
 1400: 	  *offset = p - (unsigned char *)header;
 1401: 	p = do_rfc1035_name(p, va_arg(ap, char *));
 1402: 	*p++ = 0;
 1403: 	break;
 1404: 	
 1405:       case 't':
 1406: 	usval = va_arg(ap, int);
 1407: 	sval = va_arg(ap, char *);
 1408: 	if (usval != 0)
 1409: 	  memcpy(p, sval, usval);
 1410: 	p += usval;
 1411: 	break;
 1412: 
 1413:       case 'z':
 1414: 	sval = va_arg(ap, char *);
 1415: 	usval = sval ? strlen(sval) : 0;
 1416: 	if (usval > 255)
 1417: 	  usval = 255;
 1418: 	*p++ = (unsigned char)usval;
 1419: 	memcpy(p, sval, usval);
 1420: 	p += usval;
 1421: 	break;
 1422:       }
 1423: 
 1424:   va_end(ap);	/* clean up variable argument pointer */
 1425:   
 1426:   j = p - sav - 2;
 1427:   PUTSHORT(j, sav);     /* Now, store real RDLength */
 1428:   
 1429:   /* check for overflow of buffer */
 1430:   if (limit && ((unsigned char *)limit - p) < 0)
 1431:     {
 1432:       if (truncp)
 1433: 	*truncp = 1;
 1434:       return 0;
 1435:     }
 1436:   
 1437:   *pp = p;
 1438:   return 1;
 1439: }
 1440: 
 1441: static unsigned long crec_ttl(struct crec *crecp, time_t now)
 1442: {
 1443:   /* Return 0 ttl for DHCP entries, which might change
 1444:      before the lease expires. */
 1445: 
 1446:   if  (crecp->flags & (F_IMMORTAL | F_DHCP))
 1447:     return daemon->local_ttl;
 1448:   
 1449:   /* Return the Max TTL value if it is lower then the actual TTL */
 1450:   if (daemon->max_ttl == 0 || ((unsigned)(crecp->ttd - now) < daemon->max_ttl))
 1451:     return crecp->ttd - now;
 1452:   else
 1453:     return daemon->max_ttl;
 1454: }
 1455:   
 1456: 
 1457: /* return zero if we can't answer from cache, or packet size if we can */
 1458: size_t answer_request(struct dns_header *header, char *limit, size_t qlen,  
 1459: 		      struct in_addr local_addr, struct in_addr local_netmask, 
 1460: 		      time_t now, int *ad_reqd, int *do_bit) 
 1461: {
 1462:   char *name = daemon->namebuff;
 1463:   unsigned char *p, *ansp, *pheader;
 1464:   unsigned int qtype, qclass;
 1465:   struct all_addr addr;
 1466:   int nameoffset;
 1467:   unsigned short flag;
 1468:   int q, ans, anscount = 0, addncount = 0;
 1469:   int dryrun = 0, sec_reqd = 0, have_pseudoheader = 0;
 1470:   int is_sign;
 1471:   struct crec *crecp;
 1472:   int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1;
 1473:   struct mx_srv_record *rec;
 1474:   size_t len;
 1475:  
 1476:   /* Don't return AD set if checking disabled. */
 1477:   if (header->hb4 & HB4_CD)
 1478:     sec_data = 0;
 1479:   
 1480:   /* RFC 6840 5.7 */
 1481:   *ad_reqd = header->hb4 & HB4_AD;
 1482:   *do_bit = 0;
 1483: 
 1484:   /* If there is an RFC2671 pseudoheader then it will be overwritten by
 1485:      partial replies, so we have to do a dry run to see if we can answer
 1486:      the query. We check to see if the do bit is set, if so we always
 1487:      forward rather than answering from the cache, which doesn't include
 1488:      security information, unless we're in DNSSEC validation mode. */
 1489: 
 1490:   if (find_pseudoheader(header, qlen, NULL, &pheader, &is_sign))
 1491:     { 
 1492:       unsigned short udpsz, flags;
 1493:       unsigned char *psave = pheader;
 1494: 
 1495:       have_pseudoheader = 1;
 1496: 
 1497:       GETSHORT(udpsz, pheader);
 1498:       pheader += 2; /* ext_rcode */
 1499:       GETSHORT(flags, pheader);
 1500:       
 1501:       if ((sec_reqd = flags & 0x8000))
 1502: 	*do_bit = 1;/* do bit */ 
 1503:       *ad_reqd = 1;
 1504: 
 1505:       /* If our client is advertising a larger UDP packet size
 1506: 	 than we allow, trim it so that we don't get an overlarge
 1507: 	 response from upstream */
 1508: 
 1509:       if (!is_sign && (udpsz > daemon->edns_pktsz))
 1510: 	PUTSHORT(daemon->edns_pktsz, psave); 
 1511: 
 1512:       dryrun = 1;
 1513:     }
 1514: 
 1515:   if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
 1516:     return 0;
 1517:   
 1518:   for (rec = daemon->mxnames; rec; rec = rec->next)
 1519:     rec->offset = 0;
 1520:   
 1521:  rerun:
 1522:   /* determine end of question section (we put answers there) */
 1523:   if (!(ansp = skip_questions(header, qlen)))
 1524:     return 0; /* bad packet */
 1525:    
 1526:   /* now process each question, answers go in RRs after the question */
 1527:   p = (unsigned char *)(header+1);
 1528: 
 1529:   for (q = ntohs(header->qdcount); q != 0; q--)
 1530:     {
 1531:       /* save pointer to name for copying into answers */
 1532:       nameoffset = p - (unsigned char *)header;
 1533: 
 1534:       /* now extract name as .-concatenated string into name */
 1535:       if (!extract_name(header, qlen, &p, name, 1, 4))
 1536: 	return 0; /* bad packet */
 1537:             
 1538:       GETSHORT(qtype, p); 
 1539:       GETSHORT(qclass, p);
 1540: 
 1541:       ans = 0; /* have we answered this question */
 1542:       
 1543:       if (qtype == T_TXT || qtype == T_ANY)
 1544: 	{
 1545: 	  struct txt_record *t;
 1546: 	  for(t = daemon->txt; t ; t = t->next)
 1547: 	    {
 1548: 	      if (t->class == qclass && hostname_isequal(name, t->name))
 1549: 		{
 1550: 		  ans = 1;
 1551: 		  if (!dryrun)
 1552: 		    {
 1553: 		      unsigned long ttl = daemon->local_ttl;
 1554: 		      int ok = 1;
 1555: 		      log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
 1556: 		      /* Dynamically generate stat record */
 1557: 		      if (t->stat != 0)
 1558: 			{
 1559: 			  ttl = 0;
 1560: 			  if (!cache_make_stat(t))
 1561: 			    ok = 0;
 1562: 			}
 1563: 		      
 1564: 		      if (ok && add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1565: 						    ttl, NULL,
 1566: 						    T_TXT, t->class, "t", t->len, t->txt))
 1567: 			anscount++;
 1568: 
 1569: 		    }
 1570: 		}
 1571: 	    }
 1572: 	}
 1573: 
 1574: #ifdef HAVE_DNSSEC
 1575:       if (option_bool(OPT_DNSSEC_VALID) && (qtype == T_DNSKEY || qtype == T_DS))
 1576: 	{
 1577: 	  int gotone = 0;
 1578: 	  struct blockdata *keydata;
 1579: 
 1580: 	  /* Do we have RRSIG? Can't do DS or DNSKEY otherwise. */
 1581: 	  if (sec_reqd)
 1582: 	    {
 1583: 	      crecp = NULL;
 1584: 	      while ((crecp = cache_find_by_name(crecp, name, now, F_DNSKEY | F_DS)))
 1585: 		if (crecp->uid == qclass && crecp->addr.sig.type_covered == qtype)
 1586: 		  break;
 1587: 	    }
 1588: 	  
 1589: 	  if (!sec_reqd || crecp)
 1590: 	    {
 1591: 	      if (qtype == T_DS)
 1592: 		{
 1593: 		  crecp = NULL;
 1594: 		  while ((crecp = cache_find_by_name(crecp, name, now, F_DS)))
 1595: 		    if (crecp->uid == qclass)
 1596: 		      {
 1597: 			gotone = 1; 
 1598: 			if (!dryrun)
 1599: 			  {
 1600: 			    if (crecp->flags & F_NEG)
 1601: 			      {
 1602: 				if (crecp->flags & F_NXDOMAIN)
 1603: 				  nxdomain = 1;
 1604: 				log_query(F_UPSTREAM, name, NULL, "secure no DS");	
 1605: 			      }
 1606: 			    else if ((keydata = blockdata_retrieve(crecp->addr.ds.keydata, crecp->addr.ds.keylen, NULL)))
 1607: 			      {			     			      
 1608: 				struct all_addr a;
 1609: 				a.addr.keytag =  crecp->addr.ds.keytag;
 1610: 				log_query(F_KEYTAG | (crecp->flags & F_CONFIG), name, &a, "DS keytag %u");
 1611: 				if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1612: 							crec_ttl(crecp, now), &nameoffset,
 1613: 							T_DS, qclass, "sbbt", 
 1614: 							crecp->addr.ds.keytag, crecp->addr.ds.algo, 
 1615: 							crecp->addr.ds.digest, crecp->addr.ds.keylen, keydata))
 1616: 				  anscount++;
 1617: 				
 1618: 			      } 
 1619: 			  }
 1620: 		      }
 1621: 		}
 1622: 	      else /* DNSKEY */
 1623: 		{
 1624: 		  crecp = NULL;
 1625: 		  while ((crecp = cache_find_by_name(crecp, name, now, F_DNSKEY)))
 1626: 		    if (crecp->uid == qclass)
 1627: 		      {
 1628: 			gotone = 1;
 1629: 			if (!dryrun && (keydata = blockdata_retrieve(crecp->addr.key.keydata, crecp->addr.key.keylen, NULL)))
 1630: 			  {			     			      
 1631: 			    struct all_addr a;
 1632: 			    a.addr.keytag =  crecp->addr.key.keytag;
 1633: 			    log_query(F_KEYTAG | (crecp->flags & F_CONFIG), name, &a, "DNSKEY keytag %u");
 1634: 			    if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1635: 						    crec_ttl(crecp, now), &nameoffset,
 1636: 						    T_DNSKEY, qclass, "sbbt", 
 1637: 						    crecp->addr.key.flags, 3, crecp->addr.key.algo, crecp->addr.key.keylen, keydata))
 1638: 			      anscount++;
 1639: 			  }
 1640: 		      }
 1641: 		}
 1642: 	    }
 1643: 	  
 1644: 	  /* Now do RRSIGs */
 1645: 	  if (gotone)
 1646: 	    {
 1647: 	      ans = 1;
 1648: 	      auth = 0;
 1649: 	      if (!dryrun && sec_reqd)
 1650: 		{
 1651: 		  crecp = NULL;
 1652: 		  while ((crecp = cache_find_by_name(crecp, name, now, F_DNSKEY | F_DS)))
 1653: 		    if (crecp->uid == qclass && crecp->addr.sig.type_covered == qtype &&
 1654: 			(keydata = blockdata_retrieve(crecp->addr.sig.keydata, crecp->addr.sig.keylen, NULL)))
 1655: 		      {
 1656: 			add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1657: 					    crec_ttl(crecp, now), &nameoffset,
 1658: 					    T_RRSIG, qclass, "t", crecp->addr.sig.keylen, keydata);
 1659: 			anscount++;
 1660: 		      }
 1661: 		}
 1662: 	    }
 1663: 	}
 1664: #endif	     
 1665:       
 1666:       if (qclass == C_IN)
 1667: 	{
 1668: 	  struct txt_record *t;
 1669: 
 1670: 	  for (t = daemon->rr; t; t = t->next)
 1671: 	    if ((t->class == qtype || qtype == T_ANY) && hostname_isequal(name, t->name))
 1672: 	      {
 1673: 		ans = 1;
 1674: 		if (!dryrun)
 1675: 		  {
 1676: 		    log_query(F_CONFIG | F_RRNAME, name, NULL, "<RR>");
 1677: 		    if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1678: 					    daemon->local_ttl, NULL,
 1679: 					    t->class, C_IN, "t", t->len, t->txt))
 1680: 		      anscount ++;
 1681: 		  }
 1682: 	      }
 1683: 		
 1684: 	  if (qtype == T_PTR || qtype == T_ANY)
 1685: 	    {
 1686: 	      /* see if it's w.z.y.z.in-addr.arpa format */
 1687: 	      int is_arpa = in_arpa_name_2_addr(name, &addr);
 1688: 	      struct ptr_record *ptr;
 1689: 	      struct interface_name* intr = NULL;
 1690: 
 1691: 	      for (ptr = daemon->ptr; ptr; ptr = ptr->next)
 1692: 		if (hostname_isequal(name, ptr->name))
 1693: 		  break;
 1694: 
 1695: 	      if (is_arpa == F_IPV4)
 1696: 		for (intr = daemon->int_names; intr; intr = intr->next)
 1697: 		  {
 1698: 		    struct addrlist *addrlist;
 1699: 		    
 1700: 		    for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
 1701: 		      if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
 1702: 			break;
 1703: 		    
 1704: 		    if (addrlist)
 1705: 		      break;
 1706: 		    else
 1707: 		      while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
 1708: 			intr = intr->next;
 1709: 		  }
 1710: #ifdef HAVE_IPV6
 1711: 	      else if (is_arpa == F_IPV6)
 1712: 		for (intr = daemon->int_names; intr; intr = intr->next)
 1713: 		  {
 1714: 		    struct addrlist *addrlist;
 1715: 		    
 1716: 		    for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
 1717: 		      if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
 1718: 			break;
 1719: 		    
 1720: 		    if (addrlist)
 1721: 		      break;
 1722: 		    else
 1723: 		      while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
 1724: 			intr = intr->next;
 1725: 		  }
 1726: #endif
 1727: 	      
 1728: 	      if (intr)
 1729: 		{
 1730: 		  ans = 1;
 1731: 		  if (!dryrun)
 1732: 		    {
 1733: 		      log_query(is_arpa | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
 1734: 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1735: 					      daemon->local_ttl, NULL,
 1736: 					      T_PTR, C_IN, "d", intr->name))
 1737: 			anscount++;
 1738: 		    }
 1739: 		}
 1740: 	      else if (ptr)
 1741: 		{
 1742: 		  ans = 1;
 1743: 		  if (!dryrun)
 1744: 		    {
 1745: 		      log_query(F_CONFIG | F_RRNAME, name, NULL, "<PTR>");
 1746: 		      for (ptr = daemon->ptr; ptr; ptr = ptr->next)
 1747: 			if (hostname_isequal(name, ptr->name) &&
 1748: 			    add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1749: 						daemon->local_ttl, NULL,
 1750: 						T_PTR, C_IN, "d", ptr->ptr))
 1751: 			  anscount++;
 1752: 			 
 1753: 		    }
 1754: 		}
 1755: 	      else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
 1756: 		{
 1757: 		  if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && sec_reqd)
 1758: 		    {
 1759: 		      if (!option_bool(OPT_DNSSEC_VALID) || ((crecp->flags & F_NEG) && (crecp->flags & F_DNSSECOK)))
 1760: 			crecp = NULL;
 1761: #ifdef HAVE_DNSSEC
 1762: 		      else if (crecp->flags & F_DNSSECOK)
 1763: 			{
 1764: 			  int gotsig = 0;
 1765: 			  struct crec *rr_crec = NULL;
 1766: 
 1767: 			  while ((rr_crec = cache_find_by_name(rr_crec, name, now, F_DS | F_DNSKEY)))
 1768: 			    {
 1769: 			      if (rr_crec->addr.sig.type_covered == T_PTR && rr_crec->uid == C_IN)
 1770: 				{
 1771: 				  char *sigdata = blockdata_retrieve(rr_crec->addr.sig.keydata, rr_crec->addr.sig.keylen, NULL);
 1772: 				  gotsig = 1;
 1773: 				  
 1774: 				  if (!dryrun && 
 1775: 				      add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1776: 							  rr_crec->ttd - now, &nameoffset,
 1777: 							  T_RRSIG, C_IN, "t", crecp->addr.sig.keylen, sigdata))
 1778: 				    anscount++;
 1779: 				}
 1780: 			    } 
 1781: 			  
 1782: 			  if (!gotsig)
 1783: 			    crecp = NULL;
 1784: 			}
 1785: #endif
 1786: 		    }
 1787: 
 1788: 		  if (crecp)
 1789: 		    {
 1790: 		      do 
 1791: 			{ 
 1792: 			  /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
 1793: 			  if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
 1794: 			    continue;
 1795: 			  
 1796: 			  if (!(crecp->flags & F_DNSSECOK))
 1797: 			    sec_data = 0;
 1798: 			  
 1799: 			  if (crecp->flags & F_NEG)
 1800: 			    {
 1801: 			      ans = 1;
 1802: 			      auth = 0;
 1803: 			      if (crecp->flags & F_NXDOMAIN)
 1804: 				nxdomain = 1;
 1805: 			      if (!dryrun)
 1806: 				log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
 1807: 			    }
 1808: 			  else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd || option_bool(OPT_DNSSEC_VALID))
 1809: 			    {
 1810: 			      ans = 1;
 1811: 			      if (!(crecp->flags & (F_HOSTS | F_DHCP)))
 1812: 				auth = 0;
 1813: 			      if (!dryrun)
 1814: 				{
 1815: 				  log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr, 
 1816: 					    record_source(crecp->uid));
 1817: 				  
 1818: 				  if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1819: 							  crec_ttl(crecp, now), NULL,
 1820: 							  T_PTR, C_IN, "d", cache_get_name(crecp)))
 1821: 				    anscount++;
 1822: 				}
 1823: 			    }
 1824: 			} while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
 1825: 		    }
 1826: 		}
 1827: 	      else if (is_rev_synth(is_arpa, &addr, name))
 1828: 		{
 1829: 		  ans = 1;
 1830: 		  if (!dryrun)
 1831: 		    {
 1832: 		      log_query(F_CONFIG | F_REVERSE | is_arpa, name, &addr, NULL); 
 1833: 		      
 1834: 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1835: 					      daemon->local_ttl, NULL,
 1836: 					      T_PTR, C_IN, "d", name))
 1837: 			      anscount++;
 1838: 		    }
 1839: 		}
 1840: 	      else if (is_arpa == F_IPV4 && 
 1841: 		       option_bool(OPT_BOGUSPRIV) && 
 1842: 		       private_net(addr.addr.addr4, 1))
 1843: 		{
 1844: 		  /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
 1845: 		  ans = 1;
 1846: 		  nxdomain = 1;
 1847: 		  if (!dryrun)
 1848: 		    log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN, 
 1849: 			      name, &addr, NULL);
 1850: 		}
 1851: 	    }
 1852: 	    
 1853: 	  for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
 1854: 	    {
 1855: 	      unsigned short type = T_A;
 1856: 	      struct interface_name *intr;
 1857: 
 1858: 	      if (flag == F_IPV6)
 1859: #ifdef HAVE_IPV6
 1860: 		type = T_AAAA;
 1861: #else
 1862: 	        break;
 1863: #endif
 1864: 	      
 1865: 	      if (qtype != type && qtype != T_ANY)
 1866: 		continue;
 1867: 	      
 1868: 	      /* Check for "A for A"  queries; be rather conservative 
 1869: 		 about what looks like dotted-quad.  */
 1870: 	      if (qtype == T_A)
 1871: 		{
 1872: 		  char *cp;
 1873: 		  unsigned int i, a;
 1874: 		  int x;
 1875: 
 1876: 		  for (cp = name, i = 0, a = 0; *cp; i++)
 1877: 		    {
 1878: 		      if (!isdigit((unsigned char)*cp) || (x = strtol(cp, &cp, 10)) > 255) 
 1879: 			{
 1880: 			  i = 5;
 1881: 			  break;
 1882: 			}
 1883: 		      
 1884: 		      a = (a << 8) + x;
 1885: 		      
 1886: 		      if (*cp == '.') 
 1887: 			cp++;
 1888: 		    }
 1889: 		  
 1890: 		  if (i == 4)
 1891: 		    {
 1892: 		      ans = 1;
 1893: 		      if (!dryrun)
 1894: 			{
 1895: 			  addr.addr.addr4.s_addr = htonl(a);
 1896: 			  log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
 1897: 			  if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1898: 						  daemon->local_ttl, NULL, type, C_IN, "4", &addr))
 1899: 			    anscount++;
 1900: 			}
 1901: 		      continue;
 1902: 		    }
 1903: 		}
 1904: 
 1905: 	      /* interface name stuff */
 1906: 	    intname_restart:
 1907: 	      for (intr = daemon->int_names; intr; intr = intr->next)
 1908: 		if (hostname_isequal(name, intr->name))
 1909: 		  break;
 1910: 	      
 1911: 	      if (intr)
 1912: 		{
 1913: 		  struct addrlist *addrlist;
 1914: 		  int gotit = 0;
 1915: 
 1916: 		  enumerate_interfaces(0);
 1917: 		  
 1918: 		  for (intr = daemon->int_names; intr; intr = intr->next)
 1919: 		    if (hostname_isequal(name, intr->name))
 1920: 		      {
 1921: 			ans = 1;
 1922: 			if (!dryrun)
 1923: 			  {
 1924: 			    
 1925: 			    for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
 1926: #ifdef HAVE_IPV6
 1927: 			      if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
 1928: #endif
 1929: 				{
 1930: 				  gotit = 1;
 1931: 				  log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
 1932: 				  if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1933: 							  daemon->local_ttl, NULL, type, C_IN, 
 1934: 							  type == T_A ? "4" : "6", &addrlist->addr))
 1935: 				    anscount++;
 1936: 				}
 1937: 			  }
 1938: 		      }
 1939: 		  
 1940: 		  if (!dryrun && !gotit)
 1941: 		    log_query(F_FORWARD | F_CONFIG | flag | F_NEG, name, NULL, NULL);
 1942: 		     
 1943: 		  continue;
 1944: 		}
 1945: 
 1946: 	    cname_restart:
 1947: 	      if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME | (dryrun ? F_NO_RR : 0))))
 1948: 		{
 1949: 		  int localise = 0;
 1950: 		  
 1951: 		  /* See if a putative address is on the network from which we recieved
 1952: 		     the query, is so we'll filter other answers. */
 1953: 		  if (local_addr.s_addr != 0 && option_bool(OPT_LOCALISE) && flag == F_IPV4)
 1954: 		    {
 1955: 		      struct crec *save = crecp;
 1956: 		      do {
 1957: 			if ((crecp->flags & F_HOSTS) &&
 1958: 			    is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
 1959: 			  {
 1960: 			    localise = 1;
 1961: 			    break;
 1962: 			  } 
 1963: 			} while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
 1964: 		      crecp = save;
 1965: 		    }
 1966: 
 1967: 		  /* If the client asked for DNSSEC and we can't provide RRSIGs, either
 1968: 		     because we've not doing DNSSEC or the cached answer is signed by negative,
 1969: 		     don't answer from the cache, forward instead. */
 1970: 		  if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && sec_reqd)
 1971: 		    {
 1972: 		      if (!option_bool(OPT_DNSSEC_VALID) || ((crecp->flags & F_NEG) && (crecp->flags & F_DNSSECOK)))
 1973: 			crecp = NULL;
 1974: #ifdef HAVE_DNSSEC
 1975: 		      else if (crecp->flags & F_DNSSECOK)
 1976: 			{
 1977: 			  /* We're returning validated data, need to return the RRSIG too. */
 1978: 			  struct crec *rr_crec = NULL;
 1979: 			  int sigtype = type;
 1980: 			  /* The signature may have expired even though the data is still in cache, 
 1981: 			     forward instead of answering from cache if so. */
 1982: 			  int gotsig = 0;
 1983: 			  
 1984: 			  if (crecp->flags & F_CNAME)
 1985: 			    sigtype = T_CNAME;
 1986: 			  
 1987: 			  while ((rr_crec = cache_find_by_name(rr_crec, name, now, F_DS | F_DNSKEY)))
 1988: 			    {
 1989: 			      if (rr_crec->addr.sig.type_covered == sigtype && rr_crec->uid == C_IN)
 1990: 				{
 1991: 				  char *sigdata = blockdata_retrieve(rr_crec->addr.sig.keydata, rr_crec->addr.sig.keylen, NULL);
 1992: 				  gotsig = 1;
 1993: 				  
 1994: 				  if (!dryrun && 
 1995: 				      add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 1996: 							  rr_crec->ttd - now, &nameoffset,
 1997: 							  T_RRSIG, C_IN, "t", rr_crec->addr.sig.keylen, sigdata))
 1998: 				    anscount++;
 1999: 				}
 2000: 			    }
 2001: 			  
 2002: 			  if (!gotsig)
 2003: 			    crecp = NULL;
 2004: 			}
 2005: #endif
 2006: 		    }		 
 2007: 
 2008: 		  if (crecp)
 2009: 		    do
 2010: 		      { 
 2011: 			/* don't answer wildcard queries with data not from /etc/hosts
 2012: 			   or DHCP leases */
 2013: 			if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
 2014: 			  break;
 2015: 			
 2016: 			if (!(crecp->flags & F_DNSSECOK))
 2017: 			  sec_data = 0;
 2018: 			
 2019: 			if (crecp->flags & F_CNAME)
 2020: 			  {
 2021: 			    char *cname_target = cache_get_cname_target(crecp);
 2022: 			    
 2023: 			    if (!dryrun)
 2024: 			      {
 2025: 				log_query(crecp->flags, name, NULL, record_source(crecp->uid));
 2026: 				if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 2027: 							crec_ttl(crecp, now), &nameoffset,
 2028: 							T_CNAME, C_IN, "d", cname_target))
 2029: 				  anscount++;
 2030: 			      }
 2031: 			    
 2032: 			    strcpy(name, cname_target);
 2033: 			    /* check if target interface_name */
 2034: 			    if (crecp->addr.cname.uid == SRC_INTERFACE)
 2035: 			      goto intname_restart;
 2036: 			    else
 2037: 			      goto cname_restart;
 2038: 			  }
 2039: 			
 2040: 			if (crecp->flags & F_NEG)
 2041: 			  {
 2042: 			    /* We don't cache NSEC records, so if a DNSSEC-validated negative answer
 2043: 			       is cached and the client wants DNSSEC, forward rather than answering from the cache */
 2044: 			    if (!sec_reqd || !(crecp->flags & F_DNSSECOK))
 2045: 			      {
 2046: 				ans = 1;
 2047: 				auth = 0;
 2048: 				if (crecp->flags & F_NXDOMAIN)
 2049: 				  nxdomain = 1;
 2050: 				if (!dryrun)
 2051: 				  log_query(crecp->flags, name, NULL, NULL);
 2052: 			      }
 2053: 			  }
 2054: 			else 
 2055: 			  {
 2056: 			    /* If we are returning local answers depending on network,
 2057: 			       filter here. */
 2058: 			    if (localise && 
 2059: 				(crecp->flags & F_HOSTS) &&
 2060: 				!is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
 2061: 			      continue;
 2062: 			    
 2063: 			    if (!(crecp->flags & (F_HOSTS | F_DHCP)))
 2064: 			      auth = 0;
 2065: 			    
 2066: 			    ans = 1;
 2067: 			    if (!dryrun)
 2068: 			      {
 2069: 				log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
 2070: 					  record_source(crecp->uid));
 2071: 				
 2072: 				if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 2073: 							crec_ttl(crecp, now), NULL, type, C_IN, 
 2074: 							type == T_A ? "4" : "6", &crecp->addr))
 2075: 				  anscount++;
 2076: 			      }
 2077: 			  }
 2078: 		      } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
 2079: 		}
 2080: 	      else if (is_name_synthetic(flag, name, &addr))
 2081: 		{
 2082: 		  ans = 1;
 2083: 		  if (!dryrun)
 2084: 		    {
 2085: 		      log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL);
 2086: 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 2087: 					      daemon->local_ttl, NULL, type, C_IN, type == T_A ? "4" : "6", &addr))
 2088: 			anscount++;
 2089: 		    }
 2090: 		}
 2091: 	    }
 2092: 
 2093: 	  if (qtype == T_CNAME || qtype == T_ANY)
 2094: 	    {
 2095: 	      if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME)) &&
 2096: 		  (qtype == T_CNAME || (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG  | (dryrun ? F_NO_RR : 0)))))
 2097: 		{
 2098: 		  if (!(crecp->flags & F_DNSSECOK))
 2099: 		    sec_data = 0;
 2100: 		  
 2101: 		  ans = 1;
 2102: 		  if (!dryrun)
 2103: 		    {
 2104: 		      log_query(crecp->flags, name, NULL, record_source(crecp->uid));
 2105: 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
 2106: 					      crec_ttl(crecp, now), &nameoffset,
 2107: 					      T_CNAME, C_IN, "d", cache_get_cname_target(crecp)))
 2108: 			anscount++;
 2109: 		    }
 2110: 		}
 2111: 	    }
 2112: 
 2113: 	  if (qtype == T_MX || qtype == T_ANY)
 2114: 	    {
 2115: 	      int found = 0;
 2116: 	      for (rec = daemon->mxnames; rec; rec = rec->next)
 2117: 		if (!rec->issrv && hostname_isequal(name, rec->name))
 2118: 		  {
 2119: 		  ans = found = 1;
 2120: 		  if (!dryrun)
 2121: 		    {
 2122: 		      int offset;
 2123: 		      log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
 2124: 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
 2125: 					      &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
 2126: 			{
 2127: 			  anscount++;
 2128: 			  if (rec->target)
 2129: 			    rec->offset = offset;
 2130: 			}
 2131: 		    }
 2132: 		  }
 2133: 	      
 2134: 	      if (!found && (option_bool(OPT_SELFMX) || option_bool(OPT_LOCALMX)) && 
 2135: 		  cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP | F_NO_RR))
 2136: 		{ 
 2137: 		  ans = 1;
 2138: 		  if (!dryrun)
 2139: 		    {
 2140: 		      log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
 2141: 		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL, 
 2142: 					      T_MX, C_IN, "sd", 1, 
 2143: 					      option_bool(OPT_SELFMX) ? name : daemon->mxtarget))
 2144: 			anscount++;
 2145: 		    }
 2146: 		}
 2147: 	    }
 2148: 	  	  
 2149: 	  if (qtype == T_SRV || qtype == T_ANY)
 2150: 	    {
 2151: 	      int found = 0;
 2152: 	      struct mx_srv_record *move = NULL, **up = &daemon->mxnames;
 2153: 
 2154: 	      for (rec = daemon->mxnames; rec; rec = rec->next)
 2155: 		if (rec->issrv && hostname_isequal(name, rec->name))
 2156: 		  {
 2157: 		    found = ans = 1;
 2158: 		    if (!dryrun)
 2159: 		      {
 2160: 			int offset;
 2161: 			log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>");
 2162: 			if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, 
 2163: 						&offset, T_SRV, C_IN, "sssd", 
 2164: 						rec->priority, rec->weight, rec->srvport, rec->target))
 2165: 			  {
 2166: 			    anscount++;
 2167: 			    if (rec->target)
 2168: 			      rec->offset = offset;
 2169: 			  }
 2170: 		      }
 2171: 		    
 2172: 		    /* unlink first SRV record found */
 2173: 		    if (!move)
 2174: 		      {
 2175: 			move = rec;
 2176: 			*up = rec->next;
 2177: 		      }
 2178: 		    else
 2179: 		      up = &rec->next;      
 2180: 		  }
 2181: 		else
 2182: 		  up = &rec->next;
 2183: 
 2184: 	      /* put first SRV record back at the end. */
 2185: 	      if (move)
 2186: 		{
 2187: 		  *up = move;
 2188: 		  move->next = NULL;
 2189: 		}
 2190: 	      
 2191: 	      if (!found && option_bool(OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
 2192: 		{
 2193: 		  ans = 1;
 2194: 		  if (!dryrun)
 2195: 		    log_query(F_CONFIG | F_NEG, name, NULL, NULL);
 2196: 		}
 2197: 	    }
 2198: 
 2199: 	  if (qtype == T_NAPTR || qtype == T_ANY)
 2200: 	    {
 2201: 	      struct naptr *na;
 2202: 	      for (na = daemon->naptr; na; na = na->next)
 2203: 		if (hostname_isequal(name, na->name))
 2204: 		  {
 2205: 		    ans = 1;
 2206: 		    if (!dryrun)
 2207: 		      {
 2208: 			log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>");
 2209: 			if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, 
 2210: 						NULL, T_NAPTR, C_IN, "sszzzd", 
 2211: 						na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
 2212: 			  anscount++;
 2213: 		      }
 2214: 		  }
 2215: 	    }
 2216: 	  
 2217: 	  if (qtype == T_MAILB)
 2218: 	    ans = 1, nxdomain = 1;
 2219: 
 2220: 	  if (qtype == T_SOA && option_bool(OPT_FILTER))
 2221: 	    {
 2222: 	      ans = 1; 
 2223: 	      if (!dryrun)
 2224: 		log_query(F_CONFIG | F_NEG, name, &addr, NULL);
 2225: 	    }
 2226: 	}
 2227: 
 2228:       if (!ans)
 2229: 	return 0; /* failed to answer a question */
 2230:     }
 2231:   
 2232:   if (dryrun)
 2233:     {
 2234:       dryrun = 0;
 2235:       goto rerun;
 2236:     }
 2237:   
 2238:   /* create an additional data section, for stuff in SRV and MX record replies. */
 2239:   for (rec = daemon->mxnames; rec; rec = rec->next)
 2240:     if (rec->offset != 0)
 2241:       {
 2242: 	/* squash dupes */
 2243: 	struct mx_srv_record *tmp;
 2244: 	for (tmp = rec->next; tmp; tmp = tmp->next)
 2245: 	  if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
 2246: 	    tmp->offset = 0;
 2247: 	
 2248: 	crecp = NULL;
 2249: 	while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
 2250: 	  {
 2251: #ifdef HAVE_IPV6
 2252: 	    int type =  crecp->flags & F_IPV4 ? T_A : T_AAAA;
 2253: #else
 2254: 	    int type = T_A;
 2255: #endif
 2256: 	    if (crecp->flags & F_NEG)
 2257: 	      continue;
 2258: 
 2259: 	    if (add_resource_record(header, limit, NULL, rec->offset, &ansp, 
 2260: 				    crec_ttl(crecp, now), NULL, type, C_IN, 
 2261: 				    crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
 2262: 	      addncount++;
 2263: 	  }
 2264:       }
 2265:   
 2266:   /* done all questions, set up header and return length of result */
 2267:   /* clear authoritative and truncated flags, set QR flag */
 2268:   header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
 2269:   /* set RA flag */
 2270:   header->hb4 |= HB4_RA;
 2271:    
 2272:   /* authoritive - only hosts and DHCP derived names. */
 2273:   if (auth)
 2274:     header->hb3 |= HB3_AA;
 2275:   
 2276:   /* truncation */
 2277:   if (trunc)
 2278:     header->hb3 |= HB3_TC;
 2279:   
 2280:   if (nxdomain)
 2281:     SET_RCODE(header, NXDOMAIN);
 2282:   else
 2283:     SET_RCODE(header, NOERROR); /* no error */
 2284:   header->ancount = htons(anscount);
 2285:   header->nscount = htons(0);
 2286:   header->arcount = htons(addncount);
 2287: 
 2288:   len = ansp - (unsigned char *)header;
 2289:   
 2290:   if (have_pseudoheader)
 2291:     len = add_pseudoheader(header, len, (unsigned char *)limit, 0, NULL, 0, sec_reqd);
 2292:   
 2293:   if (*ad_reqd && sec_data)
 2294:     header->hb4 |= HB4_AD;
 2295:   else
 2296:     header->hb4 &= ~HB4_AD;
 2297:   
 2298:   return len;
 2299: }
 2300: 

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