/* SPDX-License-Identifier: LGPL-2.1-or-later */

#if HAVE_GCRYPT
#include <gcrypt.h>
#endif

#include "alloc-util.h"
#include "dns-domain.h"
#include "memory-util.h"
#include "resolved-dns-packet.h"
#include "set.h"
#include "string-table.h"
#include "strv.h"
#include "unaligned.h"
#include "utf8.h"
#include "util.h"

#define EDNS0_OPT_DO (1<<15)

assert_cc(DNS_PACKET_SIZE_START > DNS_PACKET_HEADER_SIZE);

typedef struct DnsPacketRewinder {
        DnsPacket *packet;
        size_t saved_rindex;
} DnsPacketRewinder;

static void rewind_dns_packet(DnsPacketRewinder *rewinder) {
        if (rewinder->packet)
                dns_packet_rewind(rewinder->packet, rewinder->saved_rindex);
}

#define INIT_REWINDER(rewinder, p) do { rewinder.packet = p; rewinder.saved_rindex = p->rindex; } while (0)
#define CANCEL_REWINDER(rewinder) do { rewinder.packet = NULL; } while (0)

int dns_packet_new(
                DnsPacket **ret,
                DnsProtocol protocol,
                size_t min_alloc_dsize,
                size_t max_size) {

        DnsPacket *p;
        size_t a;

        assert(ret);
        assert(max_size >= DNS_PACKET_HEADER_SIZE);

        if (max_size > DNS_PACKET_SIZE_MAX)
                max_size = DNS_PACKET_SIZE_MAX;

        /* The caller may not check what is going to be truly allocated, so do not allow to
         * allocate a DNS packet bigger than DNS_PACKET_SIZE_MAX.
         */
        if (min_alloc_dsize > DNS_PACKET_SIZE_MAX)
                return log_error_errno(SYNTHETIC_ERRNO(EFBIG),
                                       "Requested packet data size too big: %zu",
                                       min_alloc_dsize);

        /* When dns_packet_new() is called with min_alloc_dsize == 0, allocate more than the
         * absolute minimum (which is the dns packet header size), to avoid
         * resizing immediately again after appending the first data to the packet.
         */
        if (min_alloc_dsize < DNS_PACKET_HEADER_SIZE)
                a = DNS_PACKET_SIZE_START;
        else
                a = min_alloc_dsize;

        /* round up to next page size */
        a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));

        /* make sure we never allocate more than useful */
        if (a > max_size)
                a = max_size;

        p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
        if (!p)
                return -ENOMEM;

        *p = (DnsPacket) {
                .n_ref = 1,
                .protocol = protocol,
                .size = DNS_PACKET_HEADER_SIZE,
                .rindex = DNS_PACKET_HEADER_SIZE,
                .allocated = a,
                .max_size = max_size,
                .opt_start = SIZE_MAX,
                .opt_size = SIZE_MAX,
        };

        *ret = p;

        return 0;
}

void dns_packet_set_flags(DnsPacket *p, bool dnssec_checking_disabled, bool truncated) {

        DnsPacketHeader *h;

        assert(p);

        h = DNS_PACKET_HEADER(p);

        switch(p->protocol) {
        case DNS_PROTOCOL_LLMNR:
                assert(!truncated);

                h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
                                                         0 /* opcode */,
                                                         0 /* c */,
                                                         0 /* tc */,
                                                         0 /* t */,
                                                         0 /* ra */,
                                                         0 /* ad */,
                                                         0 /* cd */,
                                                         0 /* rcode */));
                break;

        case DNS_PROTOCOL_MDNS:
                h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0         /* qr */,
                                                         0         /* opcode */,
                                                         0         /* aa */,
                                                         truncated /* tc */,
                                                         0         /* rd (ask for recursion) */,
                                                         0         /* ra */,
                                                         0         /* ad */,
                                                         0         /* cd */,
                                                         0         /* rcode */));
                break;

        default:
                assert(!truncated);

                h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
                                                         0 /* opcode */,
                                                         0 /* aa */,
                                                         0 /* tc */,
                                                         1 /* rd (ask for recursion) */,
                                                         0 /* ra */,
                                                         0 /* ad */,
                                                         dnssec_checking_disabled /* cd */,
                                                         0 /* rcode */));
        }
}

int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t min_alloc_dsize, bool dnssec_checking_disabled) {
        DnsPacket *p;
        int r;

        assert(ret);

        r = dns_packet_new(&p, protocol, min_alloc_dsize, DNS_PACKET_SIZE_MAX);
        if (r < 0)
                return r;

        /* Always set the TC bit to 0 initially.
         * If there are multiple packets later, we'll update the bit shortly before sending.
         */
        dns_packet_set_flags(p, dnssec_checking_disabled, false);

        *ret = p;
        return 0;
}

int dns_packet_dup(DnsPacket **ret, DnsPacket *p) {
        DnsPacket *c;
        int r;

        assert(ret);
        assert(p);

        r = dns_packet_validate(p);
        if (r < 0)
                return r;

        c = malloc(ALIGN(sizeof(DnsPacket)) + p->size);
        if (!c)
                return -ENOMEM;

        *c = (DnsPacket) {
                .n_ref = 1,
                .protocol = p->protocol,
                .size = p->size,
                .rindex = DNS_PACKET_HEADER_SIZE,
                .allocated = p->size,
                .max_size = p->max_size,
                .opt_start = SIZE_MAX,
                .opt_size = SIZE_MAX,
        };

        memcpy(DNS_PACKET_DATA(c), DNS_PACKET_DATA(p), p->size);

        *ret = c;
        return 0;
}

DnsPacket *dns_packet_ref(DnsPacket *p) {

        if (!p)
                return NULL;

        assert(!p->on_stack);

        assert(p->n_ref > 0);
        p->n_ref++;
        return p;
}

static void dns_packet_free(DnsPacket *p) {
        char *s;

        assert(p);

        dns_question_unref(p->question);
        dns_answer_unref(p->answer);
        dns_resource_record_unref(p->opt);

        while ((s = hashmap_steal_first_key(p->names)))
                free(s);
        hashmap_free(p->names);

        free(p->_data);

        if (!p->on_stack)
                free(p);
}

DnsPacket *dns_packet_unref(DnsPacket *p) {
        if (!p)
                return NULL;

        assert(p->n_ref > 0);

        dns_packet_unref(p->more);

        if (p->n_ref == 1)
                dns_packet_free(p);
        else
                p->n_ref--;

        return NULL;
}

int dns_packet_validate(DnsPacket *p) {
        assert(p);

        if (p->size < DNS_PACKET_HEADER_SIZE)
                return -EBADMSG;

        if (p->size > DNS_PACKET_SIZE_MAX)
                return -EBADMSG;

        return 1;
}

int dns_packet_validate_reply(DnsPacket *p) {
        int r;

        assert(p);

        r = dns_packet_validate(p);
        if (r < 0)
                return r;

        if (DNS_PACKET_QR(p) != 1)
                return 0;

        if (DNS_PACKET_OPCODE(p) != 0)
                return -EBADMSG;

        switch (p->protocol) {

        case DNS_PROTOCOL_LLMNR:
                /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
                if (DNS_PACKET_QDCOUNT(p) != 1)
                        return -EBADMSG;

                break;

        case DNS_PROTOCOL_MDNS:
                /* RFC 6762, Section 18 */
                if (DNS_PACKET_RCODE(p) != 0)
                        return -EBADMSG;

                break;

        default:
                break;
        }

        return 1;
}

