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

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

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