/* dnsmasq is Copyright (c) 2000-2009 Simon Kelley

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 dated June, 1991, or
   (at your option) version 3 dated 29 June, 2007.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "dnsmasq.h"

static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigned int nameoffset,
                               unsigned char** pp, unsigned long ttl, unsigned int* offset,
                               unsigned short type, unsigned short class, char* format, ...);

#define CHECK_LEN(header, pp, plen, len) \
    ((size_t)((pp) - (unsigned char*) (header) + (len)) <= (plen))

#define ADD_RDLEN(header, pp, plen, len) \
    (!CHECK_LEN(header, pp, plen, len) ? 0 : (long) ((pp) += (len)), 1)

static int extract_name(HEADER* header, size_t plen, unsigned char** pp, char* name, int isExtract,
                        int extrabytes) {
    unsigned char *cp = (unsigned char*) name, *p = *pp, *p1 = NULL;
    unsigned int j, l, hops = 0;
    int retvalue = 1;

    if (isExtract) *cp = 0;

    while (1) {
        unsigned int label_type;

        if (!CHECK_LEN(header, p, plen, 1)) return 0;

        if ((l = *p++) == 0)
        /* end marker */
        {
            /* check that there are the correct no of bytes after the name */
            if (!CHECK_LEN(header, p1 ? p1 : p, plen, extrabytes)) return 0;

            if (isExtract) {
                if (cp != (unsigned char*) name) cp--;
                *cp = 0; /* terminate: lose final period */
            } else if (*cp != 0)
                retvalue = 2;

            if (p1) /* we jumped via compression */
                *pp = p1;
            else
                *pp = p;

            return retvalue;
        }

        label_type = l & 0xc0;

        if (label_type == 0xc0) /* pointer */
        {
            if (!CHECK_LEN(header, p, plen, 1)) return 0;

            /* get offset */
            l = (l & 0x3f) << 8;
            l |= *p++;

            if (!p1) /* first jump, save location to go back to */
                p1 = p;

            hops++; /* break malicious infinite loops */
            if (hops > 255) return 0;

            p = l + (unsigned char*) header;
        } else if (label_type == 0x80)
            return 0;                  /* reserved */
        else if (label_type == 0x40) { /* ELT */
            unsigned int count, digs;

            if ((l & 0x3f) != 1) return 0; /* we only understand bitstrings */

            if (!isExtract) return 0; /* Cannot compare bitsrings */

            count = *p++;
            if (count == 0) count = 256;
            digs = ((count - 1) >> 2) + 1;

            /* output is \[x<hex>/siz]. which is digs+9 chars */
            if (cp - (unsigned char*) name + digs + 9 >= MAXDNAME) return 0;
            if (!CHECK_LEN(header, p, plen, (count - 1) >> 3)) return 0;

            *cp++ = '\\';
            *cp++ = '[';
            *cp++ = 'x';
            for (j = 0; j < digs; j++) {
                unsigned int dig;
                if (j % 2 == 0)
                    dig = *p >> 4;
                else
                    dig = *p++ & 0x0f;

                *cp++ = dig < 10 ? dig + '0' : dig + 'A' - 10;
            }
            cp += sprintf((char*) cp, "/%d]", count);
            /* do this here to overwrite the zero char from sprintf */
            *cp++ = '.';
        } else { /* label_type = 0 -> label. */
            if (cp - (unsigned char*) name + l + 1 >= MAXDNAME) return 0;
            if (!CHECK_LEN(header, p, plen, l)) return 0;

            for (j = 0; j < l; j++, p++)
                if (isExtract) {
                    unsigned char c = *p;
                    if (isascii(c) && !iscntrl(c) && c != '.')
                        *cp++ = *p;
                    else
                        return 0;
                } else {
                    unsigned char c1 = *cp, c2 = *p;

                    if (c1 == 0)
                        retvalue = 2;
                    else {
                        cp++;
                        if (c1 >= 'A' && c1 <= 'Z') c1 += 'a' - 'A';
                        if (c2 >= 'A' && c2 <= 'Z') c2 += 'a' - 'A';

                        if (c1 != c2) retvalue = 2;
                    }
                }

            if (isExtract)
                *cp++ = '.';
            else if (*cp != 0 && *cp++ != '.')
                retvalue = 2;
        }
    }
}

/* Max size of input string (for IPv6) is 75 chars.) */
#define MAXARPANAME 75
static int in_arpa_name_2_addr(char* namein, struct all_addr* addrp) {
    int j;
    char name[MAXARPANAME + 1], *cp1;
    unsigned char* addr = (unsigned char*) addrp;
    char *lastchunk = NULL, *penchunk = NULL;

    if (strlen(namein) > MAXARPANAME) return 0;

    memset(addrp, 0, sizeof(struct all_addr));

    /* turn name into a series of asciiz strings */
    /* j counts no of labels */
    for (j = 1, cp1 = name; *namein; cp1++, namein++)
        if (*namein == '.') {
            penchunk = lastchunk;
            lastchunk = cp1 + 1;
            *cp1 = 0;
            j++;
        } else
            *cp1 = *namein;

    *cp1 = 0;

    if (j < 3) return 0;

    if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr")) {
        /* IP v4 */
        /* address arives as a name of the form
       www.xxx.yyy.zzz.in-addr.arpa
       some of the low order address octets might be missing
       and should be set to zero. */
        for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1) + 1) {
            /* check for digits only (weeds out things like
               50.0/24.67.28.64.in-addr.arpa which are used
               as CNAME targets according to RFC 2317 */
            char* cp;
            for (cp = cp1; *cp; cp++)
                if (!isdigit((int) *cp)) return 0;

            addr[3] = addr[2];
            addr[2] = addr[1];
            addr[1] = addr[0];
            addr[0] = atoi(cp1);
        }

        return F_IPV4;
    }