int dns_packet_validate_query(DnsPacket *p) {
        int r;

        assert(p);

        r = dns_packet_validate(p);
        if (r < 0)
                return r;

        if (DNS_PACKET_QR(p) != 0)
                return 0;

        if (DNS_PACKET_OPCODE(p) != 0)
                return -EBADMSG;

        if (DNS_PACKET_TC(p))
                return -EBADMSG;

        switch (p->protocol) {

        case DNS_PROTOCOL_LLMNR:
        case DNS_PROTOCOL_DNS:
                /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
                if (DNS_PACKET_QDCOUNT(p) != 1)
                        return -EBADMSG;

                /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
                if (DNS_PACKET_ANCOUNT(p) > 0)
                        return -EBADMSG;

                /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
                if (DNS_PACKET_NSCOUNT(p) > 0)
                        return -EBADMSG;

                break;

        case DNS_PROTOCOL_MDNS:
                /* RFC 6762, Section 18 specifies that messages with non-zero RCODE
                 * must be silently ignored, and that we must ignore the values of
                 * AA, RD, RA, AD, and CD bits. */
                if (DNS_PACKET_RCODE(p) != 0)
                        return -EBADMSG;

                break;

        default:
                break;
        }

        return 1;
}

static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
        assert(p);

        if (p->size + add > p->allocated) {
                size_t a, ms;

                a = PAGE_ALIGN((p->size + add) * 2);

                ms = dns_packet_size_max(p);
                if (a > ms)
                        a = ms;

                if (p->size + add > a)
                        return -EMSGSIZE;

                if (p->_data) {
                        void *d;

                        d = realloc(p->_data, a);
                        if (!d)
                                return -ENOMEM;

                        p->_data = d;
                } else {
                        p->_data = malloc(a);
                        if (!p->_data)
                                return -ENOMEM;

                        memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
                        memzero((uint8_t*) p->_data + p->size, a - p->size);
                }

                p->allocated = a;
        }

        if (start)
                *start = p->size;

        if (ret)
                *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;

        p->size += add;
        return 0;
}

void dns_packet_truncate(DnsPacket *p, size_t sz) {
        char *s;
        void *n;

        assert(p);

        if (p->size <= sz)
                return;

        HASHMAP_FOREACH_KEY(n, s, p->names) {

                if (PTR_TO_SIZE(n) < sz)
                        continue;

                hashmap_remove(p->names, s);
                free(s);
        }

        p->size = sz;
}

int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
        void *q;
        int r;

        assert(p);

        r = dns_packet_extend(p, l, &q, start);
        if (r < 0)
                return r;

        memcpy_safe(q, d, l);
        return 0;
}

int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
        void *d;
        int r;

        assert(p);

        r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
        if (r < 0)
                return r;

        ((uint8_t*) d)[0] = v;

        return 0;
}

int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
        void *d;
        int r;

        assert(p);

        r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
        if (r < 0)
                return r;

        unaligned_write_be16(d, v);

        return 0;
}

int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start) {
        void *d;
        int r;

        assert(p);

        r = dns_packet_extend(p, sizeof(uint32_t), &d, start);
        if (r < 0)
                return r;

        unaligned_write_be32(d, v);

        return 0;
}

int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
        assert(p);
        assert(s);

        return dns_packet_append_raw_string(p, s, strlen(s), start);
}

int dns_packet_append_raw_string(DnsPacket *p, const void *s, size_t size, size_t *start) {
        void *d;
        int r;

        assert(p);
        assert(s || size == 0);

        if (size > 255)
                return -E2BIG;

        r = dns_packet_extend(p, 1 + size, &d, start);
        if (r < 0)
                return r;

        ((uint8_t*) d)[0] = (uint8_t) size;

        memcpy_safe(((uint8_t*) d) + 1, s, size);

        return 0;
}

int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, bool canonical_candidate, size_t *start) {
        uint8_t *w;
        int r;

        /* Append a label to a packet. Optionally, does this in DNSSEC
         * canonical form, if this label is marked as a candidate for
         * it, and the canonical form logic is enabled for the
         * packet */

        assert(p);
        assert(d);

        if (l > DNS_LABEL_MAX)
                return -E2BIG;

        r = dns_packet_extend(p, 1 + l, (void**) &w, start);
        if (r < 0)
                return r;

        *(w++) = (uint8_t) l;

        if (p->canonical_form && canonical_candidate) {
                size_t i;

                /* Generate in canonical form, as defined by DNSSEC
                 * RFC 4034, Section 6.2, i.e. all lower-case. */

                for (i = 0; i < l; i++)
                        w[i] = (uint8_t) ascii_tolower(d[i]);
        } else
                /* Otherwise, just copy the string unaltered. This is
                 * essential for DNS-SD, where the casing of labels
                 * matters and needs to be retained. */
                memcpy(w, d, l);

        return 0;
}

int dns_packet_append_name(
                DnsPacket *p,
                const char *name,
                bool allow_compression,
                bool canonical_candidate,
                size_t *start) {

        size_t saved_size;
        int r;

        assert(p);
        assert(name);

        if (p->refuse_compression)
                allow_compression = false;

        saved_size = p->size;

        while (!dns_name_is_root(name)) {
                const char *z = name;
                char label[DNS_LABEL_MAX];
                size_t n = 0;

                if (allow_compression)
                        n = PTR_TO_SIZE(hashmap_get(p->names, name));
                if (n > 0) {
                        assert(n < p->size);

                        if (n < 0x4000) {
                                r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
                                if (r < 0)
                                        goto fail;

                                goto done;
                        }
                }

                r = dns_label_unescape(&name, label, sizeof label, 0);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_label(p, label, r, canonical_candidate, &n);
                if (r < 0)
                        goto fail;

                if (allow_compression) {
                        _cleanup_free_ char *s = NULL;

                        s = strdup(z);
                        if (!s) {
                                r = -ENOMEM;
                                goto fail;
                        }

                        r = hashmap_ensure_put(&p->names, &dns_name_hash_ops, s, SIZE_TO_PTR(n));
                        if (r < 0)
                                goto fail;

                        TAKE_PTR(s);
                }
        }

        r = dns_packet_append_uint8(p, 0, NULL);
        if (r < 0)
                return r;

done:
        if (start)
                *start = saved_size;

        return 0;

fail:
        dns_packet_truncate(p, saved_size);
        return r;
}

int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, const DnsAnswerFlags flags, size_t *start) {
        size_t saved_size;
        uint16_t class;
        int r;

        assert(p);
        assert(k);

        saved_size = p->size;

        r = dns_packet_append_name(p, dns_resource_key_name(k), true, true, NULL);
        if (r < 0)
                goto fail;

        r = dns_packet_append_uint16(p, k->type, NULL);
        if (r < 0)
                goto fail;

        class = flags & DNS_ANSWER_CACHE_FLUSH ? k->class | MDNS_RR_CACHE_FLUSH_OR_QU : k->class;
        r = dns_packet_append_uint16(p, class, NULL);
        if (r < 0)
                goto fail;

        if (start)
                *start = saved_size;

        return 0;

fail:
        dns_packet_truncate(p, saved_size);
        return r;
}

static int dns_packet_append_type_window(DnsPacket *p, uint8_t window, uint8_t length, const uint8_t *types, size_t *start) {
        size_t saved_size;
        int r;

        assert(p);
        assert(types);
        assert(length > 0);

        saved_size = p->size;

        r = dns_packet_append_uint8(p, window, NULL);
        if (r < 0)
                goto fail;

        r = dns_packet_append_uint8(p, length, NULL);
        if (r < 0)
                goto fail;

        r = dns_packet_append_blob(p, types, length, NULL);
        if (r < 0)
                goto fail;

        if (start)
                *start = saved_size;

        return 0;
fail:
        dns_packet_truncate(p, saved_size);
        return r;
}

