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 if (strv_isempty(rr->txt.strings)) {
551 /* RFC 6763, section 6.1 suggests to generate
552 * single empty string for an empty array. */
554 r = dns_packet_append_string(p, "", NULL);
558 STRV_FOREACH(s, rr->txt.strings) {
559 r = dns_packet_append_string(p, *s, NULL);
570 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
574 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
578 r = dns_packet_append_name(p, rr->soa.mname, true, NULL);
582 r = dns_packet_append_name(p, rr->soa.rname, true, NULL);
586 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
590 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
594 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
598 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
602 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
606 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
610 r = dns_packet_append_name(p, rr->mx.exchange, true, NULL);
614 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
618 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
622 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
626 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
630 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
634 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
638 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
642 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
646 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
650 r = dns_packet_append_blob(p, rr->sshfp.key, rr->sshfp.key_size, NULL);
653 case DNS_TYPE_DNSKEY:
654 r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
658 r = dns_packet_append_uint8(p, 3u, NULL);
662 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
666 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
670 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
674 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
678 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
682 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
686 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
690 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
694 r = dns_packet_append_uint8(p, rr->rrsig.key_tag, NULL);
698 r = dns_packet_append_name(p, rr->rrsig.signer, false, NULL);
702 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
705 case _DNS_TYPE_INVALID: /* unparseable */
708 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
714 /* Let's calculate the actual data size and update the field */
715 rdlength = p->size - rdlength_offset - sizeof(uint16_t);
716 if (rdlength > 0xFFFF) {
722 p->size = rdlength_offset;
723 r = dns_packet_append_uint16(p, rdlength, NULL);
734 dns_packet_truncate(p, saved_size);
739 int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
742 if (p->rindex + sz > p->size)
746 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
755 void dns_packet_rewind(DnsPacket *p, size_t idx) {
757 assert(idx <= p->size);
758 assert(idx >= DNS_PACKET_HEADER_SIZE);
763 int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
770 r = dns_packet_read(p, sz, &q, start);
778 int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
784 r = dns_packet_read(p, sizeof(uint8_t), &d, start);
788 *ret = ((uint8_t*) d)[0];
792 int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
798 r = dns_packet_read(p, sizeof(uint16_t), &d, start);
802 *ret = unaligned_read_be16(d);
807 int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
813 r = dns_packet_read(p, sizeof(uint32_t), &d, start);
817 *ret = unaligned_read_be32(d);
822 int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
831 saved_rindex = p->rindex;
833 r = dns_packet_read_uint8(p, &c, NULL);
837 r = dns_packet_read(p, c, &d, NULL);
841 if (memchr(d, 0, c)) {
852 if (!utf8_is_valid(t)) {
861 *start = saved_rindex;
866 dns_packet_rewind(p, saved_rindex);
870 int dns_packet_read_name(DnsPacket *p, char **_ret,
871 bool allow_compression, size_t *start) {
872 size_t saved_rindex, after_rindex = 0, jump_barrier;
873 _cleanup_free_ char *ret = NULL;
874 size_t n = 0, allocated = 0;
881 saved_rindex = p->rindex;
882 jump_barrier = p->rindex;
887 r = dns_packet_read_uint8(p, &c, NULL);
895 _cleanup_free_ char *t = NULL;
899 r = dns_packet_read(p, c, (const void**) &label, NULL);
903 r = dns_label_escape(label, c, &t);
907 if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) {
917 memcpy(ret + n, t, r);
920 } else if (allow_compression && (c & 0xc0) == 0xc0) {
924 r = dns_packet_read_uint8(p, &d, NULL);
928 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
929 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier) {
934 if (after_rindex == 0)
935 after_rindex = p->rindex;
937 /* Jumps are limited to a "prior occurence" (RFC-1035 4.1.4) */
946 if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
953 if (after_rindex != 0)
954 p->rindex= after_rindex;
960 *start = saved_rindex;
965 dns_packet_rewind(p, saved_rindex);
969 int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
970 _cleanup_free_ char *name = NULL;
971 uint16_t class, type;
979 saved_rindex = p->rindex;
981 r = dns_packet_read_name(p, &name, true, NULL);
985 r = dns_packet_read_uint16(p, &type, NULL);
989 r = dns_packet_read_uint16(p, &class, NULL);
993 key = dns_resource_key_new_consume(class, type, name);
1003 *start = saved_rindex;
1007 dns_packet_rewind(p, saved_rindex);
1011 static int dns_packet_read_public_key(DnsPacket *p, size_t length,
1012 void **dp, size_t *lengthp,
1018 r = dns_packet_read(p, length, &d, NULL);
1022 d2 = memdup(d, length);
1031 static bool loc_size_ok(uint8_t size) {
1032 uint8_t m = size >> 4, e = size & 0xF;
1034 return m <= 9 && e <= 9 && (m > 0 || e == 0);
1037 static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
1040 if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
1043 rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
1044 rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
1048 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
1049 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1050 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1051 size_t saved_rindex, offset;
1059 saved_rindex = p->rindex;
1061 r = dns_packet_read_key(p, &key, NULL);
1065 if (key->class == DNS_CLASS_ANY ||
1066 key->type == DNS_TYPE_ANY) {
1071 rr = dns_resource_record_new(key);
1077 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1081 r = dns_packet_read_uint16(p, &rdlength, NULL);
1085 if (p->rindex + rdlength > p->size) {
1092 switch (rr->key->type) {
1095 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1098 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1101 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1104 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
1109 case DNS_TYPE_CNAME:
1110 case DNS_TYPE_DNAME:
1111 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
1114 case DNS_TYPE_HINFO:
1115 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1119 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1122 case DNS_TYPE_SPF: /* exactly the same as TXT */
1124 if (rdlength <= 0) {
1125 /* RFC 6763, section 6.1 suggests to treat
1126 * empty TXT RRs as equivalent to a TXT record
1127 * with a single empty string. */
1129 r = strv_extend(&rr->txt.strings, "");
1133 while (p->rindex < offset + rdlength) {
1136 r = dns_packet_read_string(p, &s, NULL);
1140 r = strv_consume(&rr->txt.strings, s);
1150 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1154 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1158 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
1162 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
1166 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1170 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1174 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1178 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1182 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1186 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1190 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
1193 case DNS_TYPE_LOC: {
1197 r = dns_packet_read_uint8(p, &t, &pos);
1202 rr->loc.version = t;
1204 r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1208 if (!loc_size_ok(rr->loc.size)) {
1213 r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1217 if (!loc_size_ok(rr->loc.horiz_pre)) {
1222 r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1226 if (!loc_size_ok(rr->loc.vert_pre)) {
1231 r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1235 r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1239 r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1245 dns_packet_rewind(p, pos);
1246 rr->unparseable = true;
1251 case DNS_TYPE_SSHFP:
1252 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1256 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1260 r = dns_packet_read_public_key(p, rdlength - 2,
1261 &rr->sshfp.key, &rr->sshfp.key_size,
1265 case DNS_TYPE_DNSKEY: {
1269 r = dns_packet_read_uint16(p, &flags, NULL);
1273 r = dnskey_parse_flags(rr, flags);
1277 r = dns_packet_read_uint8(p, &proto, NULL);
1281 /* protocol is required to be always 3 */
1287 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1291 r = dns_packet_read_public_key(p, rdlength - 4,
1292 &rr->dnskey.key, &rr->dnskey.key_size,
1297 case DNS_TYPE_RRSIG:
1298 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1302 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1306 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1310 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1314 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1318 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1322 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1326 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1330 r = dns_packet_read_public_key(p, offset + rdlength - p->rindex,
1331 &rr->rrsig.signature, &rr->rrsig.signature_size,
1337 r = dns_packet_read(p, rdlength, &d, NULL);
1341 rr->generic.data = memdup(d, rdlength);
1342 if (!rr->generic.data) {
1347 rr->generic.size = rdlength;
1352 if (p->rindex != offset + rdlength) {
1361 *start = saved_rindex;
1365 dns_packet_rewind(p, saved_rindex);
1369 int dns_packet_extract(DnsPacket *p) {
1370 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1371 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1372 size_t saved_rindex;
1379 saved_rindex = p->rindex;
1380 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1382 n = DNS_PACKET_QDCOUNT(p);
1384 question = dns_question_new(n);
1390 for (i = 0; i < n; i++) {
1391 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1393 r = dns_packet_read_key(p, &key, NULL);
1397 r = dns_question_add(question, key);
1403 n = DNS_PACKET_RRCOUNT(p);
1405 answer = dns_answer_new(n);
1411 for (i = 0; i < n; i++) {
1412 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1414 r = dns_packet_read_rr(p, &rr, NULL);
1418 r = dns_answer_add(answer, rr);
1424 p->question = question;
1430 p->extracted = true;
1435 p->rindex = saved_rindex;
1439 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
1440 [DNS_RCODE_SUCCESS] = "SUCCESS",
1441 [DNS_RCODE_FORMERR] = "FORMERR",
1442 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
1443 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
1444 [DNS_RCODE_NOTIMP] = "NOTIMP",
1445 [DNS_RCODE_REFUSED] = "REFUSED",
1446 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
1447 [DNS_RCODE_YXRRSET] = "YRRSET",
1448 [DNS_RCODE_NXRRSET] = "NXRRSET",
1449 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
1450 [DNS_RCODE_NOTZONE] = "NOTZONE",
1451 [DNS_RCODE_BADVERS] = "BADVERS",
1452 [DNS_RCODE_BADKEY] = "BADKEY",
1453 [DNS_RCODE_BADTIME] = "BADTIME",
1454 [DNS_RCODE_BADMODE] = "BADMODE",
1455 [DNS_RCODE_BADNAME] = "BADNAME",
1456 [DNS_RCODE_BADALG] = "BADALG",
1457 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
1459 DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1461 static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
1462 [DNS_PROTOCOL_DNS] = "dns",
1463 [DNS_PROTOCOL_MDNS] = "mdns",
1464 [DNS_PROTOCOL_LLMNR] = "llmnr",
1466 DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
1468 static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
1469 [DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
1470 [DNSSEC_ALGORITHM_DH] = "DH",
1471 [DNSSEC_ALGORITHM_DSA] = "DSA",
1472 [DNSSEC_ALGORITHM_ECC] = "ECC",
1473 [DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
1474 [DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
1475 [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
1476 [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
1478 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);