#ifdef HAVE_IPV6
    else if (hostname_isequal(penchunk, "ip6") &&
             (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa"))) {
        /* IP v6:
           Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa]
           or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa]

       Note that most of these the various reprentations are obsolete and
       left-over from the many DNS-for-IPv6 wars. We support all the formats
       that we can since there is no reason not to.
        */

        /* TODO: does this make sense? */

        if (*name == '\\' && *(name + 1) == '[' && (*(name + 2) == 'x' || *(name + 2) == 'X')) {
            for (j = 0, cp1 = name + 3; *cp1 && isxdigit((int) *cp1) && j < 32; cp1++, j++) {
                char xdig[2];
                xdig[0] = *cp1;
                xdig[1] = 0;
                if (j % 2)
                    addr[j / 2] |= strtol(xdig, NULL, 16);
                else
                    addr[j / 2] = strtol(xdig, NULL, 16) << 4;
            }

            if (*cp1 == '/' && j == 32) return F_IPV6;
        } else {
            for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1) + 1) {
                if (*(cp1 + 1) || !isxdigit((int) *cp1)) return 0;

                for (j = sizeof(struct all_addr) - 1; j > 0; j--)
                    addr[j] = (addr[j] >> 4) | (addr[j - 1] << 4);
                addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4);
            }

            return F_IPV6;
        }
    }
#endif

    return 0;
}

static unsigned char* skip_name(unsigned char* ansp, HEADER* header, size_t plen, int extrabytes) {
    while (1) {
        unsigned int label_type;

        if (!CHECK_LEN(header, ansp, plen, 1)) return NULL;

        label_type = (*ansp) & 0xc0;

        if (label_type == 0xc0) {
            /* pointer for compression. */
            ansp += 2;
            break;
        } else if (label_type == 0x80)
            return NULL; /* reserved */
        else if (label_type == 0x40) {
            /* Extended label type */
            unsigned int count;

            if (!CHECK_LEN(header, ansp, plen, 2)) return NULL;

            if (((*ansp++) & 0x3f) != 1) return NULL; /* we only understand bitstrings */

            count = *(ansp++); /* Bits in bitstring */

            if (count == 0) /* count == 0 means 256 bits */
                ansp += 32;
            else
                ansp += ((count - 1) >> 3) + 1;
        } else { /* label type == 0 Bottom six bits is length */
            unsigned int len = (*ansp++) & 0x3f;

            if (!ADD_RDLEN(header, ansp, plen, len)) return NULL;

            if (len == 0) break; /* zero length label marks the end. */
        }
    }

    if (!CHECK_LEN(header, ansp, plen, extrabytes)) return NULL;

    return ansp;
}

static unsigned char* skip_questions(HEADER* header, size_t plen) {
    int q;
    unsigned char* ansp = (unsigned char*) (header + 1);

    for (q = ntohs(header->qdcount); q != 0; q--) {
        if (!(ansp = skip_name(ansp, header, plen, 4))) return NULL;
        ansp += 4; /* class and type */
    }

    return ansp;
}

static unsigned char* skip_section(unsigned char* ansp, int count, HEADER* header, size_t plen) {
    int i, rdlen;

    for (i = 0; i < count; i++) {
        if (!(ansp = skip_name(ansp, header, plen, 10))) return NULL;
        ansp += 8; /* type, class, TTL */
        GETSHORT(rdlen, ansp);
        if (!ADD_RDLEN(header, ansp, plen, rdlen)) return NULL;
    }

    return ansp;
}

/* CRC the question section. This is used to safely detect query
   retransmision and to detect answers to questions we didn't ask, which
   might be poisoning attacks. Note that we decode the name rather
   than CRC the raw bytes, since replies might be compressed differently.
   We ignore case in the names for the same reason. Return all-ones
   if there is not question section. */
unsigned int questions_crc(HEADER* header, size_t plen, char* name) {
    int q;
    unsigned int crc = 0xffffffff;
    unsigned char *p1, *p = (unsigned char*) (header + 1);

    for (q = ntohs(header->qdcount); q != 0; q--) {
        if (!extract_name(header, plen, &p, name, 1, 4)) return crc; /* bad packet */

        for (p1 = (unsigned char*) name; *p1; p1++) {
            int i = 8;
            char c = *p1;

            if (c >= 'A' && c <= 'Z') c += 'a' - 'A';

            crc ^= c << 24;
            while (i--) crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
        }

        /* CRC the class and type as well */
        for (p1 = p; p1 < p + 4; p1++) {
            int i = 8;
            crc ^= *p1 << 24;
            while (i--) crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1;
        }

        p += 4;
        if (!CHECK_LEN(header, p, plen, 0)) return crc; /* bad packet */
    }

    return crc;
}

size_t resize_packet(HEADER* header, size_t plen, unsigned char* pheader, size_t hlen) {
    unsigned char* ansp = skip_questions(header, plen);

    /* if packet is malformed, just return as-is. */
    if (!ansp) return plen;

    if (!(ansp = skip_section(
              ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount),
              header, plen)))
        return plen;

    /* restore pseudoheader */
    if (pheader && ntohs(header->arcount) == 0) {
        /* must use memmove, may overlap */
        memmove(ansp, pheader, hlen);
        header->arcount = htons(1);
        ansp += hlen;
    }

    return ansp - (unsigned char*) header;
}