static int dns_packet_append_types(DnsPacket *p, Bitmap *types, size_t *start) {
        uint8_t window = 0;
        uint8_t entry = 0;
        uint8_t bitmaps[32] = {};
        unsigned n;
        size_t saved_size;
        int r;

        assert(p);

        saved_size = p->size;

        BITMAP_FOREACH(n, types) {
                assert(n <= 0xffff);

                if ((n >> 8) != window && bitmaps[entry / 8] != 0) {
                        r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
                        if (r < 0)
                                goto fail;

                        zero(bitmaps);
                }

                window = n >> 8;
                entry = n & 255;

                bitmaps[entry / 8] |= 1 << (7 - (entry % 8));
        }

        if (bitmaps[entry / 8] != 0) {
                r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
                if (r < 0)
                        goto fail;
        }

        if (start)
                *start = saved_size;

        return 0;
fail:
        dns_packet_truncate(p, saved_size);
        return r;
}

/* Append the OPT pseudo-RR described in RFC6891 */
int dns_packet_append_opt(
                DnsPacket *p,
                uint16_t max_udp_size,
                bool edns0_do,
                bool include_rfc6975,
                const char *nsid,
                int rcode,
                size_t *ret_start) {

        size_t saved_size;
        int r;

        assert(p);
        /* we must never advertise supported packet size smaller than the legacy max */
        assert(max_udp_size >= DNS_PACKET_UNICAST_SIZE_MAX);
        assert(rcode >= 0);
        assert(rcode <= _DNS_RCODE_MAX);

        if (p->opt_start != SIZE_MAX)
                return -EBUSY;

        assert(p->opt_size == SIZE_MAX);

        saved_size = p->size;

        /* empty name */
        r = dns_packet_append_uint8(p, 0, NULL);
        if (r < 0)
                return r;

        /* type */
        r = dns_packet_append_uint16(p, DNS_TYPE_OPT, NULL);
        if (r < 0)
                goto fail;

        /* class: maximum udp packet that can be received */
        r = dns_packet_append_uint16(p, max_udp_size, NULL);
        if (r < 0)
                goto fail;

        /* extended RCODE and VERSION */
        r = dns_packet_append_uint16(p, ((uint16_t) rcode & 0x0FF0) << 4, NULL);
        if (r < 0)
                goto fail;

        /* flags: DNSSEC OK (DO), see RFC3225 */
        r = dns_packet_append_uint16(p, edns0_do ? EDNS0_OPT_DO : 0, NULL);
        if (r < 0)
                goto fail;

        if (edns0_do && include_rfc6975) {
                /* If DO is on and this is requested, also append RFC6975 Algorithm data. This is supposed to
                 * be done on queries, not on replies, hencer callers should turn this off when finishing off
                 * replies. */

                static const uint8_t rfc6975[] = {

                        0, 5, /* OPTION_CODE: DAU */
#if HAVE_GCRYPT && GCRYPT_VERSION_NUMBER >= 0x010600
                        0, 7, /* LIST_LENGTH */
#else
                        0, 6, /* LIST_LENGTH */
#endif
                        DNSSEC_ALGORITHM_RSASHA1,
                        DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1,
                        DNSSEC_ALGORITHM_RSASHA256,
                        DNSSEC_ALGORITHM_RSASHA512,
                        DNSSEC_ALGORITHM_ECDSAP256SHA256,
                        DNSSEC_ALGORITHM_ECDSAP384SHA384,
#if HAVE_GCRYPT && GCRYPT_VERSION_NUMBER >= 0x010600
                        DNSSEC_ALGORITHM_ED25519,
#endif

                        0, 6, /* OPTION_CODE: DHU */
                        0, 3, /* LIST_LENGTH */
                        DNSSEC_DIGEST_SHA1,
                        DNSSEC_DIGEST_SHA256,
                        DNSSEC_DIGEST_SHA384,

                        0, 7, /* OPTION_CODE: N3U */
                        0, 1, /* LIST_LENGTH */
                        NSEC3_ALGORITHM_SHA1,
                };

                r = dns_packet_append_uint16(p, sizeof(rfc6975), NULL); /* RDLENGTH */
                if (r < 0)
                        goto fail;

                r = dns_packet_append_blob(p, rfc6975, sizeof(rfc6975), NULL); /* the payload, as defined above */

        } else if (nsid) {

                if (strlen(nsid) > UINT16_MAX - 4) {
                        r = -E2BIG;
                        goto fail;
                }

                r = dns_packet_append_uint16(p, 4 + strlen(nsid), NULL); /* RDLENGTH */
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint16(p, 3, NULL); /* OPTION-CODE: NSID */
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint16(p, strlen(nsid), NULL); /* OPTION-LENGTH */
                if (r < 0)
                        goto fail;

                r = dns_packet_append_blob(p, nsid, strlen(nsid), NULL);
        } else
                r = dns_packet_append_uint16(p, 0, NULL);
        if (r < 0)
                goto fail;

        DNS_PACKET_HEADER(p)->arcount = htobe16(DNS_PACKET_ARCOUNT(p) + 1);

        p->opt_start = saved_size;
        p->opt_size = p->size - saved_size;

        if (ret_start)
                *ret_start = saved_size;

        return 0;

fail:
        dns_packet_truncate(p, saved_size);
        return r;
}

int dns_packet_truncate_opt(DnsPacket *p) {
        assert(p);

        if (p->opt_start == SIZE_MAX) {
                assert(p->opt_size == SIZE_MAX);
                return 0;
        }

        assert(p->opt_size != SIZE_MAX);
        assert(DNS_PACKET_ARCOUNT(p) > 0);

        if (p->opt_start + p->opt_size != p->size)
                return -EBUSY;

        dns_packet_truncate(p, p->opt_start);
        DNS_PACKET_HEADER(p)->arcount = htobe16(DNS_PACKET_ARCOUNT(p) - 1);
        p->opt_start = p->opt_size = SIZE_MAX;

        return 1;
}

