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 "resolved-dns-domain.h"
26 #include "resolved-dns-packet.h"
28 int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
35 a = DNS_PACKET_SIZE_START;
39 if (a < DNS_PACKET_HEADER_SIZE)
40 a = DNS_PACKET_HEADER_SIZE;
42 /* round up to next page size */
43 a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
45 /* make sure we never allocate more than useful */
46 if (a > DNS_PACKET_SIZE_MAX)
47 a = DNS_PACKET_SIZE_MAX;
49 p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
53 p->size = p->rindex = DNS_PACKET_HEADER_SIZE;
55 p->protocol = protocol;
63 int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
70 r = dns_packet_new(&p, protocol, mtu);
74 h = DNS_PACKET_HEADER(p);
76 if (protocol == DNS_PROTOCOL_LLMNR)
77 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
87 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
91 1 /* rd (ask for recursion) */,
101 DnsPacket *dns_packet_ref(DnsPacket *p) {
106 assert(p->n_ref > 0);
111 static void dns_packet_free(DnsPacket *p) {
116 dns_question_unref(p->question);
117 dns_answer_unref(p->answer);
119 while ((s = hashmap_steal_first_key(p->names)))
121 hashmap_free(p->names);
127 DnsPacket *dns_packet_unref(DnsPacket *p) {
131 assert(p->n_ref > 0);
141 int dns_packet_validate(DnsPacket *p) {
144 if (p->size < DNS_PACKET_HEADER_SIZE)
147 if (p->size > DNS_PACKET_SIZE_MAX)
153 int dns_packet_validate_reply(DnsPacket *p) {
158 r = dns_packet_validate(p);
162 if (DNS_PACKET_QR(p) != 1)
165 if (DNS_PACKET_OPCODE(p) != 0)
168 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
169 if (p->protocol == DNS_PROTOCOL_LLMNR &&
170 DNS_PACKET_QDCOUNT(p) != 1)
176 int dns_packet_validate_query(DnsPacket *p) {
181 r = dns_packet_validate(p);
185 if (DNS_PACKET_QR(p) != 0)
188 if (DNS_PACKET_OPCODE(p) != 0)
191 if (DNS_PACKET_TC(p))
194 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
195 if (p->protocol == DNS_PROTOCOL_LLMNR &&
196 DNS_PACKET_QDCOUNT(p) != 1)
199 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
200 if (DNS_PACKET_ANCOUNT(p) > 0)
203 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
204 if (DNS_PACKET_NSCOUNT(p) > 0)
210 static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
213 if (p->size + add > p->allocated) {
216 a = PAGE_ALIGN((p->size + add) * 2);
217 if (a > DNS_PACKET_SIZE_MAX)
218 a = DNS_PACKET_SIZE_MAX;
220 if (p->size + add > a)
226 d = realloc(p->_data, a);
232 p->_data = malloc(a);
236 memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
237 memzero((uint8_t*) p->_data + p->size, a - p->size);
247 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;
253 static void dns_packet_truncate(DnsPacket *p, size_t sz) {
263 HASHMAP_FOREACH_KEY(s, n, p->names, i) {
265 if (PTR_TO_SIZE(n) < sz)
268 hashmap_remove(p->names, s);
275 int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
281 r = dns_packet_extend(p, l, &q, start);
289 int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
295 r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
299 ((uint8_t*) d)[0] = v;
304 int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
310 r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
314 ((uint8_t*) d)[0] = (uint8_t) (v >> 8);
315 ((uint8_t*) d)[1] = (uint8_t) 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 ((uint8_t*) d)[0] = (uint8_t) (v >> 24);
331 ((uint8_t*) d)[1] = (uint8_t) (v >> 16);
332 ((uint8_t*) d)[2] = (uint8_t) (v >> 8);
333 ((uint8_t*) d)[3] = (uint8_t) v;
338 int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
350 r = dns_packet_extend(p, 1 + l, &d, start);
354 ((uint8_t*) d)[0] = (uint8_t) l;
355 memcpy(((uint8_t*) d) + 1, s, l);
360 int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start) {
367 if (l > DNS_LABEL_MAX)
370 r = dns_packet_extend(p, 1 + l, &w, start);
374 ((uint8_t*) w)[0] = (uint8_t) l;
375 memcpy(((uint8_t*) w) + 1, d, l);
380 int dns_packet_append_name(DnsPacket *p, const char *name,
381 bool allow_compression, size_t *start) {
388 saved_size = p->size;
391 _cleanup_free_ char *s = NULL;
392 char label[DNS_LABEL_MAX];
396 if (allow_compression)
397 n = PTR_TO_SIZE(hashmap_get(p->names, name));
402 r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
416 r = dns_label_unescape(&name, label, sizeof(label));
420 if (p->protocol == DNS_PROTOCOL_DNS)
421 k = dns_label_apply_idna(label, r, label, sizeof(label));
423 k = dns_label_undo_idna(label, r, label, sizeof(label));
431 r = dns_packet_append_label(p, label, r, &n);
435 if (allow_compression) {
436 r = hashmap_ensure_allocated(&p->names, &dns_name_hash_ops);
440 r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
448 r = dns_packet_append_uint8(p, 0, NULL);
459 dns_packet_truncate(p, saved_size);
463 int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
470 saved_size = p->size;
472 r = dns_packet_append_name(p, DNS_RESOURCE_KEY_NAME(k), true, NULL);
476 r = dns_packet_append_uint16(p, k->type, NULL);
480 r = dns_packet_append_uint16(p, k->class, NULL);
490 dns_packet_truncate(p, saved_size);
494 int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start) {
495 size_t saved_size, rdlength_offset, end, rdlength;
501 saved_size = p->size;
503 r = dns_packet_append_key(p, rr->key, NULL);
507 r = dns_packet_append_uint32(p, rr->ttl, NULL);
511 /* Initially we write 0 here */
512 r = dns_packet_append_uint16(p, 0, &rdlength_offset);
516 switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
519 r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
523 r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
527 r = dns_packet_append_uint16(p, rr->srv.port, NULL);
531 r = dns_packet_append_name(p, rr->srv.name, true, NULL);
538 r = dns_packet_append_name(p, rr->ptr.name, true, NULL);
542 r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
546 r = dns_packet_append_string(p, rr->hinfo.os, NULL);
549 case DNS_TYPE_SPF: /* exactly the same as TXT */
553 STRV_FOREACH(s, rr->txt.strings) {
554 r = dns_packet_append_string(p, *s, NULL);
564 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
568 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
572 r = dns_packet_append_name(p, rr->soa.mname, true, NULL);
576 r = dns_packet_append_name(p, rr->soa.rname, true, NULL);
580 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
584 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
588 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
592 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
596 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
600 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
604 r = dns_packet_append_name(p, rr->mx.exchange, true, NULL);
608 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
612 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
616 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
620 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
624 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
628 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
632 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
636 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
640 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
644 r = dns_packet_append_blob(p, rr->sshfp.key, rr->sshfp.key_size, NULL);
647 case DNS_TYPE_DNSKEY:
648 r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
652 r = dns_packet_append_uint8(p, 3u, NULL);
656 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
660 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
664 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
668 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
672 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
676 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
680 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
684 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
688 r = dns_packet_append_uint8(p, rr->rrsig.key_tag, NULL);
692 r = dns_packet_append_name(p, rr->rrsig.signer, false, NULL);
696 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
699 case _DNS_TYPE_INVALID: /* unparseable */
702 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
708 /* Let's calculate the actual data size and update the field */
709 rdlength = p->size - rdlength_offset - sizeof(uint16_t);
710 if (rdlength > 0xFFFF) {
716 p->size = rdlength_offset;
717 r = dns_packet_append_uint16(p, rdlength, NULL);
728 dns_packet_truncate(p, saved_size);
733 int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
736 if (p->rindex + sz > p->size)
740 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
749 void dns_packet_rewind(DnsPacket *p, size_t idx) {
751 assert(idx <= p->size);
752 assert(idx >= DNS_PACKET_HEADER_SIZE);
757 int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
764 r = dns_packet_read(p, sz, &q, start);
772 int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
778 r = dns_packet_read(p, sizeof(uint8_t), &d, start);
782 *ret = ((uint8_t*) d)[0];
786 int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
792 r = dns_packet_read(p, sizeof(uint16_t), &d, start);
796 *ret = (((uint16_t) ((uint8_t*) d)[0]) << 8) |
797 ((uint16_t) ((uint8_t*) d)[1]);
801 int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
807 r = dns_packet_read(p, sizeof(uint32_t), &d, start);
811 *ret = (((uint32_t) ((uint8_t*) d)[0]) << 24) |
812 (((uint32_t) ((uint8_t*) d)[1]) << 16) |
813 (((uint32_t) ((uint8_t*) d)[2]) << 8) |
814 ((uint32_t) ((uint8_t*) d)[3]);
819 int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
828 saved_rindex = p->rindex;
830 r = dns_packet_read_uint8(p, &c, NULL);
834 r = dns_packet_read(p, c, &d, NULL);
838 if (memchr(d, 0, c)) {
849 if (!utf8_is_valid(t)) {
858 *start = saved_rindex;
863 dns_packet_rewind(p, saved_rindex);
867 int dns_packet_read_name(DnsPacket *p, char **_ret,
868 bool allow_compression, size_t *start) {
869 size_t saved_rindex, after_rindex = 0;
870 _cleanup_free_ char *ret = NULL;
871 size_t n = 0, allocated = 0;
878 saved_rindex = p->rindex;
883 r = dns_packet_read_uint8(p, &c, NULL);
891 _cleanup_free_ char *t = NULL;
895 r = dns_packet_read(p, c, (const void**) &label, NULL);
899 r = dns_label_escape(label, c, &t);
903 if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) {
913 memcpy(ret + n, t, r);
916 } else if (allow_compression && (c & 0xc0) == 0xc0) {
920 r = dns_packet_read_uint8(p, &d, NULL);
924 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
925 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= saved_rindex) {
930 if (after_rindex == 0)
931 after_rindex = p->rindex;
938 if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
945 if (after_rindex != 0)
946 p->rindex= after_rindex;
952 *start = saved_rindex;
957 dns_packet_rewind(p, saved_rindex);
961 int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
962 _cleanup_free_ char *name = NULL;
963 uint16_t class, type;
971 saved_rindex = p->rindex;
973 r = dns_packet_read_name(p, &name, true, NULL);
977 r = dns_packet_read_uint16(p, &type, NULL);
981 r = dns_packet_read_uint16(p, &class, NULL);
985 key = dns_resource_key_new_consume(class, type, name);
995 *start = saved_rindex;
999 dns_packet_rewind(p, saved_rindex);
1003 static int dns_packet_read_public_key(DnsPacket *p, size_t length,
1004 void **dp, size_t *lengthp,
1010 r = dns_packet_read(p, length, &d, NULL);
1014 d2 = memdup(d, length);
1023 static bool loc_size_ok(uint8_t size) {
1024 uint8_t m = size >> 4, e = size & 0xF;
1026 return m <= 9 && e <= 9 && (m > 0 || e == 0);
1029 static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
1032 if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
1035 rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
1036 rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
1040 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
1041 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1042 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1043 size_t saved_rindex, offset;
1051 saved_rindex = p->rindex;
1053 r = dns_packet_read_key(p, &key, NULL);
1057 if (key->class == DNS_CLASS_ANY ||
1058 key->type == DNS_TYPE_ANY) {
1063 rr = dns_resource_record_new(key);
1069 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1073 r = dns_packet_read_uint16(p, &rdlength, NULL);
1077 if (p->rindex + rdlength > p->size) {
1084 switch (rr->key->type) {
1087 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1090 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1093 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1096 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
1101 case DNS_TYPE_CNAME:
1102 case DNS_TYPE_DNAME:
1103 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
1106 case DNS_TYPE_HINFO:
1107 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1111 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1114 case DNS_TYPE_SPF: /* exactly the same as TXT */
1115 case DNS_TYPE_TXT: {
1118 while (p->rindex < offset + rdlength) {
1119 r = dns_packet_read_string(p, &s, NULL);
1123 r = strv_consume(&rr->txt.strings, s);
1133 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1137 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1141 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
1145 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
1149 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1153 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1157 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1161 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1165 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1169 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1173 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
1176 case DNS_TYPE_LOC: {
1180 r = dns_packet_read_uint8(p, &t, &pos);
1185 rr->loc.version = t;
1187 r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1191 if (!loc_size_ok(rr->loc.size)) {
1196 r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1200 if (!loc_size_ok(rr->loc.horiz_pre)) {
1205 r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1209 if (!loc_size_ok(rr->loc.vert_pre)) {
1214 r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1218 r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1222 r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1228 dns_packet_rewind(p, pos);
1229 rr->unparseable = true;
1234 case DNS_TYPE_SSHFP:
1235 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1239 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1243 r = dns_packet_read_public_key(p, rdlength - 2,
1244 &rr->sshfp.key, &rr->sshfp.key_size,
1248 case DNS_TYPE_DNSKEY: {
1252 r = dns_packet_read_uint16(p, &flags, NULL);
1256 r = dnskey_parse_flags(rr, flags);
1260 r = dns_packet_read_uint8(p, &proto, NULL);
1264 /* protocol is required to be always 3 */
1270 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1274 r = dns_packet_read_public_key(p, rdlength - 4,
1275 &rr->dnskey.key, &rr->dnskey.key_size,
1280 case DNS_TYPE_RRSIG:
1281 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1285 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1289 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1293 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1297 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1301 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1305 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1309 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1313 r = dns_packet_read_public_key(p, offset + rdlength - p->rindex,
1314 &rr->rrsig.signature, &rr->rrsig.signature_size,
1320 r = dns_packet_read(p, rdlength, &d, NULL);
1324 rr->generic.data = memdup(d, rdlength);
1325 if (!rr->generic.data) {
1330 rr->generic.size = rdlength;
1335 if (p->rindex != offset + rdlength) {
1344 *start = saved_rindex;
1348 dns_packet_rewind(p, saved_rindex);
1352 int dns_packet_extract(DnsPacket *p) {
1353 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1354 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1355 size_t saved_rindex;
1362 saved_rindex = p->rindex;
1363 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1365 n = DNS_PACKET_QDCOUNT(p);
1367 question = dns_question_new(n);
1373 for (i = 0; i < n; i++) {
1374 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1376 r = dns_packet_read_key(p, &key, NULL);
1380 r = dns_question_add(question, key);
1386 n = DNS_PACKET_RRCOUNT(p);
1388 answer = dns_answer_new(n);
1394 for (i = 0; i < n; i++) {
1395 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1397 r = dns_packet_read_rr(p, &rr, NULL);
1401 r = dns_answer_add(answer, rr);
1407 p->question = question;
1413 p->extracted = true;
1418 p->rindex = saved_rindex;
1422 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
1423 [DNS_RCODE_SUCCESS] = "SUCCESS",
1424 [DNS_RCODE_FORMERR] = "FORMERR",
1425 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
1426 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
1427 [DNS_RCODE_NOTIMP] = "NOTIMP",
1428 [DNS_RCODE_REFUSED] = "REFUSED",
1429 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
1430 [DNS_RCODE_YXRRSET] = "YRRSET",
1431 [DNS_RCODE_NXRRSET] = "NXRRSET",
1432 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
1433 [DNS_RCODE_NOTZONE] = "NOTZONE",
1434 [DNS_RCODE_BADVERS] = "BADVERS",
1435 [DNS_RCODE_BADKEY] = "BADKEY",
1436 [DNS_RCODE_BADTIME] = "BADTIME",
1437 [DNS_RCODE_BADMODE] = "BADMODE",
1438 [DNS_RCODE_BADNAME] = "BADNAME",
1439 [DNS_RCODE_BADALG] = "BADALG",
1440 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
1442 DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1444 static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
1445 [DNS_PROTOCOL_DNS] = "dns",
1446 [DNS_PROTOCOL_MDNS] = "mdns",
1447 [DNS_PROTOCOL_LLMNR] = "llmnr",
1449 DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
1451 static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
1452 [DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
1453 [DNSSEC_ALGORITHM_DH] = "DH",
1454 [DNSSEC_ALGORITHM_DSA] = "DSA",
1455 [DNSSEC_ALGORITHM_ECC] = "ECC",
1456 [DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
1457 [DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
1458 [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
1459 [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
1461 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);