unsigned char* find_pseudoheader(HEADER* header, size_t plen, size_t* len, unsigned char** p,
                                 int* is_sign) {
    /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
       also return length of pseudoheader in *len and pointer to the UDP size in *p
       Finally, check to see if a packet is signed. If it is we cannot change a single bit before
       forwarding. We look for SIG and TSIG in the addition section, and TKEY queries (for GSS-TSIG) */

    int i, arcount = ntohs(header->arcount);
    unsigned char* ansp = (unsigned char*) (header + 1);
    unsigned short rdlen, type, class;
    unsigned char* ret = NULL;

    if (is_sign) {
        *is_sign = 0;

        if (header->opcode == QUERY) {
            for (i = ntohs(header->qdcount); i != 0; i--) {
                if (!(ansp = skip_name(ansp, header, plen, 4))) return NULL;

                GETSHORT(type, ansp);
                GETSHORT(class, ansp);

                if (class == C_IN && type == T_TKEY) *is_sign = 1;
            }
        }
    } else {
        if (!(ansp = skip_questions(header, plen))) return NULL;
    }

    if (arcount == 0) return NULL;

    if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount), header, plen)))
        return NULL;

    for (i = 0; i < arcount; i++) {
        unsigned char *save, *start = ansp;
        if (!(ansp = skip_name(ansp, header, plen, 10))) return NULL;

        GETSHORT(type, ansp);
        save = ansp;
        GETSHORT(class, ansp);
        ansp += 4; /* TTL */
        GETSHORT(rdlen, ansp);
        if (!ADD_RDLEN(header, ansp, plen, rdlen)) return NULL;
        if (type == T_OPT) {
            if (len) *len = ansp - start;
            if (p) *p = save;
            ret = start;
        } else if (is_sign && i == arcount - 1 && class == C_ANY &&
                   (type == T_SIG || type == T_TSIG))
            *is_sign = 1;
    }

    return ret;
}