int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAnswerFlags flags, size_t *start, size_t *rdata_start) {

        size_t saved_size, rdlength_offset, end, rdlength, rds;
        uint32_t ttl;
        int r;

        assert(p);
        assert(rr);

        saved_size = p->size;

        r = dns_packet_append_key(p, rr->key, flags, NULL);
        if (r < 0)
                goto fail;

        ttl = flags & DNS_ANSWER_GOODBYE ? 0 : rr->ttl;
        r = dns_packet_append_uint32(p, ttl, NULL);
        if (r < 0)
                goto fail;

        /* Initially we write 0 here */
        r = dns_packet_append_uint16(p, 0, &rdlength_offset);
        if (r < 0)
                goto fail;

        rds = p->size - saved_size;

        switch (rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) {

        case DNS_TYPE_SRV:
                r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint16(p, rr->srv.port, NULL);
                if (r < 0)
                        goto fail;

                /* RFC 2782 states "Unless and until permitted by future standards
                 * action, name compression is not to be used for this field." */
                r = dns_packet_append_name(p, rr->srv.name, false, true, NULL);
                break;

        case DNS_TYPE_PTR:
        case DNS_TYPE_NS:
        case DNS_TYPE_CNAME:
        case DNS_TYPE_DNAME:
                r = dns_packet_append_name(p, rr->ptr.name, true, true, NULL);
                break;

        case DNS_TYPE_HINFO:
                r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_string(p, rr->hinfo.os, NULL);
                break;

        case DNS_TYPE_SPF: /* exactly the same as TXT */
        case DNS_TYPE_TXT:

                if (!rr->txt.items) {
                        /* RFC 6763, section 6.1 suggests to generate
                         * single empty string for an empty array. */

                        r = dns_packet_append_raw_string(p, NULL, 0, NULL);
                        if (r < 0)
                                goto fail;
                } else {
                        DnsTxtItem *i;

                        LIST_FOREACH(items, i, rr->txt.items) {
                                r = dns_packet_append_raw_string(p, i->data, i->length, NULL);
                                if (r < 0)
                                        goto fail;
                        }
                }

                r = 0;
                break;

        case DNS_TYPE_A:
                r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
                break;

        case DNS_TYPE_AAAA:
                r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
                break;

        case DNS_TYPE_SOA:
                r = dns_packet_append_name(p, rr->soa.mname, true, true, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_name(p, rr->soa.rname, true, true, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
                break;

        case DNS_TYPE_MX:
                r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_name(p, rr->mx.exchange, true, true, NULL);
                break;

        case DNS_TYPE_LOC:
                r = dns_packet_append_uint8(p, rr->loc.version, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->loc.size, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
                break;

        case DNS_TYPE_DS:
                r = dns_packet_append_uint16(p, rr->ds.key_tag, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->ds.algorithm, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->ds.digest_type, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_blob(p, rr->ds.digest, rr->ds.digest_size, NULL);
                break;

        case DNS_TYPE_SSHFP:
                r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_blob(p, rr->sshfp.fingerprint, rr->sshfp.fingerprint_size, NULL);
                break;

        case DNS_TYPE_DNSKEY:
                r = dns_packet_append_uint16(p, rr->dnskey.flags, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->dnskey.protocol, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
                break;

        case DNS_TYPE_RRSIG:
                r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint16(p, rr->rrsig.key_tag, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_name(p, rr->rrsig.signer, false, true, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
                break;

        case DNS_TYPE_NSEC:
                r = dns_packet_append_name(p, rr->nsec.next_domain_name, false, false, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_types(p, rr->nsec.types, NULL);
                if (r < 0)
                        goto fail;

                break;

        case DNS_TYPE_NSEC3:
                r = dns_packet_append_uint8(p, rr->nsec3.algorithm, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->nsec3.flags, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint16(p, rr->nsec3.iterations, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->nsec3.salt_size, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_blob(p, rr->nsec3.salt, rr->nsec3.salt_size, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->nsec3.next_hashed_name_size, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_blob(p, rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_types(p, rr->nsec3.types, NULL);
                if (r < 0)
                        goto fail;

                break;

        case DNS_TYPE_TLSA:
                r = dns_packet_append_uint8(p, rr->tlsa.cert_usage, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->tlsa.selector, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_uint8(p, rr->tlsa.matching_type, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_blob(p, rr->tlsa.data, rr->tlsa.data_size, NULL);
                break;

        case DNS_TYPE_CAA:
                r = dns_packet_append_uint8(p, rr->caa.flags, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_string(p, rr->caa.tag, NULL);
                if (r < 0)
                        goto fail;

                r = dns_packet_append_blob(p, rr->caa.value, rr->caa.value_size, NULL);
                break;

        case DNS_TYPE_OPT:
        case DNS_TYPE_OPENPGPKEY:
        case _DNS_TYPE_INVALID: /* unparsable */
        default:

                r = dns_packet_append_blob(p, rr->generic.data, rr->generic.data_size, NULL);
                break;
        }
        if (r < 0)
                goto fail;

        /* Let's calculate the actual data size and update the field */
        rdlength = p->size - rdlength_offset - sizeof(uint16_t);
        if (rdlength > 0xFFFF) {
                r = -ENOSPC;
                goto fail;
        }

        end = p->size;
        p->size = rdlength_offset;
        r = dns_packet_append_uint16(p, rdlength, NULL);
        if (r < 0)
                goto fail;
        p->size = end;

        if (start)
                *start = saved_size;

        if (rdata_start)
                *rdata_start = rds;

        return 0;

fail:
        dns_packet_truncate(p, saved_size);
        return r;
}

int dns_packet_append_question(DnsPacket *p, DnsQuestion *q) {
        DnsResourceKey *key;
        int r;

        assert(p);

        DNS_QUESTION_FOREACH(key, q) {
                r = dns_packet_append_key(p, key, 0, NULL);
                if (r < 0)
                        return r;
        }

        return 0;
}

int dns_packet_append_answer(DnsPacket *p, DnsAnswer *a, unsigned *completed) {
        DnsResourceRecord *rr;
        DnsAnswerFlags flags;
        int r;

        assert(p);

        DNS_ANSWER_FOREACH_FLAGS(rr, flags, a) {
                r = dns_packet_append_rr(p, rr, flags, NULL, NULL);
                if (r < 0)
                        return r;

                if (completed)
                        (*completed)++;
        }

        return 0;
}

int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
        assert(p);

        if (p->rindex + sz > p->size)
                return -EMSGSIZE;

        if (ret)
                *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;

        if (start)
                *start = p->rindex;

        p->rindex += sz;
        return 0;
}

void dns_packet_rewind(DnsPacket *p, size_t idx) {
        assert(p);
        assert(idx <= p->size);
        assert(idx >= DNS_PACKET_HEADER_SIZE);

        p->rindex = idx;
}

int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
        const void *q;
        int r;

        assert(p);
        assert(d);

        r = dns_packet_read(p, sz, &q, start);
        if (r < 0)
                return r;

        memcpy(d, q, sz);
        return 0;
}

static int dns_packet_read_memdup(
                DnsPacket *p, size_t size,
                void **ret, size_t *ret_size,
                size_t *ret_start) {

        const void *src;
        size_t start;
        int r;

        assert(p);
        assert(ret);

        r = dns_packet_read(p, size, &src, &start);
        if (r < 0)
                return r;

        if (size <= 0)
                *ret = NULL;
        else {
                void *copy;

                copy = memdup(src, size);
                if (!copy)
                        return -ENOMEM;

                *ret = copy;
        }

        if (ret_size)
                *ret_size = size;
        if (ret_start)
                *ret_start = start;

        return 0;
}

int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
        const void *d;
        int r;

        assert(p);

        r = dns_packet_read(p, sizeof(uint8_t), &d, start);
        if (r < 0)
                return r;

        *ret = ((uint8_t*) d)[0];
        return 0;
}

int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
        const void *d;
        int r;

        assert(p);

        r = dns_packet_read(p, sizeof(uint16_t), &d, start);
        if (r < 0)
                return r;

        if (ret)
                *ret = unaligned_read_be16(d);

        return 0;
}

int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
        const void *d;
        int r;

        assert(p);

        r = dns_packet_read(p, sizeof(uint32_t), &d, start);
        if (r < 0)
                return r;

        *ret = unaligned_read_be32(d);

        return 0;
}

int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
        const void *d;
        char *t;
        uint8_t c;
        int r;

        assert(p);
        INIT_REWINDER(rewinder, p);

        r = dns_packet_read_uint8(p, &c, NULL);
        if (r < 0)
                return r;

        r = dns_packet_read(p, c, &d, NULL);
        if (r < 0)
                return r;

        if (memchr(d, 0, c))
                return -EBADMSG;

        t = strndup(d, c);
        if (!t)
                return -ENOMEM;

        if (!utf8_is_valid(t)) {
                free(t);
                return -EBADMSG;
        }

        *ret = t;

        if (start)
                *start = rewinder.saved_rindex;
        CANCEL_REWINDER(rewinder);

        return 0;
}

int dns_packet_read_raw_string(DnsPacket *p, const void **ret, size_t *size, size_t *start) {
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
        uint8_t c;
        int r;

        assert(p);
        INIT_REWINDER(rewinder, p);

        r = dns_packet_read_uint8(p, &c, NULL);
        if (r < 0)
                return r;

        r = dns_packet_read(p, c, ret, NULL);
        if (r < 0)
                return r;

        if (size)
                *size = c;
        if (start)
                *start = rewinder.saved_rindex;
        CANCEL_REWINDER(rewinder);

        return 0;
}

int dns_packet_read_name(
                DnsPacket *p,
                char **ret,
                bool allow_compression,
                size_t *ret_start) {

        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
        size_t after_rindex = 0, jump_barrier;
        _cleanup_free_ char *name = NULL;
        bool first = true;
        size_t n = 0;
        int r;

        assert(p);

        INIT_REWINDER(rewinder, p);
        jump_barrier = p->rindex;

        if (p->refuse_compression)
                allow_compression = false;

        for (;;) {
                uint8_t c, d;

                r = dns_packet_read_uint8(p, &c, NULL);
                if (r < 0)
                        return r;

                if (c == 0)
                        /* End of name */
                        break;
                else if (c <= 63) {
                        const char *label;

                        /* Literal label */
                        r = dns_packet_read(p, c, (const void**) &label, NULL);
                        if (r < 0)
                                return r;

                        if (!GREEDY_REALLOC(name, n + !first + DNS_LABEL_ESCAPED_MAX))
                                return -ENOMEM;

                        if (first)
                                first = false;
                        else
                                name[n++] = '.';

                        r = dns_label_escape(label, c, name + n, DNS_LABEL_ESCAPED_MAX);
                        if (r < 0)
                                return r;

                        n += r;
                        continue;
                } else if (allow_compression && FLAGS_SET(c, 0xc0)) {
                        uint16_t ptr;

                        /* Pointer */
                        r = dns_packet_read_uint8(p, &d, NULL);
                        if (r < 0)
                                return r;

                        ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
                        if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier)
                                return -EBADMSG;

                        if (after_rindex == 0)
                                after_rindex = p->rindex;

                        /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
                        jump_barrier = ptr;
                        p->rindex = ptr;
                } else
                        return -EBADMSG;
        }

        if (!GREEDY_REALLOC(name, n + 1))
                return -ENOMEM;

        name[n] = 0;

        if (after_rindex != 0)
                p->rindex= after_rindex;

        if (ret)
                *ret = TAKE_PTR(name);
        if (ret_start)
                *ret_start = rewinder.saved_rindex;

        CANCEL_REWINDER(rewinder);

        return 0;
}

static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *start) {
        uint8_t window;
        uint8_t length;
        const uint8_t *bitmap;
        uint8_t bit = 0;
        unsigned i;
        bool found = false;
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
        int r;

        assert(p);
        assert(types);
        INIT_REWINDER(rewinder, p);

        r = systemd_bitmap_ensure_allocated(types);
        if (r < 0)
                return r;

        r = dns_packet_read_uint8(p, &window, NULL);
        if (r < 0)
                return r;

        r = dns_packet_read_uint8(p, &length, NULL);
        if (r < 0)
                return r;

        if (length == 0 || length > 32)
                return -EBADMSG;

        r = dns_packet_read(p, length, (const void **)&bitmap, NULL);
        if (r < 0)
                return r;

        for (i = 0; i < length; i++) {
                uint8_t bitmask = 1 << 7;

                if (!bitmap[i]) {
                        found = false;
                        bit += 8;
                        continue;
                }

                found = true;

                for (; bitmask; bit++, bitmask >>= 1)
                        if (bitmap[i] & bitmask) {
                                uint16_t n;

                                n = (uint16_t) window << 8 | (uint16_t) bit;

                                /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
                                if (dns_type_is_pseudo(n))
                                        continue;

                                r = systemd_bitmap_set(*types, n);
                                if (r < 0)
                                        return r;
                        }
        }

        if (!found)
                return -EBADMSG;

        if (start)
                *start = rewinder.saved_rindex;
        CANCEL_REWINDER(rewinder);

        return 0;
}

static int dns_packet_read_type_windows(DnsPacket *p, Bitmap **types, size_t size, size_t *start) {
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
        int r;

        INIT_REWINDER(rewinder, p);

        while (p->rindex < rewinder.saved_rindex + size) {
                r = dns_packet_read_type_window(p, types, NULL);
                if (r < 0)
                        return r;

                /* don't read past end of current RR */
                if (p->rindex > rewinder.saved_rindex + size)
                        return -EBADMSG;
        }

        if (p->rindex != rewinder.saved_rindex + size)
                return -EBADMSG;

        if (start)
                *start = rewinder.saved_rindex;
        CANCEL_REWINDER(rewinder);

        return 0;
}

int dns_packet_read_key(
                DnsPacket *p,
                DnsResourceKey **ret,
                bool *ret_cache_flush_or_qu,
                size_t *ret_start) {

        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
        _cleanup_free_ char *name = NULL;
        bool cache_flush_or_qu = false;
        uint16_t class, type;
        int r;

        assert(p);
        INIT_REWINDER(rewinder, p);

        r = dns_packet_read_name(p, &name, true, NULL);
        if (r < 0)
                return r;

        r = dns_packet_read_uint16(p, &type, NULL);
        if (r < 0)
                return r;

        r = dns_packet_read_uint16(p, &class, NULL);
        if (r < 0)
                return r;

        if (p->protocol == DNS_PROTOCOL_MDNS) {
                /* See RFC6762, sections 5.4 and 10.2 */

                if (type != DNS_TYPE_OPT && (class & MDNS_RR_CACHE_FLUSH_OR_QU)) {
                        class &= ~MDNS_RR_CACHE_FLUSH_OR_QU;
                        cache_flush_or_qu = true;
                }
        }

        if (ret) {
                DnsResourceKey *key;

                key = dns_resource_key_new_consume(class, type, name);
                if (!key)
                        return -ENOMEM;

                TAKE_PTR(name);
                *ret = key;
        }

        if (ret_cache_flush_or_qu)
                *ret_cache_flush_or_qu = cache_flush_or_qu;
        if (ret_start)
                *ret_start = rewinder.saved_rindex;

        CANCEL_REWINDER(rewinder);
        return 0;
}

static bool loc_size_ok(uint8_t size) {
        uint8_t m = size >> 4, e = size & 0xF;

        return m <= 9 && e <= 9 && (m > 0 || e == 0);
}

int dns_packet_read_rr(
                DnsPacket *p,
                DnsResourceRecord **ret,
                bool *ret_cache_flush,
                size_t *ret_start) {

        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
        size_t offset;
        uint16_t rdlength;
        bool cache_flush;
        int r;

        assert(p);

        INIT_REWINDER(rewinder, p);

        r = dns_packet_read_key(p, &key, &cache_flush, NULL);
        if (r < 0)
                return r;

        if (!dns_class_is_valid_rr(key->class) || !dns_type_is_valid_rr(key->type))
                return -EBADMSG;

        rr = dns_resource_record_new(key);
        if (!rr)
                return -ENOMEM;

        r = dns_packet_read_uint32(p, &rr->ttl, NULL);
        if (r < 0)
                return r;

        /* RFC 2181, Section 8, suggests to
         * treat a TTL with the MSB set as a zero TTL. */
        if (rr->ttl & UINT32_C(0x80000000))
                rr->ttl = 0;

        r = dns_packet_read_uint16(p, &rdlength, NULL);
        if (r < 0)
                return r;

        if (p->rindex + rdlength > p->size)
                return -EBADMSG;

        offset = p->rindex;

        switch (rr->key->type) {

        case DNS_TYPE_SRV:
                r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
                if (r < 0)
                        return r;
                r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
                if (r < 0)
                        return r;
                r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
                if (r < 0)
                        return r;
                r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
                break;

        case DNS_TYPE_PTR:
        case DNS_TYPE_NS:
        case DNS_TYPE_CNAME:
        case DNS_TYPE_DNAME:
                r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
                break;

        case DNS_TYPE_HINFO:
                r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
                break;

        case DNS_TYPE_SPF: /* exactly the same as TXT */
        case DNS_TYPE_TXT:
                if (rdlength <= 0) {
                        r = dns_txt_item_new_empty(&rr->txt.items);
                        if (r < 0)
                                return r;
                } else {
                        DnsTxtItem *last = NULL;

                        while (p->rindex < offset + rdlength) {
                                DnsTxtItem *i;
                                const void *data;
                                size_t sz;

                                r = dns_packet_read_raw_string(p, &data, &sz, NULL);
                                if (r < 0)
                                        return r;

                                i = malloc0(offsetof(DnsTxtItem, data) + sz + 1); /* extra NUL byte at the end */
                                if (!i)
                                        return -ENOMEM;

                                memcpy(i->data, data, sz);
                                i->length = sz;

                                LIST_INSERT_AFTER(items, rr->txt.items, last, i);
                                last = i;
                        }
                }

                r = 0;
                break;

        case DNS_TYPE_A:
                r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
                break;

        case DNS_TYPE_AAAA:
                r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
                break;

        case DNS_TYPE_SOA:
                r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
                break;

        case DNS_TYPE_MX:
                r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
                break;

        case DNS_TYPE_LOC: {
                uint8_t t;
                size_t pos;

                r = dns_packet_read_uint8(p, &t, &pos);
                if (r < 0)
                        return r;

                if (t == 0) {
                        rr->loc.version = t;

                        r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
                        if (r < 0)
                                return r;

                        if (!loc_size_ok(rr->loc.size))
                                return -EBADMSG;

                        r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
                        if (r < 0)
                                return r;

                        if (!loc_size_ok(rr->loc.horiz_pre))
                                return -EBADMSG;

                        r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
                        if (r < 0)
                                return r;

                        if (!loc_size_ok(rr->loc.vert_pre))
                                return -EBADMSG;

                        r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
                        if (r < 0)
                                return r;

                        r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
                        if (r < 0)
                                return r;

                        r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
                        if (r < 0)
                                return r;

                        break;
                } else {
                        dns_packet_rewind(p, pos);
                        rr->unparsable = true;
                        goto unparsable;
                }
        }

        case DNS_TYPE_DS:
                r = dns_packet_read_uint16(p, &rr->ds.key_tag, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint8(p, &rr->ds.algorithm, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint8(p, &rr->ds.digest_type, NULL);
                if (r < 0)
                        return r;

                if (rdlength < 4)
                        return -EBADMSG;

                r = dns_packet_read_memdup(p, rdlength - 4,
                                           &rr->ds.digest, &rr->ds.digest_size,
                                           NULL);
                if (r < 0)
                        return r;

                if (rr->ds.digest_size <= 0)
                        /* the accepted size depends on the algorithm, but for now
                           just ensure that the value is greater than zero */
                        return -EBADMSG;

                break;

        case DNS_TYPE_SSHFP:
                r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
                if (r < 0)
                        return r;

                if (rdlength < 2)
                        return -EBADMSG;

                r = dns_packet_read_memdup(p, rdlength - 2,
                                           &rr->sshfp.fingerprint, &rr->sshfp.fingerprint_size,
                                           NULL);

                if (rr->sshfp.fingerprint_size <= 0)
                        /* the accepted size depends on the algorithm, but for now
                           just ensure that the value is greater than zero */
                        return -EBADMSG;

                break;

        case DNS_TYPE_DNSKEY:
                r = dns_packet_read_uint16(p, &rr->dnskey.flags, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint8(p, &rr->dnskey.protocol, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
                if (r < 0)
                        return r;

                if (rdlength < 4)
                        return -EBADMSG;

                r = dns_packet_read_memdup(p, rdlength - 4,
                                           &rr->dnskey.key, &rr->dnskey.key_size,
                                           NULL);

                if (rr->dnskey.key_size <= 0)
                        /* the accepted size depends on the algorithm, but for now
                           just ensure that the value is greater than zero */
                        return -EBADMSG;

                break;

        case DNS_TYPE_RRSIG:
                r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
                if (r < 0)
                        return r;

                if (rdlength + offset < p->rindex)
                        return -EBADMSG;

                r = dns_packet_read_memdup(p, offset + rdlength - p->rindex,
                                           &rr->rrsig.signature, &rr->rrsig.signature_size,
                                           NULL);

                if (rr->rrsig.signature_size <= 0)
                        /* the accepted size depends on the algorithm, but for now
                           just ensure that the value is greater than zero */
                        return -EBADMSG;

                break;

        case DNS_TYPE_NSEC: {

                /*
                 * RFC6762, section 18.14 explicitly states mDNS should use name compression.
                 * This contradicts RFC3845, section 2.1.1
                 */

                bool allow_compressed = p->protocol == DNS_PROTOCOL_MDNS;

                r = dns_packet_read_name(p, &rr->nsec.next_domain_name, allow_compressed, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL);

                /* We accept empty NSEC bitmaps. The bit indicating the presence of the NSEC record itself
                 * is redundant and in e.g., RFC4956 this fact is used to define a use for NSEC records
                 * without the NSEC bit set. */

                break;
        }
        case DNS_TYPE_NSEC3: {
                uint8_t size;

                r = dns_packet_read_uint8(p, &rr->nsec3.algorithm, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint8(p, &rr->nsec3.flags, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint16(p, &rr->nsec3.iterations, NULL);
                if (r < 0)
                        return r;

                /* this may be zero */
                r = dns_packet_read_uint8(p, &size, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_memdup(p, size, &rr->nsec3.salt, &rr->nsec3.salt_size, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint8(p, &size, NULL);
                if (r < 0)
                        return r;

                if (size <= 0)
                        return -EBADMSG;

                r = dns_packet_read_memdup(p, size,
                                           &rr->nsec3.next_hashed_name, &rr->nsec3.next_hashed_name_size,
                                           NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL);

                /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */

                break;
        }

        case DNS_TYPE_TLSA:
                r = dns_packet_read_uint8(p, &rr->tlsa.cert_usage, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint8(p, &rr->tlsa.selector, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_uint8(p, &rr->tlsa.matching_type, NULL);
                if (r < 0)
                        return r;

                if (rdlength < 3)
                        return -EBADMSG;

                r = dns_packet_read_memdup(p, rdlength - 3,
                                           &rr->tlsa.data, &rr->tlsa.data_size,
                                           NULL);

                if (rr->tlsa.data_size <= 0)
                        /* the accepted size depends on the algorithm, but for now
                           just ensure that the value is greater than zero */
                        return -EBADMSG;

                break;

        case DNS_TYPE_CAA:
                r = dns_packet_read_uint8(p, &rr->caa.flags, NULL);
                if (r < 0)
                        return r;

                r = dns_packet_read_string(p, &rr->caa.tag, NULL);
                if (r < 0)
                        return r;

                if (rdlength + offset < p->rindex)
                        return -EBADMSG;

                r = dns_packet_read_memdup(p,
                                           rdlength + offset - p->rindex,
                                           &rr->caa.value, &rr->caa.value_size, NULL);

                break;

        case DNS_TYPE_OPT: /* we only care about the header of OPT for now. */
        case DNS_TYPE_OPENPGPKEY:
        default:
        unparsable:
                r = dns_packet_read_memdup(p, rdlength, &rr->generic.data, &rr->generic.data_size, NULL);

                break;
        }
        if (r < 0)
                return r;
        if (p->rindex != offset + rdlength)
                return -EBADMSG;

        if (ret)
                *ret = TAKE_PTR(rr);
        if (ret_cache_flush)
                *ret_cache_flush = cache_flush;
        if (ret_start)
                *ret_start = rewinder.saved_rindex;

        CANCEL_REWINDER(rewinder);
        return 0;
}

static bool opt_is_good(DnsResourceRecord *rr, bool *rfc6975) {
        const uint8_t* p;
        bool found_dau_dhu_n3u = false;
        size_t l;

        /* Checks whether the specified OPT RR is well-formed and whether it contains RFC6975 data (which is not OK in
         * a reply). */

        assert(rr);
        assert(rr->key->type == DNS_TYPE_OPT);

        /* Check that the version is 0 */
        if (((rr->ttl >> 16) & UINT32_C(0xFF)) != 0) {
                *rfc6975 = false;
                return true; /* if it's not version 0, it's OK, but we will ignore the OPT field contents */
        }

        p = rr->opt.data;
        l = rr->opt.data_size;
        while (l > 0) {
                uint16_t option_code, option_length;

                /* At least four bytes for OPTION-CODE and OPTION-LENGTH are required */
                if (l < 4U)
                        return false;

                option_code = unaligned_read_be16(p);
                option_length = unaligned_read_be16(p + 2);

                if (l < option_length + 4U)
                        return false;

                /* RFC 6975 DAU, DHU or N3U fields found. */
                if (IN_SET(option_code, 5, 6, 7))
                        found_dau_dhu_n3u = true;

                p += option_length + 4U;
                l -= option_length + 4U;
        }

        *rfc6975 = found_dau_dhu_n3u;
        return true;
}

static int dns_packet_extract_question(DnsPacket *p, DnsQuestion **ret_question) {
        _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
        unsigned n, i;
        int r;

        n = DNS_PACKET_QDCOUNT(p);
        if (n > 0) {
                question = dns_question_new(n);
                if (!question)
                        return -ENOMEM;

                _cleanup_set_free_ Set *keys = NULL; /* references to keys are kept by Question */

                keys = set_new(&dns_resource_key_hash_ops);
                if (!keys)
                        return log_oom();

                r = set_reserve(keys, n * 2); /* Higher multipliers give slightly higher efficiency through
                                               * hash collisions, but the gains quickly drop off after 2. */
                if (r < 0)
                        return r;

                for (i = 0; i < n; i++) {
                        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
                        bool qu;

                        r = dns_packet_read_key(p, &key, &qu, NULL);
                        if (r < 0)
                                return r;

                        if (!dns_type_is_valid_query(key->type))
                                return -EBADMSG;

                        r = set_put(keys, key);
                        if (r < 0)
                                return r;
                        if (r == 0)
                                /* Already in the Question, let's skip */
                                continue;

                        r = dns_question_add_raw(question, key, qu ? DNS_QUESTION_WANTS_UNICAST_REPLY : 0);
                        if (r < 0)
                                return r;
                }
        }

        *ret_question = TAKE_PTR(question);

        return 0;
}

static int dns_packet_extract_answer(DnsPacket *p, DnsAnswer **ret_answer) {
        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
        unsigned n, i;
        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *previous = NULL;
        bool bad_opt = false;
        int r;

        n = DNS_PACKET_RRCOUNT(p);
        if (n == 0)
                return 0;

        answer = dns_answer_new(n);
        if (!answer)
                return -ENOMEM;

        for (i = 0; i < n; i++) {
                _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
                bool cache_flush = false;
                size_t start;

                if (p->rindex == p->size && p->opt) {
                        /* If we reached the end of the packet already, but there are still more RRs
                         * declared, then that's a corrupt packet. Let's accept the packet anyway, since it's
                         * apparently a common bug in routers. Let's however suppress OPT support in this
                         * case, so that we force the rest of the logic into lowest DNS baseline support. Or
                         * to say this differently: if the DNS server doesn't even get the RR counts right,
                         * it's highly unlikely it gets EDNS right. */
                        log_debug("More resource records declared in packet than included, suppressing OPT.");
                        bad_opt = true;
                        break;
                }

                r = dns_packet_read_rr(p, &rr, &cache_flush, &start);
                if (r < 0)
                        return r;

                /* Try to reduce memory usage a bit */
                if (previous)
                        dns_resource_key_reduce(&rr->key, &previous->key);

                if (rr->key->type == DNS_TYPE_OPT) {
                        bool has_rfc6975;

                        if (p->opt || bad_opt) {
                                /* Multiple OPT RRs? if so, let's ignore all, because there's
                                 * something wrong with the server, and if one is valid we wouldn't
                                 * know which one. */
                                log_debug("Multiple OPT RRs detected, ignoring all.");
                                bad_opt = true;
                                continue;
                        }

                        if (!dns_name_is_root(dns_resource_key_name(rr->key))) {
                                /* If the OPT RR is not owned by the root domain, then it is bad,
                                 * let's ignore it. */
                                log_debug("OPT RR is not owned by root domain, ignoring.");
                                bad_opt = true;
                                continue;
                        }

                        if (i < DNS_PACKET_ANCOUNT(p) + DNS_PACKET_NSCOUNT(p)) {
                                /* OPT RR is in the wrong section? Some Belkin routers do this. This
                                 * is a hint the EDNS implementation is borked, like the Belkin one
                                 * is, hence ignore it. */
                                log_debug("OPT RR in wrong section, ignoring.");
                                bad_opt = true;
                                continue;
                        }

                        if (!opt_is_good(rr, &has_rfc6975)) {
                                log_debug("Malformed OPT RR, ignoring.");
                                bad_opt = true;
                                continue;
                        }

                        if (DNS_PACKET_QR(p)) {
                                /* Additional checks for responses */

                                if (!DNS_RESOURCE_RECORD_OPT_VERSION_SUPPORTED(rr))
                                        /* If this is a reply and we don't know the EDNS version
                                         * then something is weird... */
                                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                                               "EDNS version newer that our request, bad server.");

                                if (has_rfc6975) {
                                        /* If the OPT RR contains RFC6975 algorithm data, then this
                                         * is indication that the server just copied the OPT it got
                                         * from us (which contained that data) back into the reply.
                                         * If so, then it doesn't properly support EDNS, as RFC6975
                                         * makes it very clear that the algorithm data should only
                                         * be contained in questions, never in replies. Crappy
                                         * Belkin routers copy the OPT data for example, hence let's
                                         * detect this so that we downgrade early. */
                                        log_debug("OPT RR contains RFC6975 data, ignoring.");
                                        bad_opt = true;
                                        continue;
                                }
                        }

                        p->opt = dns_resource_record_ref(rr);
                        p->opt_start = start;
                        assert(p->rindex >= start);
                        p->opt_size = p->rindex - start;
                } else {
                        DnsAnswerFlags flags = 0;

                        if (p->protocol == DNS_PROTOCOL_MDNS && !cache_flush)
                                flags |= DNS_ANSWER_SHARED_OWNER;

                        /* According to RFC 4795, section 2.9. only the RRs from the Answer section shall be
                         * cached. Hence mark only those RRs as cacheable by default, but not the ones from
                         * the Additional or Authority sections. */
                        if (i < DNS_PACKET_ANCOUNT(p))
                                flags |= DNS_ANSWER_CACHEABLE|DNS_ANSWER_SECTION_ANSWER;
                        else if (i < DNS_PACKET_ANCOUNT(p) + DNS_PACKET_NSCOUNT(p))
                                flags |= DNS_ANSWER_SECTION_AUTHORITY;
                        else
                                flags |= DNS_ANSWER_SECTION_ADDITIONAL;

                        r = dns_answer_add(answer, rr, p->ifindex, flags, NULL);
                        if (r < 0)
                                return r;
                }

                /* Remember this RR, so that we can potentially merge its ->key object with the
                 * next RR. Note that we only do this if we actually decided to keep the RR around.
                 */
                dns_resource_record_unref(previous);
                previous = dns_resource_record_ref(rr);
        }

        if (bad_opt) {
                p->opt = dns_resource_record_unref(p->opt);
                p->opt_start = p->opt_size = SIZE_MAX;
        }

        *ret_answer = TAKE_PTR(answer);

        return 0;
}

int dns_packet_extract(DnsPacket *p) {
        _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = {};
        int r;

        if (p->extracted)
                return 0;

        INIT_REWINDER(rewinder, p);
        dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);

        r = dns_packet_extract_question(p, &question);
        if (r < 0)
                return r;

        r = dns_packet_extract_answer(p, &answer);
        if (r < 0)
                return r;

        if (p->rindex < p->size)  {
                log_debug("Trailing garbage in packet, suppressing OPT.");
                p->opt = dns_resource_record_unref(p->opt);
                p->opt_start = p->opt_size = SIZE_MAX;
        }

        p->question = TAKE_PTR(question);
        p->answer = TAKE_PTR(answer);

        p->extracted = true;

        /* no CANCEL, always rewind */
        return 0;
}

int dns_packet_is_reply_for(DnsPacket *p, const DnsResourceKey *key) {
        int r;

        assert(p);
        assert(key);

        /* Checks if the specified packet is a reply for the specified
         * key and the specified key is the only one in the question
         * section. */

        if (DNS_PACKET_QR(p) != 1)
                return 0;

        /* Let's unpack the packet, if that hasn't happened yet. */
        r = dns_packet_extract(p);
        if (r < 0)
                return r;

        if (!p->question)
                return 0;

        if (p->question->n_keys != 1)
                return 0;

        return dns_resource_key_equal(dns_question_first_key(p->question), key);
}

int dns_packet_patch_max_udp_size(DnsPacket *p, uint16_t max_udp_size) {
        assert(p);
        assert(max_udp_size >= DNS_PACKET_UNICAST_SIZE_MAX);

        if (p->opt_start == SIZE_MAX) /* No OPT section, nothing to patch */
                return 0;

        assert(p->opt_size != SIZE_MAX);
        assert(p->opt_size >= 5);

        unaligned_write_be16(DNS_PACKET_DATA(p) + p->opt_start + 3, max_udp_size);
        return 1;
}

static int patch_rr(DnsPacket *p, usec_t age) {
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
        size_t ttl_index;
        uint32_t ttl;
        uint16_t type, rdlength;
        int r;

        INIT_REWINDER(rewinder, p);

        /* Patches the RR at the current rindex, subtracts the specified time from the TTL */

        r = dns_packet_read_name(p, NULL, true, NULL);
        if (r < 0)
                return r;

        r = dns_packet_read_uint16(p, &type, NULL);
        if (r < 0)
                return r;

        r = dns_packet_read_uint16(p, NULL, NULL);
        if (r < 0)
                return r;

        r = dns_packet_read_uint32(p, &ttl, &ttl_index);
        if (r < 0)
                return r;

        if (type != DNS_TYPE_OPT) { /* The TTL of the OPT field is not actually a TTL, skip it */
                ttl = LESS_BY(ttl * USEC_PER_SEC, age) / USEC_PER_SEC;
                unaligned_write_be32(DNS_PACKET_DATA(p) + ttl_index, ttl);
        }

        r = dns_packet_read_uint16(p, &rdlength, NULL);
        if (r < 0)
                return r;

        r = dns_packet_read(p, rdlength, NULL, NULL);
        if (r < 0)
                return r;

        CANCEL_REWINDER(rewinder);
        return 0;
}

int dns_packet_patch_ttls(DnsPacket *p, usec_t timestamp) {
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = {};
        unsigned i, n;
        usec_t k;
        int r;

        assert(p);
        assert(timestamp_is_set(timestamp));

        /* Adjusts all TTLs in the packet by subtracting the time difference between now and the specified timestamp */

        k = now(clock_boottime_or_monotonic());
        assert(k >= timestamp);
        k -= timestamp;

        INIT_REWINDER(rewinder, p);

        dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);

        n = DNS_PACKET_QDCOUNT(p);
        for (i = 0; i < n; i++) {
                r = dns_packet_read_key(p, NULL, NULL, NULL);
                if (r < 0)
                        return r;
        }

        n = DNS_PACKET_RRCOUNT(p);
        for (i = 0; i < n; i++) {

                /* DNS servers suck, hence the RR count is in many servers off. If we reached the end
                 * prematurely, accept that, exit early */
                if (p->rindex == p->size)
                        break;

                r = patch_rr(p, k);
                if (r < 0)
                        return r;
        }

        return 0;
}

static void dns_packet_hash_func(const DnsPacket *s, struct siphash *state) {
        assert(s);

        siphash24_compress(&s->size, sizeof(s->size), state);
        siphash24_compress(DNS_PACKET_DATA((DnsPacket*) s), s->size, state);
}

static int dns_packet_compare_func(const DnsPacket *x, const DnsPacket *y) {
        int r;

        r = CMP(x->size, y->size);
        if (r != 0)
                return r;

        return memcmp(DNS_PACKET_DATA((DnsPacket*) x), DNS_PACKET_DATA((DnsPacket*) y), x->size);
}

DEFINE_HASH_OPS(dns_packet_hash_ops, DnsPacket, dns_packet_hash_func, dns_packet_compare_func);

bool dns_packet_equal(const DnsPacket *a, const DnsPacket *b) {
        return dns_packet_compare_func(a, b) == 0;
}

int dns_packet_has_nsid_request(DnsPacket *p) {
        bool has_nsid = false;
        const uint8_t *d;
        size_t l;

        assert(p);

        if (!p->opt)
                return false;

        d = p->opt->opt.data;
        l = p->opt->opt.data_size;

        while (l > 0) {
                uint16_t code, length;

                if (l < 4U)
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "EDNS0 variable part has invalid size.");

                code = unaligned_read_be16(d);
                length = unaligned_read_be16(d + 2);

                if (l < 4U + length)
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                               "Truncated option in EDNS0 variable part.");

                if (code == 3) {
                        if (has_nsid)
                                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                                       "Duplicate NSID option in EDNS0 variable part.");

                        if (length != 0)
                                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
                                                       "Non-empty NSID option in DNS request.");

                        has_nsid = true;
                }

                d += 4U + length;
                l -= 4U + length;
        }

        return has_nsid;
}

size_t dns_packet_size_unfragmented(DnsPacket *p) {
        assert(p);

        if (p->fragsize == 0) /* Wasn't fragmented */
                return p->size;

        /* The fragment size (p->fragsize) covers the whole (fragmented) IP packet, while the regular packet
         * size (p->size) only covers the DNS part. Thus, subtract the UDP header from the largest fragment
         * size, in order to determine which size of DNS packet would have gone through without
         * fragmenting. */

        return LESS_BY(p->fragsize, udp_header_size(p->family));
}

static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
        [DNS_RCODE_SUCCESS]   = "SUCCESS",
        [DNS_RCODE_FORMERR]   = "FORMERR",
        [DNS_RCODE_SERVFAIL]  = "SERVFAIL",
        [DNS_RCODE_NXDOMAIN]  = "NXDOMAIN",
        [DNS_RCODE_NOTIMP]    = "NOTIMP",
        [DNS_RCODE_REFUSED]   = "REFUSED",
        [DNS_RCODE_YXDOMAIN]  = "YXDOMAIN",
        [DNS_RCODE_YXRRSET]   = "YRRSET",
        [DNS_RCODE_NXRRSET]   = "NXRRSET",
        [DNS_RCODE_NOTAUTH]   = "NOTAUTH",
        [DNS_RCODE_NOTZONE]   = "NOTZONE",
        [DNS_RCODE_BADVERS]   = "BADVERS",
        [DNS_RCODE_BADKEY]    = "BADKEY",
        [DNS_RCODE_BADTIME]   = "BADTIME",
        [DNS_RCODE_BADMODE]   = "BADMODE",
        [DNS_RCODE_BADNAME]   = "BADNAME",
        [DNS_RCODE_BADALG]    = "BADALG",
        [DNS_RCODE_BADTRUNC]  = "BADTRUNC",
        [DNS_RCODE_BADCOOKIE] = "BADCOOKIE",
};
DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);

static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
        [DNS_PROTOCOL_DNS]   = "dns",
        [DNS_PROTOCOL_MDNS]  = "mdns",
        [DNS_PROTOCOL_LLMNR] = "llmnr",
};
DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
