Home | History | Annotate | Download | only in src
      1 /* dnsmasq is Copyright (c) 2000-2009 Simon Kelley
      2 
      3    This program is free software; you can redistribute it and/or modify
      4    it under the terms of the GNU General Public License as published by
      5    the Free Software Foundation; version 2 dated June, 1991, or
      6    (at your option) version 3 dated 29 June, 2007.
      7 
      8    This program is distributed in the hope that it will be useful,
      9    but WITHOUT ANY WARRANTY; without even the implied warranty of
     10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11    GNU General Public License for more details.
     12 
     13    You should have received a copy of the GNU General Public License
     14    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15 */
     16 
     17 #include "dnsmasq.h"
     18 
     19 static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigned int nameoffset,
     20                                unsigned char** pp, unsigned long ttl, unsigned int* offset,
     21                                unsigned short type, unsigned short class, char* format, ...);
     22 
     23 #define CHECK_LEN(header, pp, plen, len) \
     24     ((size_t)((pp) - (unsigned char*) (header) + (len)) <= (plen))
     25 
     26 #define ADD_RDLEN(header, pp, plen, len) \
     27     (!CHECK_LEN(header, pp, plen, len) ? 0 : (long) ((pp) += (len)), 1)
     28 
     29 static int extract_name(HEADER* header, size_t plen, unsigned char** pp, char* name, int isExtract,
     30                         int extrabytes) {
     31     unsigned char *cp = (unsigned char*) name, *p = *pp, *p1 = NULL;
     32     unsigned int j, l, hops = 0;
     33     int retvalue = 1;
     34 
     35     if (isExtract) *cp = 0;
     36 
     37     while (1) {
     38         unsigned int label_type;
     39 
     40         if (!CHECK_LEN(header, p, plen, 1)) return 0;
     41 
     42         if ((l = *p++) == 0)
     43         /* end marker */
     44         {
     45             /* check that there are the correct no of bytes after the name */
     46             if (!CHECK_LEN(header, p1 ? p1 : p, plen, extrabytes)) return 0;
     47 
     48             if (isExtract) {
     49                 if (cp != (unsigned char*) name) cp--;
     50                 *cp = 0; /* terminate: lose final period */
     51             } else if (*cp != 0)
     52                 retvalue = 2;
     53 
     54             if (p1) /* we jumped via compression */
     55                 *pp = p1;
     56             else
     57                 *pp = p;
     58 
     59             return retvalue;
     60         }
     61 
     62         label_type = l & 0xc0;
     63 
     64         if (label_type == 0xc0) /* pointer */
     65         {
     66             if (!CHECK_LEN(header, p, plen, 1)) return 0;
     67 
     68             /* get offset */
     69             l = (l & 0x3f) << 8;
     70             l |= *p++;
     71 
     72             if (!p1) /* first jump, save location to go back to */
     73                 p1 = p;
     74 
     75             hops++; /* break malicious infinite loops */
     76             if (hops > 255) return 0;
     77 
     78             p = l + (unsigned char*) header;
     79         } else if (label_type == 0x80)
     80             return 0;                  /* reserved */
     81         else if (label_type == 0x40) { /* ELT */
     82             unsigned int count, digs;
     83 
     84             if ((l & 0x3f) != 1) return 0; /* we only understand bitstrings */
     85 
     86             if (!isExtract) return 0; /* Cannot compare bitsrings */
     87 
     88             count = *p++;
     89             if (count == 0) count = 256;
     90             digs = ((count - 1) >> 2) + 1;
     91 
     92             /* output is \[x<hex>/siz]. which is digs+9 chars */
     93             if (cp - (unsigned char*) name + digs + 9 >= MAXDNAME) return 0;
     94             if (!CHECK_LEN(header, p, plen, (count - 1) >> 3)) return 0;
     95 
     96             *cp++ = '\\';
     97             *cp++ = '[';
     98             *cp++ = 'x';
     99             for (j = 0; j < digs; j++) {
    100                 unsigned int dig;
    101                 if (j % 2 == 0)
    102                     dig = *p >> 4;
    103                 else
    104                     dig = *p++ & 0x0f;
    105 
    106                 *cp++ = dig < 10 ? dig + '0' : dig + 'A' - 10;
    107             }
    108             cp += sprintf((char*) cp, "/%d]", count);
    109             /* do this here to overwrite the zero char from sprintf */
    110             *cp++ = '.';
    111         } else { /* label_type = 0 -> label. */
    112             if (cp - (unsigned char*) name + l + 1 >= MAXDNAME) return 0;
    113             if (!CHECK_LEN(header, p, plen, l)) return 0;
    114 
    115             for (j = 0; j < l; j++, p++)
    116                 if (isExtract) {
    117                     unsigned char c = *p;
    118                     if (isascii(c) && !iscntrl(c) && c != '.')
    119                         *cp++ = *p;
    120                     else
    121                         return 0;
    122                 } else {
    123                     unsigned char c1 = *cp, c2 = *p;
    124 
    125                     if (c1 == 0)
    126                         retvalue = 2;
    127                     else {
    128                         cp++;
    129                         if (c1 >= 'A' && c1 <= 'Z') c1 += 'a' - 'A';
    130                         if (c2 >= 'A' && c2 <= 'Z') c2 += 'a' - 'A';
    131 
    132                         if (c1 != c2) retvalue = 2;
    133                     }
    134                 }
    135 
    136             if (isExtract)
    137                 *cp++ = '.';
    138             else if (*cp != 0 && *cp++ != '.')
    139                 retvalue = 2;
    140         }
    141     }
    142 }
    143 
    144 /* Max size of input string (for IPv6) is 75 chars.) */
    145 #define MAXARPANAME 75
    146 static int in_arpa_name_2_addr(char* namein, struct all_addr* addrp) {
    147     int j;
    148     char name[MAXARPANAME + 1], *cp1;
    149     unsigned char* addr = (unsigned char*) addrp;
    150     char *lastchunk = NULL, *penchunk = NULL;
    151 
    152     if (strlen(namein) > MAXARPANAME) return 0;
    153 
    154     memset(addrp, 0, sizeof(struct all_addr));
    155 
    156     /* turn name into a series of asciiz strings */
    157     /* j counts no of labels */
    158     for (j = 1, cp1 = name; *namein; cp1++, namein++)
    159         if (*namein == '.') {
    160             penchunk = lastchunk;
    161             lastchunk = cp1 + 1;
    162             *cp1 = 0;
    163             j++;
    164         } else
    165             *cp1 = *namein;
    166 
    167     *cp1 = 0;
    168 
    169     if (j < 3) return 0;
    170 
    171     if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr")) {
    172         /* IP v4 */
    173         /* address arives as a name of the form
    174        www.xxx.yyy.zzz.in-addr.arpa
    175        some of the low order address octets might be missing
    176        and should be set to zero. */
    177         for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1) + 1) {
    178             /* check for digits only (weeds out things like
    179                50.0/24.67.28.64.in-addr.arpa which are used
    180                as CNAME targets according to RFC 2317 */
    181             char* cp;
    182             for (cp = cp1; *cp; cp++)
    183                 if (!isdigit((int) *cp)) return 0;
    184 
    185             addr[3] = addr[2];
    186             addr[2] = addr[1];
    187             addr[1] = addr[0];
    188             addr[0] = atoi(cp1);
    189         }
    190 
    191         return F_IPV4;
    192     }
    193 #ifdef HAVE_IPV6
    194     else if (hostname_isequal(penchunk, "ip6") &&
    195              (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa"))) {
    196         /* IP v6:
    197            Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
    198            or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]
    199 
    200        Note that most of these the various reprentations are obsolete and
    201        left-over from the many DNS-for-IPv6 wars. We support all the formats
    202        that we can since there is no reason not to.
    203         */
    204 
    205         /* TODO: does this make sense? */
    206 
    207         if (*name == '\\' && *(name + 1) == '[' && (*(name + 2) == 'x' || *(name + 2) == 'X')) {
    208             for (j = 0, cp1 = name + 3; *cp1 && isxdigit((int) *cp1) && j < 32; cp1++, j++) {
    209                 char xdig[2];
    210                 xdig[0] = *cp1;
    211                 xdig[1] = 0;
    212                 if (j % 2)
    213                     addr[j / 2] |= strtol(xdig, NULL, 16);
    214                 else
    215                     addr[j / 2] = strtol(xdig, NULL, 16) << 4;
    216             }
    217 
    218             if (*cp1 == '/' && j == 32) return F_IPV6;
    219         } else {
    220             for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1) + 1) {
    221                 if (*(cp1 + 1) || !isxdigit((int) *cp1)) return 0;
    222 
    223                 for (j = sizeof(struct all_addr) - 1; j > 0; j--)
    224                     addr[j] = (addr[j] >> 4) | (addr[j - 1] << 4);
    225                 addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
    226             }
    227 
    228             return F_IPV6;
    229         }
    230     }
    231 #endif
    232 
    233     return 0;
    234 }
    235 
    236 static unsigned char* skip_name(unsigned char* ansp, HEADER* header, size_t plen, int extrabytes) {
    237     while (1) {
    238         unsigned int label_type;
    239 
    240         if (!CHECK_LEN(header, ansp, plen, 1)) return NULL;
    241 
    242         label_type = (*ansp) & 0xc0;
    243 
    244         if (label_type == 0xc0) {
    245             /* pointer for compression. */
    246             ansp += 2;
    247             break;
    248         } else if (label_type == 0x80)
    249             return NULL; /* reserved */
    250         else if (label_type == 0x40) {
    251             /* Extended label type */
    252             unsigned int count;
    253 
    254             if (!CHECK_LEN(header, ansp, plen, 2)) return NULL;
    255 
    256             if (((*ansp++) & 0x3f) != 1) return NULL; /* we only understand bitstrings */
    257 
    258             count = *(ansp++); /* Bits in bitstring */
    259 
    260             if (count == 0) /* count == 0 means 256 bits */
    261                 ansp += 32;
    262             else
    263                 ansp += ((count - 1) >> 3) + 1;
    264         } else { /* label type == 0 Bottom six bits is length */
    265             unsigned int len = (*ansp++) & 0x3f;
    266 
    267             if (!ADD_RDLEN(header, ansp, plen, len)) return NULL;
    268 
    269             if (len == 0) break; /* zero length label marks the end. */
    270         }
    271     }
    272 
    273     if (!CHECK_LEN(header, ansp, plen, extrabytes)) return NULL;
    274 
    275     return ansp;
    276 }
    277 
    278 static unsigned char* skip_questions(HEADER* header, size_t plen) {
    279     int q;
    280     unsigned char* ansp = (unsigned char*) (header + 1);
    281 
    282     for (q = ntohs(header->qdcount); q != 0; q--) {
    283         if (!(ansp = skip_name(ansp, header, plen, 4))) return NULL;
    284         ansp += 4; /* class and type */
    285     }
    286 
    287     return ansp;
    288 }
    289 
    290 static unsigned char* skip_section(unsigned char* ansp, int count, HEADER* header, size_t plen) {
    291     int i, rdlen;
    292 
    293     for (i = 0; i < count; i++) {
    294         if (!(ansp = skip_name(ansp, header, plen, 10))) return NULL;
    295         ansp += 8; /* type, class, TTL */
    296         GETSHORT(rdlen, ansp);
    297         if (!ADD_RDLEN(header, ansp, plen, rdlen)) return NULL;
    298     }
    299 
    300     return ansp;
    301 }
    302 
    303 /* CRC the question section. This is used to safely detect query
    304    retransmision and to detect answers to questions we didn't ask, which
    305    might be poisoning attacks. Note that we decode the name rather
    306    than CRC the raw bytes, since replies might be compressed differently.
    307    We ignore case in the names for the same reason. Return all-ones
    308    if there is not question section. */
    309 unsigned int questions_crc(HEADER* header, size_t plen, char* name) {
    310     int q;
    311     unsigned int crc = 0xffffffff;
    312     unsigned char *p1, *p = (unsigned char*) (header + 1);
    313 
    314     for (q = ntohs(header->qdcount); q != 0; q--) {
    315         if (!extract_name(header, plen, &p, name, 1, 4)) return crc; /* bad packet */
    316 
    317         for (p1 = (unsigned char*) name; *p1; p1++) {
    318             int i = 8;
    319             char c = *p1;
    320 
    321             if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
    322 
    323             crc ^= c << 24;
    324             while (i--) crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
    325         }
    326 
    327         /* CRC the class and type as well */
    328         for (p1 = p; p1 < p + 4; p1++) {
    329             int i = 8;
    330             crc ^= *p1 << 24;
    331             while (i--) crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
    332         }
    333 
    334         p += 4;
    335         if (!CHECK_LEN(header, p, plen, 0)) return crc; /* bad packet */
    336     }
    337 
    338     return crc;
    339 }
    340 
    341 size_t resize_packet(HEADER* header, size_t plen, unsigned char* pheader, size_t hlen) {
    342     unsigned char* ansp = skip_questions(header, plen);
    343 
    344     /* if packet is malformed, just return as-is. */
    345     if (!ansp) return plen;
    346 
    347     if (!(ansp = skip_section(
    348               ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
    349               header, plen)))
    350         return plen;
    351 
    352     /* restore pseudoheader */
    353     if (pheader && ntohs(header->arcount) == 0) {
    354         /* must use memmove, may overlap */
    355         memmove(ansp, pheader, hlen);
    356         header->arcount = htons(1);
    357         ansp += hlen;
    358     }
    359 
    360     return ansp - (unsigned char*) header;
    361 }
    362 
    363 unsigned char* find_pseudoheader(HEADER* header, size_t plen, size_t* len, unsigned char** p,
    364                                  int* is_sign) {
    365     /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
    366        also return length of pseudoheader in *len and pointer to the UDP size in *p
    367        Finally, check to see if a packet is signed. If it is we cannot change a single bit before
    368        forwarding. We look for SIG and TSIG in the addition section, and TKEY queries (for GSS-TSIG) */
    369 
    370     int i, arcount = ntohs(header->arcount);
    371     unsigned char* ansp = (unsigned char*) (header + 1);
    372     unsigned short rdlen, type, class;
    373     unsigned char* ret = NULL;
    374 
    375     if (is_sign) {
    376         *is_sign = 0;
    377 
    378         if (header->opcode == QUERY) {
    379             for (i = ntohs(header->qdcount); i != 0; i--) {
    380                 if (!(ansp = skip_name(ansp, header, plen, 4))) return NULL;
    381 
    382                 GETSHORT(type, ansp);
    383                 GETSHORT(class, ansp);
    384 
    385                 if (class == C_IN && type == T_TKEY) *is_sign = 1;
    386             }
    387         }
    388     } else {
    389         if (!(ansp = skip_questions(header, plen))) return NULL;
    390     }
    391 
    392     if (arcount == 0) return NULL;
    393 
    394     if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount), header, plen)))
    395         return NULL;
    396 
    397     for (i = 0; i < arcount; i++) {
    398         unsigned char *save, *start = ansp;
    399         if (!(ansp = skip_name(ansp, header, plen, 10))) return NULL;
    400 
    401         GETSHORT(type, ansp);
    402         save = ansp;
    403         GETSHORT(class, ansp);
    404         ansp += 4; /* TTL */
    405         GETSHORT(rdlen, ansp);
    406         if (!ADD_RDLEN(header, ansp, plen, rdlen)) return NULL;
    407         if (type == T_OPT) {
    408             if (len) *len = ansp - start;
    409             if (p) *p = save;
    410             ret = start;
    411         } else if (is_sign && i == arcount - 1 && class == C_ANY &&
    412                    (type == T_SIG || type == T_TSIG))
    413             *is_sign = 1;
    414     }
    415 
    416     return ret;
    417 }
    418 
    419 /* is addr in the non-globally-routed IP space? */
    420 static int private_net(struct in_addr addr) {
    421     in_addr_t ip_addr = ntohl(addr.s_addr);
    422 
    423     return ((ip_addr & 0xFF000000) == 0x7F000000) /* 127.0.0.0/8    (loopback) */ ||
    424            ((ip_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168.0.0/16 (private)  */ ||
    425            ((ip_addr & 0xFF000000) == 0x0A000000) /* 10.0.0.0/8     (private)  */ ||
    426            ((ip_addr & 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12  (private)  */ ||
    427            ((ip_addr & 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */;
    428 }
    429 
    430 static unsigned char* do_doctor(unsigned char* p, int count, HEADER* header, size_t qlen) {
    431     int i, qtype, qclass, rdlen;
    432     unsigned long ttl;
    433 
    434     for (i = count; i != 0; i--) {
    435         if (!(p = skip_name(p, header, qlen, 10))) return 0; /* bad packet */
    436 
    437         GETSHORT(qtype, p);
    438         GETSHORT(qclass, p);
    439         GETLONG(ttl, p);
    440         GETSHORT(rdlen, p);
    441 
    442         if ((qclass == C_IN) && (qtype == T_A)) {
    443             struct doctor* doctor;
    444             struct in_addr addr;
    445 
    446             if (!CHECK_LEN(header, p, qlen, INADDRSZ)) return 0;
    447 
    448             /* alignment */
    449             memcpy(&addr, p, INADDRSZ);
    450 
    451             for (doctor = daemon->doctors; doctor; doctor = doctor->next) {
    452                 if (doctor->end.s_addr == 0) {
    453                     if (!is_same_net(doctor->in, addr, doctor->mask)) continue;
    454                 } else if (ntohl(doctor->in.s_addr) > ntohl(addr.s_addr) ||
    455                            ntohl(doctor->end.s_addr) < ntohl(addr.s_addr))
    456                     continue;
    457 
    458                 addr.s_addr &= ~doctor->mask.s_addr;
    459                 addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
    460                 /* Since we munged the data, the server it came from is no longer authoritative */
    461                 header->aa = 0;
    462                 memcpy(p, &addr, INADDRSZ);
    463                 break;
    464             }
    465         }
    466 
    467         if (!ADD_RDLEN(header, p, qlen, rdlen)) return 0; /* bad packet */
    468     }
    469 
    470     return p;
    471 }
    472 
    473 static int find_soa(HEADER* header, size_t qlen) {
    474     unsigned char* p;
    475     int qtype, qclass, rdlen;
    476     unsigned long ttl, minttl = ULONG_MAX;
    477     int i, found_soa = 0;
    478 
    479     /* first move to NS section and find TTL from any SOA section */
    480     if (!(p = skip_questions(header, qlen)) ||
    481         !(p = do_doctor(p, ntohs(header->ancount), header, qlen)))
    482         return 0; /* bad packet */
    483 
    484     for (i = ntohs(header->nscount); i != 0; i--) {
    485         if (!(p = skip_name(p, header, qlen, 10))) return 0; /* bad packet */
    486 
    487         GETSHORT(qtype, p);
    488         GETSHORT(qclass, p);
    489         GETLONG(ttl, p);
    490         GETSHORT(rdlen, p);
    491 
    492         if ((qclass == C_IN) && (qtype == T_SOA)) {
    493             found_soa = 1;
    494             if (ttl < minttl) minttl = ttl;
    495 
    496             /* MNAME */
    497             if (!(p = skip_name(p, header, qlen, 0))) return 0;
    498             /* RNAME */
    499             if (!(p = skip_name(p, header, qlen, 20))) return 0;
    500             p += 16; /* SERIAL REFRESH RETRY EXPIRE */
    501 
    502             GETLONG(ttl, p); /* minTTL */
    503             if (ttl < minttl) minttl = ttl;
    504         } else if (!ADD_RDLEN(header, p, qlen, rdlen))
    505             return 0; /* bad packet */
    506     }
    507 
    508     /* rewrite addresses in additioal section too */
    509     if (!do_doctor(p, ntohs(header->arcount), header, qlen)) return 0;
    510 
    511     if (!found_soa) minttl = daemon->neg_ttl;
    512 
    513     return minttl;
    514 }
    515 
    516 /* Note that the following code can create CNAME chains that don't point to a real record,
    517    either because of lack of memory, or lack of SOA records.  These are treated by the cache code as
    518    expired and cleaned out that way.
    519    Return 1 if we reject an address because it look like parct of dns-rebinding attack. */
    520 int extract_addresses(HEADER* header, size_t qlen, char* name, time_t now) {
    521     unsigned char *p, *p1, *endrr, *namep;
    522     int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
    523     unsigned long ttl = 0;
    524     struct all_addr addr;
    525 
    526     cache_start_insert();
    527 
    528     /* find_soa is needed for dns_doctor side-effects, so don't call it lazily if there are any. */
    529     if (daemon->doctors) {
    530         searched_soa = 1;
    531         ttl = find_soa(header, qlen);
    532     }
    533 
    534     /* go through the questions. */
    535     p = (unsigned char*) (header + 1);
    536 
    537     for (i = ntohs(header->qdcount); i != 0; i--) {
    538         int found = 0, cname_count = 5;
    539         struct crec* cpp = NULL;
    540         int flags = header->rcode == NXDOMAIN ? F_NXDOMAIN : 0;
    541         unsigned long cttl = ULONG_MAX, attl;
    542 
    543         namep = p;
    544         if (!extract_name(header, qlen, &p, name, 1, 4)) return 0; /* bad packet */
    545 
    546         GETSHORT(qtype, p);
    547         GETSHORT(qclass, p);
    548 
    549         if (qclass != C_IN) continue;
    550 
    551         /* PTRs: we chase CNAMEs here, since we have no way to
    552        represent them in the cache. */
    553         if (qtype == T_PTR) {
    554             int name_encoding = in_arpa_name_2_addr(name, &addr);
    555 
    556             if (!name_encoding) continue;
    557 
    558             if (!(flags & F_NXDOMAIN)) {
    559             cname_loop:
    560                 if (!(p1 = skip_questions(header, qlen))) return 0;
    561 
    562                 for (j = ntohs(header->ancount); j != 0; j--) {
    563                     unsigned char* tmp = namep;
    564                     /* the loop body overwrites the original name, so get it back here. */
    565                     if (!extract_name(header, qlen, &tmp, name, 1, 0) ||
    566                         !(res = extract_name(header, qlen, &p1, name, 0, 10)))
    567                         return 0; /* bad packet */
    568 
    569                     GETSHORT(aqtype, p1);
    570                     GETSHORT(aqclass, p1);
    571                     GETLONG(attl, p1);
    572                     GETSHORT(ardlen, p1);
    573                     endrr = p1 + ardlen;
    574 
    575                     /* TTL of record is minimum of CNAMES and PTR */
    576                     if (attl < cttl) cttl = attl;
    577 
    578                     if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR)) {
    579                         if (!extract_name(header, qlen, &p1, name, 1, 0)) return 0;
    580 
    581                         if (aqtype == T_CNAME) {
    582                             if (!cname_count--) return 0; /* looped CNAMES */
    583                             goto cname_loop;
    584                         }
    585 
    586                         cache_insert(name, &addr, now, cttl, name_encoding | F_REVERSE);
    587                         found = 1;
    588                     }
    589 
    590                     p1 = endrr;
    591                     if (!CHECK_LEN(header, p1, qlen, 0)) return 0; /* bad packet */
    592                 }
    593             }
    594 
    595             if (!found && !(daemon->options & OPT_NO_NEG)) {
    596                 if (!searched_soa) {
    597                     searched_soa = 1;
    598                     ttl = find_soa(header, qlen);
    599                 }
    600                 if (ttl)
    601                     cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags);
    602             }
    603         } else {
    604             /* everything other than PTR */
    605             struct crec* newc;
    606             int addrlen;
    607 
    608             if (qtype == T_A) {
    609                 addrlen = INADDRSZ;
    610                 flags |= F_IPV4;
    611             }
    612 #ifdef HAVE_IPV6
    613             else if (qtype == T_AAAA) {
    614                 addrlen = IN6ADDRSZ;
    615                 flags |= F_IPV6;
    616             }
    617 #endif
    618             else
    619                 continue;
    620 
    621             if (!(flags & F_NXDOMAIN)) {
    622             cname_loop1:
    623                 if (!(p1 = skip_questions(header, qlen))) return 0;
    624 
    625                 for (j = ntohs(header->ancount); j != 0; j--) {
    626                     if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
    627                         return 0; /* bad packet */
    628 
    629                     GETSHORT(aqtype, p1);
    630                     GETSHORT(aqclass, p1);
    631                     GETLONG(attl, p1);
    632                     GETSHORT(ardlen, p1);
    633                     endrr = p1 + ardlen;
    634 
    635                     if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype)) {
    636                         if (aqtype == T_CNAME) {
    637                             if (!cname_count--) return 0; /* looped CNAMES */
    638                             newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD);
    639                             if (newc && cpp) {
    640                                 cpp->addr.cname.cache = newc;
    641                                 cpp->addr.cname.uid = newc->uid;
    642                             }
    643 
    644                             cpp = newc;
    645                             if (attl < cttl) cttl = attl;
    646 
    647                             if (!extract_name(header, qlen, &p1, name, 1, 0)) return 0;
    648                             goto cname_loop1;
    649                         } else {
    650                             found = 1;
    651 
    652                             /* copy address into aligned storage */
    653                             if (!CHECK_LEN(header, p1, qlen, addrlen)) return 0; /* bad packet */
    654                             memcpy(&addr, p1, addrlen);
    655 
    656                             /* check for returned address in private space */
    657                             if ((daemon->options & OPT_NO_REBIND) && (flags & F_IPV4) &&
    658                                 private_net(addr.addr.addr4))
    659                                 return 1;
    660 
    661                             newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
    662                             if (newc && cpp) {
    663                                 cpp->addr.cname.cache = newc;
    664                                 cpp->addr.cname.uid = newc->uid;
    665                             }
    666                             cpp = NULL;
    667                         }
    668                     }
    669 
    670                     p1 = endrr;
    671                     if (!CHECK_LEN(header, p1, qlen, 0)) return 0; /* bad packet */
    672                 }
    673             }
    674 
    675             if (!found && !(daemon->options & OPT_NO_NEG)) {
    676                 if (!searched_soa) {
    677                     searched_soa = 1;
    678                     ttl = find_soa(header, qlen);
    679                 }
    680                 /* If there's no SOA to get the TTL from, but there is a CNAME
    681                pointing at this, inherit its TTL */
    682                 if (ttl || cpp) {
    683                     newc =
    684                         cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags);
    685                     if (newc && cpp) {
    686                         cpp->addr.cname.cache = newc;
    687                         cpp->addr.cname.uid = newc->uid;
    688                     }
    689                 }
    690             }
    691         }
    692     }
    693 
    694     /* Don't put stuff from a truncated packet into the cache, but do everything else */
    695     if (!header->tc) cache_end_insert();
    696 
    697     return 0;
    698 }
    699 
    700 /* If the packet holds exactly one query
    701    return F_IPV4 or F_IPV6  and leave the name from the query in name.
    702    Abuse F_BIGNAME to indicate an NS query - yuck. */
    703 
    704 unsigned short extract_request(HEADER* header, size_t qlen, char* name, unsigned short* typep) {
    705     unsigned char* p = (unsigned char*) (header + 1);
    706     int qtype, qclass;
    707 
    708     if (typep) *typep = 0;
    709 
    710     if (ntohs(header->qdcount) != 1 || header->opcode != QUERY)
    711         return 0; /* must be exactly one query. */
    712 
    713     if (!extract_name(header, qlen, &p, name, 1, 4)) return 0; /* bad packet */
    714 
    715     GETSHORT(qtype, p);
    716     GETSHORT(qclass, p);
    717 
    718     if (typep) *typep = qtype;
    719 
    720     if (qclass == C_IN) {
    721         if (qtype == T_A) return F_IPV4;
    722         if (qtype == T_AAAA) return F_IPV6;
    723         if (qtype == T_ANY) return F_IPV4 | F_IPV6;
    724         if (qtype == T_NS || qtype == T_SOA) return F_QUERY | F_BIGNAME;
    725     }
    726 
    727     return F_QUERY;
    728 }
    729 
    730 size_t setup_reply(HEADER* header, size_t qlen, struct all_addr* addrp, unsigned short flags,
    731                    unsigned long ttl) {
    732     unsigned char* p;
    733 
    734     if (!(p = skip_questions(header, qlen))) return 0;
    735 
    736     header->qr = 1; /* response */
    737     header->aa = 0; /* authoritive */
    738     header->ra = 1; /* recursion if available */
    739     header->tc = 0; /* not truncated */
    740     header->nscount = htons(0);
    741     header->arcount = htons(0);
    742     header->ancount = htons(0); /* no answers unless changed below */
    743     if (flags == F_NEG)
    744         header->rcode = SERVFAIL; /* couldn't get memory */
    745     else if (flags == F_NOERR)
    746         header->rcode = NOERROR; /* empty domain */
    747     else if (flags == F_NXDOMAIN)
    748         header->rcode = NXDOMAIN;
    749     else if (flags == F_IPV4) { /* we know the address */
    750         header->rcode = NOERROR;
    751         header->ancount = htons(1);
    752         header->aa = 1;
    753         add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_A, C_IN, "4",
    754                             addrp);
    755     }
    756 #ifdef HAVE_IPV6
    757     else if (flags == F_IPV6) {
    758         header->rcode = NOERROR;
    759         header->ancount = htons(1);
    760         header->aa = 1;
    761         add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_AAAA, C_IN, "6",
    762                             addrp);
    763     }
    764 #endif
    765     else /* nowhere to forward to */
    766         header->rcode = REFUSED;
    767 
    768     return p - (unsigned char*) header;
    769 }
    770 
    771 /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
    772 int check_for_local_domain(char* name, time_t now) {
    773     struct crec* crecp;
    774     struct mx_srv_record* mx;
    775     struct txt_record* txt;
    776     struct interface_name* intr;
    777     struct ptr_record* ptr;
    778 
    779     if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)) &&
    780         (crecp->flags & (F_HOSTS | F_DHCP)))
    781         return 1;
    782 
    783     for (mx = daemon->mxnames; mx; mx = mx->next)
    784         if (hostname_isequal(name, mx->name)) return 1;
    785 
    786     for (txt = daemon->txt; txt; txt = txt->next)
    787         if (hostname_isequal(name, txt->name)) return 1;
    788 
    789     for (intr = daemon->int_names; intr; intr = intr->next)
    790         if (hostname_isequal(name, intr->name)) return 1;
    791 
    792     for (ptr = daemon->ptr; ptr; ptr = ptr->next)
    793         if (hostname_isequal(name, ptr->name)) return 1;
    794 
    795     return 0;
    796 }
    797 
    798 /* Is the packet a reply with the answer address equal to addr?
    799    If so mung is into an NXDOMAIN reply and also put that information
    800    in the cache. */
    801 int check_for_bogus_wildcard(HEADER* header, size_t qlen, char* name, struct bogus_addr* baddr,
    802                              time_t now) {
    803     unsigned char* p;
    804     int i, qtype, qclass, rdlen;
    805     unsigned long ttl;
    806     struct bogus_addr* baddrp;
    807 
    808     /* skip over questions */
    809     if (!(p = skip_questions(header, qlen))) return 0; /* bad packet */
    810 
    811     for (i = ntohs(header->ancount); i != 0; i--) {
    812         if (!extract_name(header, qlen, &p, name, 1, 10)) return 0; /* bad packet */
    813 
    814         GETSHORT(qtype, p);
    815         GETSHORT(qclass, p);
    816         GETLONG(ttl, p);
    817         GETSHORT(rdlen, p);
    818 
    819         if (qclass == C_IN && qtype == T_A) {
    820             if (!CHECK_LEN(header, p, qlen, INADDRSZ)) return 0;
    821 
    822             for (baddrp = baddr; baddrp; baddrp = baddrp->next)
    823                 if (memcmp(&baddrp->addr, p, INADDRSZ) == 0) {
    824                     /* Found a bogus address. Insert that info here, since there no SOA record
    825                        to get the ttl from in the normal processing */
    826                     cache_start_insert();
    827                     cache_insert(name, NULL, now, ttl,
    828                                  F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN | F_CONFIG);
    829                     cache_end_insert();
    830 
    831                     return 1;
    832                 }
    833         }
    834 
    835         if (!ADD_RDLEN(header, p, qlen, rdlen)) return 0;
    836     }
    837 
    838     return 0;
    839 }
    840 
    841 static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigned int nameoffset,
    842                                unsigned char** pp, unsigned long ttl, unsigned int* offset,
    843                                unsigned short type, unsigned short class, char* format, ...) {
    844     va_list ap;
    845     unsigned char *sav, *p = *pp;
    846     int j;
    847     unsigned short usval;
    848     long lval;
    849     char* sval;
    850 
    851     if (truncp && *truncp) return 0;
    852 
    853     PUTSHORT(nameoffset | 0xc000, p);
    854     PUTSHORT(type, p);
    855     PUTSHORT(class, p);
    856     PUTLONG(ttl, p); /* TTL */
    857 
    858     sav = p;        /* Save pointer to RDLength field */
    859     PUTSHORT(0, p); /* Placeholder RDLength */
    860 
    861     va_start(ap, format); /* make ap point to 1st unamed argument */
    862 
    863     for (; *format; format++) switch (*format) {
    864 #ifdef HAVE_IPV6
    865             case '6':
    866                 sval = va_arg(ap, char*);
    867                 memcpy(p, sval, IN6ADDRSZ);
    868                 p += IN6ADDRSZ;
    869                 break;
    870 #endif
    871 
    872             case '4':
    873                 sval = va_arg(ap, char*);
    874                 memcpy(p, sval, INADDRSZ);
    875                 p += INADDRSZ;
    876                 break;
    877 
    878             case 's':
    879                 usval = va_arg(ap, int);
    880                 PUTSHORT(usval, p);
    881                 break;
    882 
    883             case 'l':
    884                 lval = va_arg(ap, long);
    885                 PUTLONG(lval, p);
    886                 break;
    887 
    888             case 'd':
    889                 /* get domain-name answer arg and store it in RDATA field */
    890                 if (offset) *offset = p - (unsigned char*) header;
    891                 p = do_rfc1035_name(p, va_arg(ap, char*));
    892                 *p++ = 0;
    893                 break;
    894 
    895             case 't':
    896                 usval = va_arg(ap, int);
    897                 sval = va_arg(ap, char*);
    898                 memcpy(p, sval, usval);
    899                 p += usval;
    900                 break;
    901 
    902             case 'z':
    903                 sval = va_arg(ap, char*);
    904                 usval = sval ? strlen(sval) : 0;
    905                 if (usval > 255) usval = 255;
    906                 *p++ = (unsigned char) usval;
    907                 memcpy(p, sval, usval);
    908                 p += usval;
    909                 break;
    910         }
    911 
    912     va_end(ap); /* clean up variable argument pointer */
    913 
    914     j = p - sav - 2;
    915     PUTSHORT(j, sav); /* Now, store real RDLength */
    916 
    917     /* check for overflow of buffer */
    918     if (limit && ((unsigned char*) limit - p) < 0) {
    919         if (truncp) *truncp = 1;
    920         return 0;
    921     }
    922 
    923     *pp = p;
    924     return 1;
    925 }
    926 
    927 static unsigned long crec_ttl(struct crec* crecp, time_t now) {
    928     /* Return 0 ttl for DHCP entries, which might change
    929        before the lease expires. */
    930 
    931     if (crecp->flags & (F_IMMORTAL | F_DHCP)) return daemon->local_ttl;
    932 
    933     return crecp->ttd - now;
    934 }
    935 
    936 /* return zero if we can't answer from cache, or packet size if we can */
    937 size_t answer_request(HEADER* header, char* limit, size_t qlen, struct in_addr local_addr,
    938                       struct in_addr local_netmask, time_t now) {
    939     char* name = daemon->namebuff;
    940     unsigned char *p, *ansp, *pheader;
    941     int qtype, qclass;
    942     struct all_addr addr;
    943     unsigned int nameoffset;
    944     unsigned short flag;
    945     int q, ans, anscount = 0, addncount = 0;
    946     int dryrun = 0, sec_reqd = 0;
    947     int is_sign;
    948     struct crec* crecp;
    949     int nxdomain = 0, auth = 1, trunc = 0;
    950     struct mx_srv_record* rec;
    951 
    952     // Make sure we do not underflow here too.
    953     if (qlen > (size_t)(limit - ((char*) header))) return 0;
    954 
    955     /* If there is an RFC2671 pseudoheader then it will be overwritten by
    956        partial replies, so we have to do a dry run to see if we can answer
    957        the query. We check to see if the do bit is set, if so we always
    958        forward rather than answering from the cache, which doesn't include
    959        security information. */
    960 
    961     if (find_pseudoheader(header, qlen, NULL, &pheader, &is_sign)) {
    962         unsigned short udpsz, ext_rcode, flags;
    963         unsigned char* psave = pheader;
    964 
    965         GETSHORT(udpsz, pheader);
    966         GETSHORT(ext_rcode, pheader);
    967         GETSHORT(flags, pheader);
    968 
    969         sec_reqd = flags & 0x8000; /* do bit */
    970 
    971         /* If our client is advertising a larger UDP packet size
    972        than we allow, trim it so that we don't get an overlarge
    973        response from upstream */
    974 
    975         if (!is_sign && (udpsz > daemon->edns_pktsz)) PUTSHORT(daemon->edns_pktsz, psave);
    976 
    977         dryrun = 1;
    978     }
    979 
    980     if (ntohs(header->qdcount) == 0 || header->opcode != QUERY) return 0;
    981 
    982     for (rec = daemon->mxnames; rec; rec = rec->next) rec->offset = 0;
    983 
    984 rerun:
    985     /* determine end of question section (we put answers there) */
    986     if (!(ansp = skip_questions(header, qlen))) return 0; /* bad packet */
    987 
    988     /* now process each question, answers go in RRs after the question */
    989     p = (unsigned char*) (header + 1);
    990 
    991     for (q = ntohs(header->qdcount); q != 0; q--) {
    992         /* save pointer to name for copying into answers */
    993         nameoffset = p - (unsigned char*) header;
    994 
    995         /* now extract name as .-concatenated string into name */
    996         if (!extract_name(header, qlen, &p, name, 1, 4)) return 0; /* bad packet */
    997 
    998         GETSHORT(qtype, p);
    999         GETSHORT(qclass, p);
   1000 
   1001         ans = 0; /* have we answered this question */
   1002 
   1003         if (qtype == T_TXT || qtype == T_ANY) {
   1004             struct txt_record* t;
   1005             for (t = daemon->txt; t; t = t->next) {
   1006                 if (t->class == qclass && hostname_isequal(name, t->name)) {
   1007                     ans = 1;
   1008                     if (!dryrun) {
   1009                         log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<TXT>");
   1010                         if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1011                                                 daemon->local_ttl, NULL, T_TXT, t->class, "t",
   1012                                                 t->len, t->txt))
   1013                             anscount++;
   1014                     }
   1015                 }
   1016             }
   1017         }
   1018 
   1019         if (qclass == C_IN) {
   1020             if (qtype == T_PTR || qtype == T_ANY) {
   1021                 /* see if it's w.z.y.z.in-addr.arpa format */
   1022                 int is_arpa = in_arpa_name_2_addr(name, &addr);
   1023                 struct ptr_record* ptr;
   1024                 struct interface_name* intr = NULL;
   1025 
   1026                 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
   1027                     if (hostname_isequal(name, ptr->name)) break;
   1028 
   1029                 if (is_arpa == F_IPV4)
   1030                     for (intr = daemon->int_names; intr; intr = intr->next) {
   1031                         if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr)
   1032                             break;
   1033                         else
   1034                             while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
   1035                                 intr = intr->next;
   1036                     }
   1037 
   1038                 if (intr) {
   1039                     ans = 1;
   1040                     if (!dryrun) {
   1041                         log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
   1042                         if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1043                                                 daemon->local_ttl, NULL, T_PTR, C_IN, "d",
   1044                                                 intr->name))
   1045                             anscount++;
   1046                     }
   1047                 } else if (ptr) {
   1048                     ans = 1;
   1049                     if (!dryrun) {
   1050                         log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<PTR>");
   1051                         for (ptr = daemon->ptr; ptr; ptr = ptr->next)
   1052                             if (hostname_isequal(name, ptr->name) &&
   1053                                 add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1054                                                     daemon->local_ttl, NULL, T_PTR, C_IN, "d",
   1055                                                     ptr->ptr))
   1056                                 anscount++;
   1057                     }
   1058                 } else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
   1059                     do {
   1060                         /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
   1061                         if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP))) continue;
   1062 
   1063                         if (crecp->flags & F_NEG) {
   1064                             ans = 1;
   1065                             auth = 0;
   1066                             if (crecp->flags & F_NXDOMAIN) nxdomain = 1;
   1067                             if (!dryrun) log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
   1068                         } else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd) {
   1069                             ans = 1;
   1070                             if (!(crecp->flags & (F_HOSTS | F_DHCP))) auth = 0;
   1071                             if (!dryrun) {
   1072                                 log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
   1073                                           record_source(crecp->uid));
   1074 
   1075                                 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1076                                                         crec_ttl(crecp, now), NULL, T_PTR, C_IN,
   1077                                                         "d", cache_get_name(crecp)))
   1078                                     anscount++;
   1079                             }
   1080                         }
   1081                     } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
   1082                 else if (is_arpa == F_IPV4 && (daemon->options & OPT_BOGUSPRIV) &&
   1083                          private_net(addr.addr.addr4)) {
   1084                     /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
   1085                     ans = 1;
   1086                     nxdomain = 1;
   1087                     if (!dryrun)
   1088                         log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN, name, &addr,
   1089                                   NULL);
   1090                 }
   1091             }
   1092 
   1093             for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0) {
   1094                 unsigned short type = T_A;
   1095 
   1096                 if (flag == F_IPV6)
   1097 #ifdef HAVE_IPV6
   1098                     type = T_AAAA;
   1099 #else
   1100                     break;
   1101 #endif
   1102 
   1103                 if (qtype != type && qtype != T_ANY) continue;
   1104 
   1105                 /* Check for "A for A"  queries */
   1106                 if (qtype == T_A && (addr.addr.addr4.s_addr = inet_addr(name)) != (in_addr_t) -1) {
   1107                     ans = 1;
   1108                     if (!dryrun) {
   1109                         log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
   1110                         if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1111                                                 daemon->local_ttl, NULL, type, C_IN, "4", &addr))
   1112                             anscount++;
   1113                     }
   1114                     continue;
   1115                 }
   1116 
   1117                 /* interface name stuff */
   1118                 if (qtype == T_A) {
   1119                     struct interface_name* intr;
   1120 
   1121                     for (intr = daemon->int_names; intr; intr = intr->next)
   1122                         if (hostname_isequal(name, intr->name)) break;
   1123 
   1124                     if (intr) {
   1125                         ans = 1;
   1126                         if (!dryrun) {
   1127                             if ((addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr == (in_addr_t) -1)
   1128                                 log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, NULL);
   1129                             else {
   1130                                 log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
   1131                                 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1132                                                         daemon->local_ttl, NULL, type, C_IN, "4",
   1133                                                         &addr))
   1134                                     anscount++;
   1135                             }
   1136                         }
   1137                         continue;
   1138                     }
   1139                 }
   1140 
   1141             cname_restart:
   1142                 if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME))) {
   1143                     int localise = 0;
   1144 
   1145                     /* See if a putative address is on the network from which we recieved
   1146                        the query, is so we'll filter other answers. */
   1147                     if (local_addr.s_addr != 0 && (daemon->options & OPT_LOCALISE) &&
   1148                         flag == F_IPV4) {
   1149                         struct crec* save = crecp;
   1150                         do {
   1151                             if ((crecp->flags & F_HOSTS) &&
   1152                                 is_same_net(*((struct in_addr*) &crecp->addr), local_addr,
   1153                                             local_netmask)) {
   1154                                 localise = 1;
   1155                                 break;
   1156                             }
   1157                         } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
   1158                         crecp = save;
   1159                     }
   1160 
   1161                     do {
   1162                         /* don't answer wildcard queries with data not from /etc/hosts
   1163                        or DHCP leases */
   1164                         if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP))) break;
   1165 
   1166                         if (crecp->flags & F_CNAME) {
   1167                             if (!dryrun) {
   1168                                 log_query(crecp->flags, name, NULL, record_source(crecp->uid));
   1169                                 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1170                                                         crec_ttl(crecp, now), &nameoffset, T_CNAME,
   1171                                                         C_IN, "d",
   1172                                                         cache_get_name(crecp->addr.cname.cache)))
   1173                                     anscount++;
   1174                             }
   1175 
   1176                             strcpy(name, cache_get_name(crecp->addr.cname.cache));
   1177                             goto cname_restart;
   1178                         }
   1179 
   1180                         if (crecp->flags & F_NEG) {
   1181                             ans = 1;
   1182                             auth = 0;
   1183                             if (crecp->flags & F_NXDOMAIN) nxdomain = 1;
   1184                             if (!dryrun) log_query(crecp->flags, name, NULL, NULL);
   1185                         } else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd) {
   1186                             /* If we are returning local answers depending on network,
   1187                                filter here. */
   1188                             if (localise && (crecp->flags & F_HOSTS) &&
   1189                                 !is_same_net(*((struct in_addr*) &crecp->addr), local_addr,
   1190                                              local_netmask))
   1191                                 continue;
   1192 
   1193                             if (!(crecp->flags & (F_HOSTS | F_DHCP))) auth = 0;
   1194 
   1195                             ans = 1;
   1196                             if (!dryrun) {
   1197                                 log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
   1198                                           record_source(crecp->uid));
   1199 
   1200                                 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1201                                                         crec_ttl(crecp, now), NULL, type, C_IN,
   1202                                                         type == T_A ? "4" : "6", &crecp->addr))
   1203                                     anscount++;
   1204                             }
   1205                         }
   1206                     } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
   1207                 }
   1208             }
   1209 
   1210             if (qtype == T_MX || qtype == T_ANY) {
   1211                 int found = 0;
   1212                 for (rec = daemon->mxnames; rec; rec = rec->next)
   1213                     if (!rec->issrv && hostname_isequal(name, rec->name)) {
   1214                         ans = found = 1;
   1215                         if (!dryrun) {
   1216                             unsigned int offset;
   1217                             log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL,
   1218                                       "<MX>");
   1219                             if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1220                                                     daemon->local_ttl, &offset, T_MX, C_IN, "sd",
   1221                                                     rec->weight, rec->target)) {
   1222                                 anscount++;
   1223                                 if (rec->target) rec->offset = offset;
   1224                             }
   1225                         }
   1226                     }
   1227 
   1228                 if (!found && (daemon->options & (OPT_SELFMX | OPT_LOCALMX)) &&
   1229                     cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP)) {
   1230                     ans = 1;
   1231                     if (!dryrun) {
   1232                         log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>");
   1233                         if (add_resource_record(
   1234                                 header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
   1235                                 T_MX, C_IN, "sd", 1,
   1236                                 (daemon->options & OPT_SELFMX) ? name : daemon->mxtarget))
   1237                             anscount++;
   1238                     }
   1239                 }
   1240             }
   1241 
   1242             if (qtype == T_SRV || qtype == T_ANY) {
   1243                 int found = 0;
   1244 
   1245                 for (rec = daemon->mxnames; rec; rec = rec->next)
   1246                     if (rec->issrv && hostname_isequal(name, rec->name)) {
   1247                         found = ans = 1;
   1248                         if (!dryrun) {
   1249                             unsigned int offset;
   1250                             log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL,
   1251                                       "<SRV>");
   1252                             if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1253                                                     daemon->local_ttl, &offset, T_SRV, C_IN, "sssd",
   1254                                                     rec->priority, rec->weight, rec->srvport,
   1255                                                     rec->target)) {
   1256                                 anscount++;
   1257                                 if (rec->target) rec->offset = offset;
   1258                             }
   1259                         }
   1260                     }
   1261 
   1262                 if (!found && (daemon->options & OPT_FILTER) &&
   1263                     (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_')))) {
   1264                     ans = 1;
   1265                     if (!dryrun) log_query(F_CONFIG | F_NEG, name, NULL, NULL);
   1266                 }
   1267             }
   1268 
   1269             if (qtype == T_NAPTR || qtype == T_ANY) {
   1270                 struct naptr* na;
   1271                 for (na = daemon->naptr; na; na = na->next)
   1272                     if (hostname_isequal(name, na->name)) {
   1273                         ans = 1;
   1274                         if (!dryrun) {
   1275                             log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL,
   1276                                       "<NAPTR>");
   1277                             if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
   1278                                                     daemon->local_ttl, NULL, T_NAPTR, C_IN,
   1279                                                     "sszzzd", na->order, na->pref, na->flags,
   1280                                                     na->services, na->regexp, na->replace))
   1281                                 anscount++;
   1282                         }
   1283                     }
   1284             }
   1285 
   1286             if (qtype == T_MAILB) ans = 1, nxdomain = 1;
   1287 
   1288             if (qtype == T_SOA && (daemon->options & OPT_FILTER)) {
   1289                 ans = 1;
   1290                 if (!dryrun) log_query(F_CONFIG | F_NEG, name, &addr, NULL);
   1291             }
   1292         }
   1293 
   1294         if (!ans) return 0; /* failed to answer a question */
   1295     }
   1296 
   1297     if (dryrun) {
   1298         dryrun = 0;
   1299         goto rerun;
   1300     }
   1301 
   1302     /* create an additional data section, for stuff in SRV and MX record replies. */
   1303     for (rec = daemon->mxnames; rec; rec = rec->next)
   1304         if (rec->offset != 0) {
   1305             /* squash dupes */
   1306             struct mx_srv_record* tmp;
   1307             for (tmp = rec->next; tmp; tmp = tmp->next)
   1308                 if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target)) tmp->offset = 0;
   1309 
   1310             crecp = NULL;
   1311             while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6))) {
   1312 #ifdef HAVE_IPV6
   1313                 int type = crecp->flags & F_IPV4 ? T_A : T_AAAA;
   1314 #else
   1315                 int type = T_A;
   1316 #endif
   1317                 if (crecp->flags & F_NEG) continue;
   1318 
   1319                 if (add_resource_record(header, limit, NULL, rec->offset, &ansp,
   1320                                         crec_ttl(crecp, now), NULL, type, C_IN,
   1321                                         crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
   1322                     addncount++;
   1323             }
   1324         }
   1325 
   1326     /* done all questions, set up header and return length of result */
   1327     header->qr = 1;     /* response */
   1328     header->aa = auth;  /* authoritive - only hosts and DHCP derived names. */
   1329     header->ra = 1;     /* recursion if available */
   1330     header->tc = trunc; /* truncation */
   1331     if (anscount == 0 && nxdomain)
   1332         header->rcode = NXDOMAIN;
   1333     else
   1334         header->rcode = NOERROR; /* no error */
   1335     header->ancount = htons(anscount);
   1336     header->nscount = htons(0);
   1337     header->arcount = htons(addncount);
   1338     return ansp - (unsigned char*) header;
   1339 }
   1340