/* is addr in the non-globally-routed IP space? */
static int private_net(struct in_addr addr) {
    in_addr_t ip_addr = ntohl(addr.s_addr);

    return ((ip_addr & 0xFF000000) == 0x7F000000) /* 127.0.0.0/8    (loopback) */ ||
           ((ip_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168.0.0/16 (private)  */ ||
           ((ip_addr & 0xFF000000) == 0x0A000000) /* 10.0.0.0/8     (private)  */ ||
           ((ip_addr & 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12  (private)  */ ||
           ((ip_addr & 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */;
}

static unsigned char* do_doctor(unsigned char* p, int count, HEADER* header, size_t qlen) {
    int i, qtype, qclass, rdlen;
    unsigned long ttl;

    for (i = count; i != 0; i--) {
        if (!(p = skip_name(p, header, qlen, 10))) return 0; /* bad packet */

        GETSHORT(qtype, p);
        GETSHORT(qclass, p);
        GETLONG(ttl, p);
        GETSHORT(rdlen, p);

        if ((qclass == C_IN) && (qtype == T_A)) {
            struct doctor* doctor;
            struct in_addr addr;

            if (!CHECK_LEN(header, p, qlen, INADDRSZ)) return 0;

            /* alignment */
            memcpy(&addr, p, INADDRSZ);

            for (doctor = daemon->doctors; doctor; doctor = doctor->next) {
                if (doctor->end.s_addr == 0) {
                    if (!is_same_net(doctor->in, addr, doctor->mask)) continue;
                } else if (ntohl(doctor->in.s_addr) > ntohl(addr.s_addr) ||
                           ntohl(doctor->end.s_addr) < ntohl(addr.s_addr))
                    continue;

                addr.s_addr &= ~doctor->mask.s_addr;
                addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
                /* Since we munged the data, the server it came from is no longer authoritative */
                header->aa = 0;
                memcpy(p, &addr, INADDRSZ);
                break;
            }
        }

        if (!ADD_RDLEN(header, p, qlen, rdlen)) return 0; /* bad packet */
    }

    return p;
}

static int find_soa(HEADER* header, size_t qlen) {
    unsigned char* p;
    int qtype, qclass, rdlen;
    unsigned long ttl, minttl = ULONG_MAX;
    int i, found_soa = 0;

    /* first move to NS section and find TTL from any SOA section */
    if (!(p = skip_questions(header, qlen)) ||
        !(p = do_doctor(p, ntohs(header->ancount), header, qlen)))
        return 0; /* bad packet */

    for (i = ntohs(header->nscount); i != 0; i--) {
        if (!(p = skip_name(p, header, qlen, 10))) return 0; /* bad packet */

        GETSHORT(qtype, p);
        GETSHORT(qclass, p);
        GETLONG(ttl, p);
        GETSHORT(rdlen, p);

        if ((qclass == C_IN) && (qtype == T_SOA)) {
            found_soa = 1;
            if (ttl < minttl) minttl = ttl;

            /* MNAME */
            if (!(p = skip_name(p, header, qlen, 0))) return 0;
            /* RNAME */
            if (!(p = skip_name(p, header, qlen, 20))) return 0;
            p += 16; /* SERIAL REFRESH RETRY EXPIRE */

            GETLONG(ttl, p); /* minTTL */
            if (ttl < minttl) minttl = ttl;
        } else if (!ADD_RDLEN(header, p, qlen, rdlen))
            return 0; /* bad packet */
    }

    /* rewrite addresses in additioal section too */
    if (!do_doctor(p, ntohs(header->arcount), header, qlen)) return 0;

    if (!found_soa) minttl = daemon->neg_ttl;

    return minttl;
}

/* Note that the following code can create CNAME chains that don't point to a real record,
   either because of lack of memory, or lack of SOA records.  These are treated by the cache code as
   expired and cleaned out that way.
   Return 1 if we reject an address because it look like parct of dns-rebinding attack. */
int extract_addresses(HEADER* header, size_t qlen, char* name, time_t now) {
    unsigned char *p, *p1, *endrr, *namep;
    int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
    unsigned long ttl = 0;
    struct all_addr addr;

    cache_start_insert();

    /* find_soa is needed for dns_doctor side-effects, so don't call it lazily if there are any. */
    if (daemon->doctors) {
        searched_soa = 1;
        ttl = find_soa(header, qlen);
    }

    /* go through the questions. */
    p = (unsigned char*) (header + 1);

    for (i = ntohs(header->qdcount); i != 0; i--) {
        int found = 0, cname_count = 5;
        struct crec* cpp = NULL;
        int flags = header->rcode == NXDOMAIN ? F_NXDOMAIN : 0;
        unsigned long cttl = ULONG_MAX, attl;

        namep = p;
        if (!extract_name(header, qlen, &p, name, 1, 4)) return 0; /* bad packet */

        GETSHORT(qtype, p);
        GETSHORT(qclass, p);

        if (qclass != C_IN) continue;

        /* PTRs: we chase CNAMEs here, since we have no way to
       represent them in the cache. */
        if (qtype == T_PTR) {
            int name_encoding = in_arpa_name_2_addr(name, &addr);

            if (!name_encoding) continue;

            if (!(flags & F_NXDOMAIN)) {
            cname_loop:
                if (!(p1 = skip_questions(header, qlen))) return 0;

                for (j = ntohs(header->ancount); j != 0; j--) {
                    unsigned char* tmp = namep;
                    /* the loop body overwrites the original name, so get it back here. */
                    if (!extract_name(header, qlen, &tmp, name, 1, 0) ||
                        !(res = extract_name(header, qlen, &p1, name, 0, 10)))
                        return 0; /* bad packet */

                    GETSHORT(aqtype, p1);
                    GETSHORT(aqclass, p1);
                    GETLONG(attl, p1);
                    GETSHORT(ardlen, p1);
                    endrr = p1 + ardlen;

                    /* TTL of record is minimum of CNAMES and PTR */
                    if (attl < cttl) cttl = attl;

                    if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR)) {
                        if (!extract_name(header, qlen, &p1, name, 1, 0)) return 0;

                        if (aqtype == T_CNAME) {
                            if (!cname_count--) return 0; /* looped CNAMES */
                            goto cname_loop;
                        }

                        cache_insert(name, &addr, now, cttl, name_encoding | F_REVERSE);
                        found = 1;
                    }

                    p1 = endrr;
                    if (!CHECK_LEN(header, p1, qlen, 0)) return 0; /* bad packet */
                }
            }

            if (!found && !(daemon->options & OPT_NO_NEG)) {
                if (!searched_soa) {
                    searched_soa = 1;
                    ttl = find_soa(header, qlen);
                }
                if (ttl)
                    cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags);
            }
        } else {
            /* everything other than PTR */
            struct crec* newc;
            int addrlen;

            if (qtype == T_A) {
                addrlen = INADDRSZ;
                flags |= F_IPV4;
            }
#ifdef HAVE_IPV6
            else if (qtype == T_AAAA) {
                addrlen = IN6ADDRSZ;
                flags |= F_IPV6;
            }
#endif
            else
                continue;

            if (!(flags & F_NXDOMAIN)) {
            cname_loop1:
                if (!(p1 = skip_questions(header, qlen))) return 0;

                for (j = ntohs(header->ancount); j != 0; j--) {
                    if (!(res = extract_name(header, qlen, &p1, name, 0, 10)))
                        return 0; /* bad packet */

                    GETSHORT(aqtype, p1);
                    GETSHORT(aqclass, p1);
                    GETLONG(attl, p1);
                    GETSHORT(ardlen, p1);
                    endrr = p1 + ardlen;

                    if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype)) {
                        if (aqtype == T_CNAME) {
                            if (!cname_count--) return 0; /* looped CNAMES */
                            newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD);
                            if (newc && cpp) {
                                cpp->addr.cname.cache = newc;
                                cpp->addr.cname.uid = newc->uid;
                            }

                            cpp = newc;
                            if (attl < cttl) cttl = attl;

                            if (!extract_name(header, qlen, &p1, name, 1, 0)) return 0;
                            goto cname_loop1;
                        } else {
                            found = 1;

                            /* copy address into aligned storage */
                            if (!CHECK_LEN(header, p1, qlen, addrlen)) return 0; /* bad packet */
                            memcpy(&addr, p1, addrlen);

                            /* check for returned address in private space */
                            if ((daemon->options & OPT_NO_REBIND) && (flags & F_IPV4) &&
                                private_net(addr.addr.addr4))
                                return 1;

                            newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
                            if (newc && cpp) {
                                cpp->addr.cname.cache = newc;
                                cpp->addr.cname.uid = newc->uid;
                            }
                            cpp = NULL;
                        }
                    }

                    p1 = endrr;
                    if (!CHECK_LEN(header, p1, qlen, 0)) return 0; /* bad packet */
                }
            }

            if (!found && !(daemon->options & OPT_NO_NEG)) {
                if (!searched_soa) {
                    searched_soa = 1;
                    ttl = find_soa(header, qlen);
                }
                /* If there's no SOA to get the TTL from, but there is a CNAME
               pointing at this, inherit its TTL */
                if (ttl || cpp) {
                    newc =
                        cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags);
                    if (newc && cpp) {
                        cpp->addr.cname.cache = newc;
                        cpp->addr.cname.uid = newc->uid;
                    }
                }
            }
        }
    }

    /* Don't put stuff from a truncated packet into the cache, but do everything else */
    if (!header->tc) cache_end_insert();

    return 0;
}

