Annotation of embedaddon/dnsmasq/src/rfc1035.c, revision 1.1.1.1

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

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