1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include "unaligned.h"
26 #include "resolved-dns-domain.h"
27 #include "resolved-dns-packet.h"
29 int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
36 a = DNS_PACKET_SIZE_START;
40 if (a < DNS_PACKET_HEADER_SIZE)
41 a = DNS_PACKET_HEADER_SIZE;
43 /* round up to next page size */
44 a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
46 /* make sure we never allocate more than useful */
47 if (a > DNS_PACKET_SIZE_MAX)
48 a = DNS_PACKET_SIZE_MAX;
50 p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
54 p->size = p->rindex = DNS_PACKET_HEADER_SIZE;
56 p->protocol = protocol;
64 int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
71 r = dns_packet_new(&p, protocol, mtu);
75 h = DNS_PACKET_HEADER(p);
77 if (protocol == DNS_PROTOCOL_LLMNR)
78 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
88 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
92 1 /* rd (ask for recursion) */,
102 DnsPacket *dns_packet_ref(DnsPacket *p) {
107 assert(p->n_ref > 0);
112 static void dns_packet_free(DnsPacket *p) {
117 dns_question_unref(p->question);
118 dns_answer_unref(p->answer);
120 while ((s = hashmap_steal_first_key(p->names)))
122 hashmap_free(p->names);
128 DnsPacket *dns_packet_unref(DnsPacket *p) {
132 assert(p->n_ref > 0);
142 int dns_packet_validate(DnsPacket *p) {
145 if (p->size < DNS_PACKET_HEADER_SIZE)
148 if (p->size > DNS_PACKET_SIZE_MAX)
154 int dns_packet_validate_reply(DnsPacket *p) {
159 r = dns_packet_validate(p);
163 if (DNS_PACKET_QR(p) != 1)
166 if (DNS_PACKET_OPCODE(p) != 0)
169 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
170 if (p->protocol == DNS_PROTOCOL_LLMNR &&
171 DNS_PACKET_QDCOUNT(p) != 1)
177 int dns_packet_validate_query(DnsPacket *p) {
182 r = dns_packet_validate(p);
186 if (DNS_PACKET_QR(p) != 0)
189 if (DNS_PACKET_OPCODE(p) != 0)
192 if (DNS_PACKET_TC(p))
195 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
196 if (p->protocol == DNS_PROTOCOL_LLMNR &&
197 DNS_PACKET_QDCOUNT(p) != 1)
200 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
201 if (DNS_PACKET_ANCOUNT(p) > 0)
204 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
205 if (DNS_PACKET_NSCOUNT(p) > 0)
211 static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
214 if (p->size + add > p->allocated) {
217 a = PAGE_ALIGN((p->size + add) * 2);
218 if (a > DNS_PACKET_SIZE_MAX)
219 a = DNS_PACKET_SIZE_MAX;
221 if (p->size + add > a)
227 d = realloc(p->_data, a);
233 p->_data = malloc(a);
237 memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
238 memzero((uint8_t*) p->_data + p->size, a - p->size);
248 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;
254 static void dns_packet_truncate(DnsPacket *p, size_t sz) {
264 HASHMAP_FOREACH_KEY(s, n, p->names, i) {
266 if (PTR_TO_SIZE(n) < sz)
269 hashmap_remove(p->names, s);
276 int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
282 r = dns_packet_extend(p, l, &q, start);
290 int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
296 r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
300 ((uint8_t*) d)[0] = v;
305 int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
311 r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
315 unaligned_write_be16(d, v);
320 int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start) {
326 r = dns_packet_extend(p, sizeof(uint32_t), &d, start);
330 unaligned_write_be32(d, v);
335 int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
347 r = dns_packet_extend(p, 1 + l, &d, start);
351 ((uint8_t*) d)[0] = (uint8_t) l;
352 memcpy(((uint8_t*) d) + 1, s, l);
357 int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start) {
364 if (l > DNS_LABEL_MAX)
367 r = dns_packet_extend(p, 1 + l, &w, start);
371 ((uint8_t*) w)[0] = (uint8_t) l;
372 memcpy(((uint8_t*) w) + 1, d, l);
377 int dns_packet_append_name(DnsPacket *p, const char *name,
378 bool allow_compression, size_t *start) {
385 saved_size = p->size;
388 _cleanup_free_ char *s = NULL;
389 char label[DNS_LABEL_MAX];
393 if (allow_compression)
394 n = PTR_TO_SIZE(hashmap_get(p->names, name));
399 r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
413 r = dns_label_unescape(&name, label, sizeof(label));
417 if (p->protocol == DNS_PROTOCOL_DNS)
418 k = dns_label_apply_idna(label, r, label, sizeof(label));
420 k = dns_label_undo_idna(label, r, label, sizeof(label));
428 r = dns_packet_append_label(p, label, r, &n);
432 if (allow_compression) {
433 r = hashmap_ensure_allocated(&p->names, &dns_name_hash_ops);
437 r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
445 r = dns_packet_append_uint8(p, 0, NULL);
456 dns_packet_truncate(p, saved_size);
460 int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
467 saved_size = p->size;
469 r = dns_packet_append_name(p, DNS_RESOURCE_KEY_NAME(k), true, NULL);
473 r = dns_packet_append_uint16(p, k->type, NULL);
477 r = dns_packet_append_uint16(p, k->class, NULL);
487 dns_packet_truncate(p, saved_size);
491 int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start) {
492 size_t saved_size, rdlength_offset, end, rdlength;
498 saved_size = p->size;
500 r = dns_packet_append_key(p, rr->key, NULL);
504 r = dns_packet_append_uint32(p, rr->ttl, NULL);
508 /* Initially we write 0 here */
509 r = dns_packet_append_uint16(p, 0, &rdlength_offset);
513 switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
516 r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
520 r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
524 r = dns_packet_append_uint16(p, rr->srv.port, NULL);
528 r = dns_packet_append_name(p, rr->srv.name, true, NULL);
535 r = dns_packet_append_name(p, rr->ptr.name, true, NULL);
539 r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
543 r = dns_packet_append_string(p, rr->hinfo.os, NULL);
546 case DNS_TYPE_SPF: /* exactly the same as TXT */
550 STRV_FOREACH(s, rr->txt.strings) {
551 r = dns_packet_append_string(p, *s, NULL);
561 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
565 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
569 r = dns_packet_append_name(p, rr->soa.mname, true, NULL);
573 r = dns_packet_append_name(p, rr->soa.rname, true, NULL);
577 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
581 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
585 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
589 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
593 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
597 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
601 r = dns_packet_append_name(p, rr->mx.exchange, true, NULL);
605 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
609 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
613 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
617 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
621 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
625 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
629 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
633 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
637 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
641 r = dns_packet_append_blob(p, rr->sshfp.key, rr->sshfp.key_size, NULL);
644 case DNS_TYPE_DNSKEY:
645 r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
649 r = dns_packet_append_uint8(p, 3u, NULL);
653 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
657 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
661 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
665 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
669 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
673 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
677 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
681 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
685 r = dns_packet_append_uint8(p, rr->rrsig.key_tag, NULL);
689 r = dns_packet_append_name(p, rr->rrsig.signer, false, NULL);
693 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
696 case _DNS_TYPE_INVALID: /* unparseable */
699 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
705 /* Let's calculate the actual data size and update the field */
706 rdlength = p->size - rdlength_offset - sizeof(uint16_t);
707 if (rdlength > 0xFFFF) {
713 p->size = rdlength_offset;
714 r = dns_packet_append_uint16(p, rdlength, NULL);
725 dns_packet_truncate(p, saved_size);
730 int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
733 if (p->rindex + sz > p->size)
737 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
746 void dns_packet_rewind(DnsPacket *p, size_t idx) {
748 assert(idx <= p->size);
749 assert(idx >= DNS_PACKET_HEADER_SIZE);
754 int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
761 r = dns_packet_read(p, sz, &q, start);
769 int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
775 r = dns_packet_read(p, sizeof(uint8_t), &d, start);
779 *ret = ((uint8_t*) d)[0];
783 int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
789 r = dns_packet_read(p, sizeof(uint16_t), &d, start);
793 *ret = unaligned_read_be16(d);
798 int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
804 r = dns_packet_read(p, sizeof(uint32_t), &d, start);
808 *ret = unaligned_read_be32(d);
813 int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
822 saved_rindex = p->rindex;
824 r = dns_packet_read_uint8(p, &c, NULL);
828 r = dns_packet_read(p, c, &d, NULL);
832 if (memchr(d, 0, c)) {
843 if (!utf8_is_valid(t)) {
852 *start = saved_rindex;
857 dns_packet_rewind(p, saved_rindex);
861 int dns_packet_read_name(DnsPacket *p, char **_ret,
862 bool allow_compression, size_t *start) {
863 size_t saved_rindex, after_rindex = 0;
864 _cleanup_free_ char *ret = NULL;
865 size_t n = 0, allocated = 0;
872 saved_rindex = p->rindex;
877 r = dns_packet_read_uint8(p, &c, NULL);
885 _cleanup_free_ char *t = NULL;
889 r = dns_packet_read(p, c, (const void**) &label, NULL);
893 r = dns_label_escape(label, c, &t);
897 if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) {
907 memcpy(ret + n, t, r);
910 } else if (allow_compression && (c & 0xc0) == 0xc0) {
914 r = dns_packet_read_uint8(p, &d, NULL);
918 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
919 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= saved_rindex) {
924 if (after_rindex == 0)
925 after_rindex = p->rindex;
932 if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
939 if (after_rindex != 0)
940 p->rindex= after_rindex;
946 *start = saved_rindex;
951 dns_packet_rewind(p, saved_rindex);
955 int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
956 _cleanup_free_ char *name = NULL;
957 uint16_t class, type;
965 saved_rindex = p->rindex;
967 r = dns_packet_read_name(p, &name, true, NULL);
971 r = dns_packet_read_uint16(p, &type, NULL);
975 r = dns_packet_read_uint16(p, &class, NULL);
979 key = dns_resource_key_new_consume(class, type, name);
989 *start = saved_rindex;
993 dns_packet_rewind(p, saved_rindex);
997 static int dns_packet_read_public_key(DnsPacket *p, size_t length,
998 void **dp, size_t *lengthp,
1004 r = dns_packet_read(p, length, &d, NULL);
1008 d2 = memdup(d, length);
1017 static bool loc_size_ok(uint8_t size) {
1018 uint8_t m = size >> 4, e = size & 0xF;
1020 return m <= 9 && e <= 9 && (m > 0 || e == 0);
1023 static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
1026 if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
1029 rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
1030 rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
1034 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
1035 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1036 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1037 size_t saved_rindex, offset;
1045 saved_rindex = p->rindex;
1047 r = dns_packet_read_key(p, &key, NULL);
1051 if (key->class == DNS_CLASS_ANY ||
1052 key->type == DNS_TYPE_ANY) {
1057 rr = dns_resource_record_new(key);
1063 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1067 r = dns_packet_read_uint16(p, &rdlength, NULL);
1071 if (p->rindex + rdlength > p->size) {
1078 switch (rr->key->type) {
1081 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1084 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1087 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1090 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
1095 case DNS_TYPE_CNAME:
1096 case DNS_TYPE_DNAME:
1097 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
1100 case DNS_TYPE_HINFO:
1101 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1105 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1108 case DNS_TYPE_SPF: /* exactly the same as TXT */
1109 case DNS_TYPE_TXT: {
1112 while (p->rindex < offset + rdlength) {
1113 r = dns_packet_read_string(p, &s, NULL);
1117 r = strv_consume(&rr->txt.strings, s);
1127 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1131 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1135 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
1139 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
1143 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1147 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1151 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1155 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1159 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1163 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1167 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
1170 case DNS_TYPE_LOC: {
1174 r = dns_packet_read_uint8(p, &t, &pos);
1179 rr->loc.version = t;
1181 r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1185 if (!loc_size_ok(rr->loc.size)) {
1190 r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1194 if (!loc_size_ok(rr->loc.horiz_pre)) {
1199 r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1203 if (!loc_size_ok(rr->loc.vert_pre)) {
1208 r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1212 r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1216 r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1222 dns_packet_rewind(p, pos);
1223 rr->unparseable = true;
1228 case DNS_TYPE_SSHFP:
1229 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1233 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1237 r = dns_packet_read_public_key(p, rdlength - 2,
1238 &rr->sshfp.key, &rr->sshfp.key_size,
1242 case DNS_TYPE_DNSKEY: {
1246 r = dns_packet_read_uint16(p, &flags, NULL);
1250 r = dnskey_parse_flags(rr, flags);
1254 r = dns_packet_read_uint8(p, &proto, NULL);
1258 /* protocol is required to be always 3 */
1264 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1268 r = dns_packet_read_public_key(p, rdlength - 4,
1269 &rr->dnskey.key, &rr->dnskey.key_size,
1274 case DNS_TYPE_RRSIG:
1275 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1279 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1283 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1287 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1291 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1295 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1299 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1303 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1307 r = dns_packet_read_public_key(p, offset + rdlength - p->rindex,
1308 &rr->rrsig.signature, &rr->rrsig.signature_size,
1314 r = dns_packet_read(p, rdlength, &d, NULL);
1318 rr->generic.data = memdup(d, rdlength);
1319 if (!rr->generic.data) {
1324 rr->generic.size = rdlength;
1329 if (p->rindex != offset + rdlength) {
1338 *start = saved_rindex;
1342 dns_packet_rewind(p, saved_rindex);
1346 int dns_packet_extract(DnsPacket *p) {
1347 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1348 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1349 size_t saved_rindex;
1356 saved_rindex = p->rindex;
1357 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1359 n = DNS_PACKET_QDCOUNT(p);
1361 question = dns_question_new(n);
1367 for (i = 0; i < n; i++) {
1368 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1370 r = dns_packet_read_key(p, &key, NULL);
1374 r = dns_question_add(question, key);
1380 n = DNS_PACKET_RRCOUNT(p);
1382 answer = dns_answer_new(n);
1388 for (i = 0; i < n; i++) {
1389 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1391 r = dns_packet_read_rr(p, &rr, NULL);
1395 r = dns_answer_add(answer, rr);
1401 p->question = question;
1407 p->extracted = true;
1412 p->rindex = saved_rindex;
1416 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
1417 [DNS_RCODE_SUCCESS] = "SUCCESS",
1418 [DNS_RCODE_FORMERR] = "FORMERR",
1419 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
1420 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
1421 [DNS_RCODE_NOTIMP] = "NOTIMP",
1422 [DNS_RCODE_REFUSED] = "REFUSED",
1423 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
1424 [DNS_RCODE_YXRRSET] = "YRRSET",
1425 [DNS_RCODE_NXRRSET] = "NXRRSET",
1426 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
1427 [DNS_RCODE_NOTZONE] = "NOTZONE",
1428 [DNS_RCODE_BADVERS] = "BADVERS",
1429 [DNS_RCODE_BADKEY] = "BADKEY",
1430 [DNS_RCODE_BADTIME] = "BADTIME",
1431 [DNS_RCODE_BADMODE] = "BADMODE",
1432 [DNS_RCODE_BADNAME] = "BADNAME",
1433 [DNS_RCODE_BADALG] = "BADALG",
1434 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
1436 DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1438 static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
1439 [DNS_PROTOCOL_DNS] = "dns",
1440 [DNS_PROTOCOL_MDNS] = "mdns",
1441 [DNS_PROTOCOL_LLMNR] = "llmnr",
1443 DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
1445 static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
1446 [DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
1447 [DNSSEC_ALGORITHM_DH] = "DH",
1448 [DNSSEC_ALGORITHM_DSA] = "DSA",
1449 [DNSSEC_ALGORITHM_ECC] = "ECC",
1450 [DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
1451 [DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
1452 [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
1453 [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
1455 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);