/* If the packet holds exactly one query
   return F_IPV4 or F_IPV6  and leave the name from the query in name.
   Abuse F_BIGNAME to indicate an NS query - yuck. */

unsigned short extract_request(HEADER* header, size_t qlen, char* name, unsigned short* typep) {
    unsigned char* p = (unsigned char*) (header + 1);
    int qtype, qclass;

    if (typep) *typep = 0;

    if (ntohs(header->qdcount) != 1 || header->opcode != QUERY)
        return 0; /* must be exactly one query. */

    if (!extract_name(header, qlen, &p, name, 1, 4)) return 0; /* bad packet */

    GETSHORT(qtype, p);
    GETSHORT(qclass, p);

    if (typep) *typep = qtype;

    if (qclass == C_IN) {
        if (qtype == T_A) return F_IPV4;
        if (qtype == T_AAAA) return F_IPV6;
        if (qtype == T_ANY) return F_IPV4 | F_IPV6;
        if (qtype == T_NS || qtype == T_SOA) return F_QUERY | F_BIGNAME;
    }

    return F_QUERY;
}

size_t setup_reply(HEADER* header, size_t qlen, struct all_addr* addrp, unsigned short flags,
                   unsigned long ttl) {
    unsigned char* p;

    if (!(p = skip_questions(header, qlen))) return 0;

    header->qr = 1; /* response */
    header->aa = 0; /* authoritive */
    header->ra = 1; /* recursion if available */
    header->tc = 0; /* not truncated */
    header->nscount = htons(0);
    header->arcount = htons(0);
    header->ancount = htons(0); /* no answers unless changed below */
    if (flags == F_NEG)
        header->rcode = SERVFAIL; /* couldn't get memory */
    else if (flags == F_NOERR)
        header->rcode = NOERROR; /* empty domain */
    else if (flags == F_NXDOMAIN)
        header->rcode = NXDOMAIN;
    else if (flags == F_IPV4) { /* we know the address */
        header->rcode = NOERROR;
        header->ancount = htons(1);
        header->aa = 1;
        add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_A, C_IN, "4",
                            addrp);
    }
#ifdef HAVE_IPV6
    else if (flags == F_IPV6) {
        header->rcode = NOERROR;
        header->ancount = htons(1);
        header->aa = 1;
        add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_AAAA, C_IN, "6",
                            addrp);
    }
#endif
    else /* nowhere to forward to */
        header->rcode = REFUSED;

    return p - (unsigned char*) header;
}

/* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
int check_for_local_domain(char* name, time_t now) {
    struct crec* crecp;
    struct mx_srv_record* mx;
    struct txt_record* txt;
    struct interface_name* intr;
    struct ptr_record* ptr;

    if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)) &&
        (crecp->flags & (F_HOSTS | F_DHCP)))
        return 1;

    for (mx = daemon->mxnames; mx; mx = mx->next)
        if (hostname_isequal(name, mx->name)) return 1;

    for (txt = daemon->txt; txt; txt = txt->next)
        if (hostname_isequal(name, txt->name)) return 1;

    for (intr = daemon->int_names; intr; intr = intr->next)
        if (hostname_isequal(name, intr->name)) return 1;

    for (ptr = daemon->ptr; ptr; ptr = ptr->next)
        if (hostname_isequal(name, ptr->name)) return 1;

    return 0;
}

/* Is the packet a reply with the answer address equal to addr?
   If so mung is into an NXDOMAIN reply and also put that information
   in the cache. */
int check_for_bogus_wildcard(HEADER* header, size_t qlen, char* name, struct bogus_addr* baddr,
                             time_t now) {
    unsigned char* p;
    int i, qtype, qclass, rdlen;
    unsigned long ttl;
    struct bogus_addr* baddrp;

    /* skip over questions */
    if (!(p = skip_questions(header, qlen))) return 0; /* bad packet */

    for (i = ntohs(header->ancount); i != 0; i--) {
        if (!extract_name(header, qlen, &p, name, 1, 10)) return 0; /* bad packet */

        GETSHORT(qtype, p);
        GETSHORT(qclass, p);
        GETLONG(ttl, p);
        GETSHORT(rdlen, p);

        if (qclass == C_IN && qtype == T_A) {
            if (!CHECK_LEN(header, p, qlen, INADDRSZ)) return 0;

            for (baddrp = baddr; baddrp; baddrp = baddrp->next)
                if (memcmp(&baddrp->addr, p, INADDRSZ) == 0) {
                    /* Found a bogus address. Insert that info here, since there no SOA record
                       to get the ttl from in the normal processing */
                    cache_start_insert();
                    cache_insert(name, NULL, now, ttl,
                                 F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN | F_CONFIG);
                    cache_end_insert();

                    return 1;
                }
        }

        if (!ADD_RDLEN(header, p, qlen, rdlen)) return 0;
    }

    return 0;
}

static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigned int nameoffset,
                               unsigned char** pp, unsigned long ttl, unsigned int* offset,
                               unsigned short type, unsigned short class, char* format, ...) {
    va_list ap;
    unsigned char *sav, *p = *pp;
    int j;
    unsigned short usval;
    long lval;
    char* sval;
#define CHECK_LIMIT(size) \
    if (limit && p + (size) > (unsigned char*)limit) { \
        va_end(ap); \
        goto truncated; \
    }

    if (truncp && *truncp) return 0;

    va_start(ap, format); /* make ap point to 1st unamed argument */

   /* nameoffset (1 or 2) + type (2) + class (2) + ttl (4) + 0 (2) */
    CHECK_LIMIT(12);

    PUTSHORT(nameoffset | 0xc000, p);
    PUTSHORT(type, p);
    PUTSHORT(class, p);
    PUTLONG(ttl, p); /* TTL */

    sav = p;        /* Save pointer to RDLength field */
    PUTSHORT(0, p); /* Placeholder RDLength */

    for (; *format; format++) switch (*format) {
#ifdef HAVE_IPV6
            case '6':
                CHECK_LIMIT(IN6ADDRSZ);
                sval = va_arg(ap, char*);
                memcpy(p, sval, IN6ADDRSZ);
                p += IN6ADDRSZ;
                break;
#endif

            case '4':
                CHECK_LIMIT(INADDRSZ);
                sval = va_arg(ap, char*);
                memcpy(p, sval, INADDRSZ);
                p += INADDRSZ;
                break;

            case 's':
                CHECK_LIMIT(2);
                usval = va_arg(ap, int);
                PUTSHORT(usval, p);
                break;

            case 'l':
                CHECK_LIMIT(4);
                lval = va_arg(ap, long);
                PUTLONG(lval, p);
                break;

            case 'd':
                /* get domain-name answer arg and store it in RDATA field */
                if (offset) *offset = p - (unsigned char*) header;
                p = do_rfc1035_name(p, va_arg(ap, char*), limit);
                if (!p) {
                    va_end(ap);
                    goto truncated;
                }
                CHECK_LIMIT(1);
                *p++ = 0;
                break;

            case 't':
                usval = va_arg(ap, int);
                CHECK_LIMIT(usval);
                sval = va_arg(ap, char*);
                memcpy(p, sval, usval);
                p += usval;
                break;

            case 'z':
                sval = va_arg(ap, char*);
                usval = sval ? strlen(sval) : 0;
                if (usval > 255) usval = 255;
                CHECK_LIMIT(usval + 1);
                *p++ = (unsigned char) usval;
                memcpy(p, sval, usval);
                p += usval;
                break;
        }

#undef CHECK_LIMIT
    va_end(ap); /* clean up variable argument pointer */

    j = p - sav - 2;
    /* this has already been checked against limit before */
    PUTSHORT(j, sav); /* Now, store real RDLength */

    /* check for overflow of buffer */
    if (limit && ((unsigned char*) limit - p) < 0) {
truncated:
        if (truncp) *truncp = 1;
        return 0;
    }

    *pp = p;
    return 1;
}

static unsigned long crec_ttl(struct crec* crecp, time_t now) {
    /* Return 0 ttl for DHCP entries, which might change
       before the lease expires. */

    if (crecp->flags & (F_IMMORTAL | F_DHCP)) return daemon->local_ttl;

    return crecp->ttd - now;
}

/* return zero if we can't answer from cache, or packet size if we can */
size_t answer_request(HEADER* header, char* limit, size_t qlen, struct in_addr local_addr,
                      struct in_addr local_netmask, time_t now) {
    char* name = daemon->namebuff;
    unsigned char *p, *ansp, *pheader;
    int qtype, qclass;
    struct all_addr addr;
    unsigned int nameoffset;
    unsigned short flag;
    int q, ans, anscount = 0, addncount = 0;
    int dryrun = 0, sec_reqd = 0;
    int is_sign;
    struct crec* crecp;
    int nxdomain = 0, auth = 1, trunc = 0;
    struct mx_srv_record* rec;

    // Make sure we do not underflow here too.
    if (qlen > (size_t)(limit - ((char*) header))) return 0;

    /* If there is an RFC2671 pseudoheader then it will be overwritten by
       partial replies, so we have to do a dry run to see if we can answer
       the query. We check to see if the do bit is set, if so we always
       forward rather than answering from the cache, which doesn't include
       security information. */

    if (find_pseudoheader(header, qlen, NULL, &pheader, &is_sign)) {
        unsigned short udpsz, ext_rcode, flags;
        unsigned char* psave = pheader;

        GETSHORT(udpsz, pheader);
        GETSHORT(ext_rcode, pheader);
        GETSHORT(flags, pheader);

        sec_reqd = flags & 0x8000; /* do bit */

        /* If our client is advertising a larger UDP packet size
       than we allow, trim it so that we don't get an overlarge
       response from upstream */

        if (!is_sign && (udpsz > daemon->edns_pktsz)) PUTSHORT(daemon->edns_pktsz, psave);

        dryrun = 1;
    }

    if (ntohs(header->qdcount) == 0 || header->opcode != QUERY) return 0;

    for (rec = daemon->mxnames; rec; rec = rec->next) rec->offset = 0;

rerun:
    /* determine end of question section (we put answers there) */
    if (!(ansp = skip_questions(header, qlen))) return 0; /* bad packet */

    /* now process each question, answers go in RRs after the question */
    p = (unsigned char*) (header + 1);

    for (q = ntohs(header->qdcount); q != 0; q--) {
        /* save pointer to name for copying into answers */
        nameoffset = p - (unsigned char*) header;

        /* now extract name as .-concatenated string into name */
        if (!extract_name(header, qlen, &p, name, 1, 4)) return 0; /* bad packet */

        GETSHORT(qtype, p);
        GETSHORT(qclass, p);

        ans = 0; /* have we answered this question */

        if (qtype == T_TXT || qtype == T_ANY) {
            struct txt_record* t;
            for (t = daemon->txt; t; t = t->next) {
                if (t->class == qclass && hostname_isequal(name, t->name)) {
                    ans = 1;
                    if (!dryrun) {
                        log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<TXT>");
                        if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
                                                daemon->local_ttl, NULL, T_TXT, t->class, "t",
                                                t->len, t->txt))
                            anscount++;
                    }
                }
            }
        }

        if (qclass == C_IN) {
            if (qtype == T_PTR || qtype == T_ANY) {
                /* see if it's w.z.y.z.in-addr.arpa format */
                int is_arpa = in_arpa_name_2_addr(name, &addr);
                struct ptr_record* ptr;
                struct interface_name* intr = NULL;

                for (ptr = daemon->ptr; ptr; ptr = ptr->next)
                    if (hostname_isequal(name, ptr->name)) break;

                if (is_arpa == F_IPV4)
                    for (intr = daemon->int_names; intr; intr = intr->next) {
                        if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr)
                            break;
                        else
                            while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
                                intr = intr->next;
                    }

                if (intr) {
                    ans = 1;
                    if (!dryrun) {
                        log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
                        if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
                                                daemon->local_ttl, NULL, T_PTR, C_IN, "d",
                                                intr->name))
                            anscount++;
                    }
                } else if (ptr) {
                    ans = 1;
                    if (!dryrun) {
                        log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<PTR>");
                        for (ptr = daemon->ptr; ptr; ptr = ptr->next)
                            if (hostname_isequal(name, ptr->name) &&
                                add_resource_record(header, limit, &trunc, nameoffset, &ansp,
                                                    daemon->local_ttl, NULL, T_PTR, C_IN, "d",
                                                    ptr->ptr))
                                anscount++;
                    }
                } else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
                    do {
                        /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
                        if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP))) continue;

                        if (crecp->flags & F_NEG) {
                            ans = 1;
                            auth = 0;
                            if (crecp->flags & F_NXDOMAIN) nxdomain = 1;
                            if (!dryrun) log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
                        } else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd) {
                            ans = 1;
                            if (!(crecp->flags & (F_HOSTS | F_DHCP))) auth = 0;
                            if (!dryrun) {
                                log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
                                          record_source(crecp->uid));

                                if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
                                                        crec_ttl(crecp, now), NULL, T_PTR, C_IN,
                                                        "d", cache_get_name(crecp)))
                                    anscount++;
                            }
                        }
                    } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
                else if (is_arpa == F_IPV4 && (daemon->options & OPT_BOGUSPRIV) &&
                         private_net(addr.addr.addr4)) {
                    /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
                    ans = 1;
                    nxdomain = 1;
                    if (!dryrun)
                        log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN, name, &addr,
                                  NULL);
                }
            }

            for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0) {
                unsigned short type = T_A;

                if (flag == F_IPV6)
#ifdef HAVE_IPV6
                    type = T_AAAA;
#else
                    break;
#endif

                if (qtype != type && qtype != T_ANY) continue;

                /* Check for "A for A"  queries */
                if (qtype == T_A && (addr.addr.addr4.s_addr = inet_addr(name)) != (in_addr_t) -1) {
                    ans = 1;
                    if (!dryrun) {
                        log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
                        if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
                                                daemon->local_ttl, NULL, type, C_IN, "4", &addr))
                            anscount++;
                    }
                    continue;
                }

                /* interface name stuff */
                if (qtype == T_A) {
                    struct interface_name* intr;

                    for (intr = daemon->int_names; intr; intr = intr->next)
                        if (hostname_isequal(name, intr->name)) break;

                    if (intr) {
                        ans = 1;
                        if (!dryrun) {
                            if ((addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr == (in_addr_t) -1)
                                log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, NULL);
                            else {
                                log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
                                if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
                                                        daemon->local_ttl, NULL, type, C_IN, "4",
                                                        &addr))
                                    anscount++;
                            }
                        }
                        continue;
                    }
                }

            cname_restart:
                if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME))) {
                    int localise = 0;

                    /* See if a putative address is on the network from which we recieved
                       the query, is so we'll filter other answers. */
                    if (local_addr.s_addr != 0 && (daemon->options & OPT_LOCALISE) &&
                        flag == F_IPV4) {
                        struct crec* save = crecp;
                        do {
                            if ((crecp->flags & F_HOSTS) &&
                                is_same_net(*((struct in_addr*) &crecp->addr), local_addr,
                                            local_netmask)) {
                                localise = 1;
                                break;
                            }
                        } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
                        crecp = save;
                    }

                    do {
                        /* don't answer wildcard queries with data not from /etc/hosts
                       or DHCP leases */
                        if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP))) break;

                        if (crecp->flags & F_CNAME) {
                            if (!dryrun) {
                                log_query(crecp->flags, name, NULL, record_source(crecp->uid));
                                if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
                                                        crec_ttl(crecp, now), &nameoffset, T_CNAME,
                                                        C_IN, "d",
                                                        cache_get_name(crecp->addr.cname.cache)))
                                    anscount++;
                            }

                            strcpy(name, cache_get_name(crecp->addr.cname.cache));
                            goto cname_restart;
                        }

                        if (crecp->flags & F_NEG) {
                            ans = 1;
                            auth = 0;
                            if (crecp->flags & F_NXDOMAIN) nxdomain = 1;
                            if (!dryrun) log_query(crecp->flags, name, NULL, NULL);
                        } else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd) {
                            /* If we are returning local answers depending on network,
                               filter here. */
                            if (localise && (crecp->flags & F_HOSTS) &&
                                !is_same_net(*((struct in_addr*) &crecp->addr), local_addr,
                                             local_netmask))
                                continue;

                            if (!(crecp->flags & (F_HOSTS | F_DHCP))) auth = 0;

                            ans = 1;
                            if (!dryrun) {
                                log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
                                          record_source(crecp->uid));

                                if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
                                                        crec_ttl(crecp, now), NULL, type, C_IN,
                                                        type == T_A ? "4" : "6", &crecp->addr))
                                    anscount++;
                            }
                        }
                    } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
                }
            }

            if (qtype == T_MX || qtype == T_ANY) {
                int found = 0;
                for (rec = daemon->mxnames; rec; rec = rec->next)
                    if (!rec->issrv && hostname_isequal(name, rec->name)) {
                        ans = found = 1;
                        if (!dryrun) {
                            unsigned int offset;
                            log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL,
                                      "<MX>");
                            if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
                                                    daemon->local_ttl, &offset, T_MX, C_IN, "sd",
                                                    rec->weight, rec->target)) {
                                anscount++;
                                if (rec->target) rec->offset = offset;
                            }
                        }
                    }

                if (!found && (daemon->options & (OPT_SELFMX | OPT_LOCALMX)) &&
                    cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP)) {
                    ans = 1;
                    if (!dryrun) {
                        log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>");
                        if (add_resource_record(
                                header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
                                T_MX, C_IN, "sd", 1,
                                (daemon->options & OPT_SELFMX) ? name : daemon->mxtarget))
                            anscount++;
                    }
                }
            }

            if (qtype == T_SRV || qtype == T_ANY) {
                int found = 0;

                for (rec = daemon->mxnames; rec; rec = rec->next)
                    if (rec->issrv && hostname_isequal(name, rec->name)) {
                        found = ans = 1;
                        if (!dryrun) {
                            unsigned int offset;
                            log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL,
                                      "<SRV>");
                            if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
                                                    daemon->local_ttl, &offset, T_SRV, C_IN, "sssd",
                                                    rec->priority, rec->weight, rec->srvport,
                                                    rec->target)) {
                                anscount++;
                                if (rec->target) rec->offset = offset;
                            }
                        }
                    }

                if (!found && (daemon->options & OPT_FILTER) &&
                    (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_')))) {
                    ans = 1;
                    if (!dryrun) log_query(F_CONFIG | F_NEG, name, NULL, NULL);
                }
            }

            if (qtype == T_NAPTR || qtype == T_ANY) {
                struct naptr* na;
                for (na = daemon->naptr; na; na = na->next)
                    if (hostname_isequal(name, na->name)) {
                        ans = 1;
                        if (!dryrun) {
                            log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL,
                                      "<NAPTR>");
                            if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
                                                    daemon->local_ttl, NULL, T_NAPTR, C_IN,
                                                    "sszzzd", na->order, na->pref, na->flags,
                                                    na->services, na->regexp, na->replace))
                                anscount++;
                        }
                    }
            }

            if (qtype == T_MAILB) ans = 1, nxdomain = 1;

            if (qtype == T_SOA && (daemon->options & OPT_FILTER)) {
                ans = 1;
                if (!dryrun) log_query(F_CONFIG | F_NEG, name, &addr, NULL);
            }
        }

        if (!ans) return 0; /* failed to answer a question */
    }

    if (dryrun) {
        dryrun = 0;
        goto rerun;
    }

    /* create an additional data section, for stuff in SRV and MX record replies. */
    for (rec = daemon->mxnames; rec; rec = rec->next)
        if (rec->offset != 0) {
            /* squash dupes */
            struct mx_srv_record* tmp;
            for (tmp = rec->next; tmp; tmp = tmp->next)
                if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target)) tmp->offset = 0;

            crecp = NULL;
            while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6))) {
#ifdef HAVE_IPV6
                int type = crecp->flags & F_IPV4 ? T_A : T_AAAA;
#else
                int type = T_A;
#endif
                if (crecp->flags & F_NEG) continue;

                if (add_resource_record(header, limit, NULL, rec->offset, &ansp,
                                        crec_ttl(crecp, now), NULL, type, C_IN,
                                        crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
                    addncount++;
            }
        }

    /* done all questions, set up header and return length of result */
    header->qr = 1;     /* response */
    header->aa = auth;  /* authoritive - only hosts and DHCP derived names. */
    header->ra = 1;     /* recursion if available */
    header->tc = trunc; /* truncation */
    if (anscount == 0 && nxdomain)
        header->rcode = NXDOMAIN;
    else
        header->rcode = NOERROR; /* no error */
    header->ancount = htons(anscount);
    header->nscount = htons(0);
    header->arcount = htons(addncount);
    return ansp - (unsigned char*) header;
}
