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/>.
22 #include "alloc-util.h"
23 #include "dns-domain.h"
24 #include "resolved-dns-packet.h"
25 #include "string-table.h"
27 #include "unaligned.h"
31 #define EDNS0_OPT_DO (1<<15)
33 int dns_packet_new(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
39 if (mtu
<= UDP_PACKET_HEADER_SIZE
)
40 a
= DNS_PACKET_SIZE_START
;
42 a
= mtu
- UDP_PACKET_HEADER_SIZE
;
44 if (a
< DNS_PACKET_HEADER_SIZE
)
45 a
= DNS_PACKET_HEADER_SIZE
;
47 /* round up to next page size */
48 a
= PAGE_ALIGN(ALIGN(sizeof(DnsPacket
)) + a
) - ALIGN(sizeof(DnsPacket
));
50 /* make sure we never allocate more than useful */
51 if (a
> DNS_PACKET_SIZE_MAX
)
52 a
= DNS_PACKET_SIZE_MAX
;
54 p
= malloc0(ALIGN(sizeof(DnsPacket
)) + a
);
58 p
->size
= p
->rindex
= DNS_PACKET_HEADER_SIZE
;
60 p
->protocol
= protocol
;
61 p
->opt_start
= p
->opt_size
= (size_t) -1;
69 void dns_packet_set_flags(DnsPacket
*p
, bool dnssec_checking_disabled
, bool truncated
) {
75 h
= DNS_PACKET_HEADER(p
);
78 case DNS_PROTOCOL_LLMNR
:
81 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
92 case DNS_PROTOCOL_MDNS
:
93 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
97 0 /* rd (ask for recursion) */,
107 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
111 1 /* rd (ask for recursion) */,
114 dnssec_checking_disabled
/* cd */,
119 int dns_packet_new_query(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
, bool dnssec_checking_disabled
) {
125 r
= dns_packet_new(&p
, protocol
, mtu
);
129 /* Always set the TC bit to 0 initially.
130 * If there are multiple packets later, we'll update the bit shortly before sending.
132 dns_packet_set_flags(p
, dnssec_checking_disabled
, false);
138 DnsPacket
*dns_packet_ref(DnsPacket
*p
) {
143 assert(!p
->on_stack
);
145 assert(p
->n_ref
> 0);
150 static void dns_packet_free(DnsPacket
*p
) {
155 dns_question_unref(p
->question
);
156 dns_answer_unref(p
->answer
);
157 dns_resource_record_unref(p
->opt
);
159 while ((s
= hashmap_steal_first_key(p
->names
)))
161 hashmap_free(p
->names
);
169 DnsPacket
*dns_packet_unref(DnsPacket
*p
) {
173 assert(p
->n_ref
> 0);
175 dns_packet_unref(p
->more
);
185 int dns_packet_validate(DnsPacket
*p
) {
188 if (p
->size
< DNS_PACKET_HEADER_SIZE
)
191 if (p
->size
> DNS_PACKET_SIZE_MAX
)
197 int dns_packet_validate_reply(DnsPacket
*p
) {
202 r
= dns_packet_validate(p
);
206 if (DNS_PACKET_QR(p
) != 1)
209 if (DNS_PACKET_OPCODE(p
) != 0)
212 switch (p
->protocol
) {
214 case DNS_PROTOCOL_LLMNR
:
215 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
216 if (DNS_PACKET_QDCOUNT(p
) != 1)
221 case DNS_PROTOCOL_MDNS
:
222 /* RFC 6762, Section 18 */
223 if (DNS_PACKET_RCODE(p
) != 0)
235 int dns_packet_validate_query(DnsPacket
*p
) {
240 r
= dns_packet_validate(p
);
244 if (DNS_PACKET_QR(p
) != 0)
247 if (DNS_PACKET_OPCODE(p
) != 0)
250 if (DNS_PACKET_TC(p
))
253 switch (p
->protocol
) {
255 case DNS_PROTOCOL_LLMNR
:
256 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
257 if (DNS_PACKET_QDCOUNT(p
) != 1)
260 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
261 if (DNS_PACKET_ANCOUNT(p
) > 0)
264 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
265 if (DNS_PACKET_NSCOUNT(p
) > 0)
270 case DNS_PROTOCOL_MDNS
:
271 /* RFC 6762, Section 18 */
272 if (DNS_PACKET_AA(p
) != 0 ||
273 DNS_PACKET_RD(p
) != 0 ||
274 DNS_PACKET_RA(p
) != 0 ||
275 DNS_PACKET_AD(p
) != 0 ||
276 DNS_PACKET_CD(p
) != 0 ||
277 DNS_PACKET_RCODE(p
) != 0)
289 static int dns_packet_extend(DnsPacket
*p
, size_t add
, void **ret
, size_t *start
) {
292 if (p
->size
+ add
> p
->allocated
) {
295 a
= PAGE_ALIGN((p
->size
+ add
) * 2);
296 if (a
> DNS_PACKET_SIZE_MAX
)
297 a
= DNS_PACKET_SIZE_MAX
;
299 if (p
->size
+ add
> a
)
305 d
= realloc(p
->_data
, a
);
311 p
->_data
= malloc(a
);
315 memcpy(p
->_data
, (uint8_t*) p
+ ALIGN(sizeof(DnsPacket
)), p
->size
);
316 memzero((uint8_t*) p
->_data
+ p
->size
, a
- p
->size
);
326 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->size
;
332 void dns_packet_truncate(DnsPacket
*p
, size_t sz
) {
342 HASHMAP_FOREACH_KEY(n
, s
, p
->names
, i
) {
344 if (PTR_TO_SIZE(n
) < sz
)
347 hashmap_remove(p
->names
, s
);
354 int dns_packet_append_blob(DnsPacket
*p
, const void *d
, size_t l
, size_t *start
) {
360 r
= dns_packet_extend(p
, l
, &q
, start
);
368 int dns_packet_append_uint8(DnsPacket
*p
, uint8_t v
, size_t *start
) {
374 r
= dns_packet_extend(p
, sizeof(uint8_t), &d
, start
);
378 ((uint8_t*) d
)[0] = v
;
383 int dns_packet_append_uint16(DnsPacket
*p
, uint16_t v
, size_t *start
) {
389 r
= dns_packet_extend(p
, sizeof(uint16_t), &d
, start
);
393 unaligned_write_be16(d
, v
);
398 int dns_packet_append_uint32(DnsPacket
*p
, uint32_t v
, size_t *start
) {
404 r
= dns_packet_extend(p
, sizeof(uint32_t), &d
, start
);
408 unaligned_write_be32(d
, v
);
413 int dns_packet_append_string(DnsPacket
*p
, const char *s
, size_t *start
) {
417 return dns_packet_append_raw_string(p
, s
, strlen(s
), start
);
420 int dns_packet_append_raw_string(DnsPacket
*p
, const void *s
, size_t size
, size_t *start
) {
425 assert(s
|| size
== 0);
430 r
= dns_packet_extend(p
, 1 + size
, &d
, start
);
434 ((uint8_t*) d
)[0] = (uint8_t) size
;
437 memcpy(((uint8_t*) d
) + 1, s
, size
);
442 int dns_packet_append_label(DnsPacket
*p
, const char *d
, size_t l
, bool canonical_candidate
, size_t *start
) {
446 /* Append a label to a packet. Optionally, does this in DNSSEC
447 * canonical form, if this label is marked as a candidate for
448 * it, and the canonical form logic is enabled for the
454 if (l
> DNS_LABEL_MAX
)
457 r
= dns_packet_extend(p
, 1 + l
, (void**) &w
, start
);
461 *(w
++) = (uint8_t) l
;
463 if (p
->canonical_form
&& canonical_candidate
) {
466 /* Generate in canonical form, as defined by DNSSEC
467 * RFC 4034, Section 6.2, i.e. all lower-case. */
469 for (i
= 0; i
< l
; i
++)
470 w
[i
] = (uint8_t) ascii_tolower(d
[i
]);
472 /* Otherwise, just copy the string unaltered. This is
473 * essential for DNS-SD, where the casing of labels
474 * matters and needs to be retained. */
480 int dns_packet_append_name(
483 bool allow_compression
,
484 bool canonical_candidate
,
493 if (p
->refuse_compression
)
494 allow_compression
= false;
496 saved_size
= p
->size
;
498 while (!dns_name_is_root(name
)) {
499 const char *z
= name
;
500 char label
[DNS_LABEL_MAX
];
503 if (allow_compression
)
504 n
= PTR_TO_SIZE(hashmap_get(p
->names
, name
));
509 r
= dns_packet_append_uint16(p
, 0xC000 | n
, NULL
);
517 r
= dns_label_unescape(&name
, label
, sizeof(label
));
521 r
= dns_packet_append_label(p
, label
, r
, canonical_candidate
, &n
);
525 if (allow_compression
) {
526 _cleanup_free_
char *s
= NULL
;
534 r
= hashmap_ensure_allocated(&p
->names
, &dns_name_hash_ops
);
538 r
= hashmap_put(p
->names
, s
, SIZE_TO_PTR(n
));
546 r
= dns_packet_append_uint8(p
, 0, NULL
);
557 dns_packet_truncate(p
, saved_size
);
561 int dns_packet_append_key(DnsPacket
*p
, const DnsResourceKey
*k
, size_t *start
) {
568 saved_size
= p
->size
;
570 r
= dns_packet_append_name(p
, DNS_RESOURCE_KEY_NAME(k
), true, true, NULL
);
574 r
= dns_packet_append_uint16(p
, k
->type
, NULL
);
578 r
= dns_packet_append_uint16(p
, k
->class, NULL
);
588 dns_packet_truncate(p
, saved_size
);
592 static int dns_packet_append_type_window(DnsPacket
*p
, uint8_t window
, uint8_t length
, const uint8_t *types
, size_t *start
) {
600 saved_size
= p
->size
;
602 r
= dns_packet_append_uint8(p
, window
, NULL
);
606 r
= dns_packet_append_uint8(p
, length
, NULL
);
610 r
= dns_packet_append_blob(p
, types
, length
, NULL
);
619 dns_packet_truncate(p
, saved_size
);
623 static int dns_packet_append_types(DnsPacket
*p
, Bitmap
*types
, size_t *start
) {
627 uint8_t bitmaps
[32] = {};
634 saved_size
= p
->size
;
636 BITMAP_FOREACH(n
, types
, i
) {
639 if ((n
>> 8) != window
&& bitmaps
[entry
/ 8] != 0) {
640 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
650 bitmaps
[entry
/ 8] |= 1 << (7 - (entry
% 8));
653 if (bitmaps
[entry
/ 8] != 0) {
654 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
664 dns_packet_truncate(p
, saved_size
);
668 /* Append the OPT pseudo-RR described in RFC6891 */
669 int dns_packet_append_opt(DnsPacket
*p
, uint16_t max_udp_size
, bool edns0_do
, size_t *start
) {
674 /* we must never advertise supported packet size smaller than the legacy max */
675 assert(max_udp_size
>= DNS_PACKET_UNICAST_SIZE_MAX
);
677 if (p
->opt_start
!= (size_t) -1)
680 assert(p
->opt_size
== (size_t) -1);
682 saved_size
= p
->size
;
685 r
= dns_packet_append_uint8(p
, 0, NULL
);
690 r
= dns_packet_append_uint16(p
, DNS_TYPE_OPT
, NULL
);
694 /* maximum udp packet that can be received */
695 r
= dns_packet_append_uint16(p
, max_udp_size
, NULL
);
699 /* extended RCODE and VERSION */
700 r
= dns_packet_append_uint16(p
, 0, NULL
);
704 /* flags: DNSSEC OK (DO), see RFC3225 */
705 r
= dns_packet_append_uint16(p
, edns0_do
? EDNS0_OPT_DO
: 0, NULL
);
712 /* If DO is on, also append RFC6975 Algorithm data */
714 static const uint8_t rfc6975
[] = {
716 0, 5, /* OPTION_CODE: DAU */
717 0, 6, /* LIST_LENGTH */
718 DNSSEC_ALGORITHM_RSASHA1
,
719 DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1
,
720 DNSSEC_ALGORITHM_RSASHA256
,
721 DNSSEC_ALGORITHM_RSASHA512
,
722 DNSSEC_ALGORITHM_ECDSAP256SHA256
,
723 DNSSEC_ALGORITHM_ECDSAP384SHA384
,
725 0, 6, /* OPTION_CODE: DHU */
726 0, 3, /* LIST_LENGTH */
728 DNSSEC_DIGEST_SHA256
,
729 DNSSEC_DIGEST_SHA384
,
731 0, 7, /* OPTION_CODE: N3U */
732 0, 1, /* LIST_LENGTH */
733 NSEC3_ALGORITHM_SHA1
,
736 r
= dns_packet_append_uint16(p
, sizeof(rfc6975
), NULL
);
740 r
= dns_packet_append_blob(p
, rfc6975
, sizeof(rfc6975
), NULL
);
742 r
= dns_packet_append_uint16(p
, 0, NULL
);
747 DNS_PACKET_HEADER(p
)->arcount
= htobe16(DNS_PACKET_ARCOUNT(p
) + 1);
749 p
->opt_start
= saved_size
;
750 p
->opt_size
= p
->size
- saved_size
;
758 dns_packet_truncate(p
, saved_size
);
762 int dns_packet_truncate_opt(DnsPacket
*p
) {
765 if (p
->opt_start
== (size_t) -1) {
766 assert(p
->opt_size
== (size_t) -1);
770 assert(p
->opt_size
!= (size_t) -1);
771 assert(DNS_PACKET_ARCOUNT(p
) > 0);
773 if (p
->opt_start
+ p
->opt_size
!= p
->size
)
776 dns_packet_truncate(p
, p
->opt_start
);
777 DNS_PACKET_HEADER(p
)->arcount
= htobe16(DNS_PACKET_ARCOUNT(p
) - 1);
778 p
->opt_start
= p
->opt_size
= (size_t) -1;
783 int dns_packet_append_rr(DnsPacket
*p
, const DnsResourceRecord
*rr
, size_t *start
, size_t *rdata_start
) {
784 size_t saved_size
, rdlength_offset
, end
, rdlength
, rds
;
790 saved_size
= p
->size
;
792 r
= dns_packet_append_key(p
, rr
->key
, NULL
);
796 r
= dns_packet_append_uint32(p
, rr
->ttl
, NULL
);
800 /* Initially we write 0 here */
801 r
= dns_packet_append_uint16(p
, 0, &rdlength_offset
);
805 rds
= p
->size
- saved_size
;
807 switch (rr
->unparseable
? _DNS_TYPE_INVALID
: rr
->key
->type
) {
810 r
= dns_packet_append_uint16(p
, rr
->srv
.priority
, NULL
);
814 r
= dns_packet_append_uint16(p
, rr
->srv
.weight
, NULL
);
818 r
= dns_packet_append_uint16(p
, rr
->srv
.port
, NULL
);
822 r
= dns_packet_append_name(p
, rr
->srv
.name
, true, false, NULL
);
829 r
= dns_packet_append_name(p
, rr
->ptr
.name
, true, false, NULL
);
833 r
= dns_packet_append_string(p
, rr
->hinfo
.cpu
, NULL
);
837 r
= dns_packet_append_string(p
, rr
->hinfo
.os
, NULL
);
840 case DNS_TYPE_SPF
: /* exactly the same as TXT */
843 if (!rr
->txt
.items
) {
844 /* RFC 6763, section 6.1 suggests to generate
845 * single empty string for an empty array. */
847 r
= dns_packet_append_raw_string(p
, NULL
, 0, NULL
);
853 LIST_FOREACH(items
, i
, rr
->txt
.items
) {
854 r
= dns_packet_append_raw_string(p
, i
->data
, i
->length
, NULL
);
864 r
= dns_packet_append_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
868 r
= dns_packet_append_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
872 r
= dns_packet_append_name(p
, rr
->soa
.mname
, true, false, NULL
);
876 r
= dns_packet_append_name(p
, rr
->soa
.rname
, true, false, NULL
);
880 r
= dns_packet_append_uint32(p
, rr
->soa
.serial
, NULL
);
884 r
= dns_packet_append_uint32(p
, rr
->soa
.refresh
, NULL
);
888 r
= dns_packet_append_uint32(p
, rr
->soa
.retry
, NULL
);
892 r
= dns_packet_append_uint32(p
, rr
->soa
.expire
, NULL
);
896 r
= dns_packet_append_uint32(p
, rr
->soa
.minimum
, NULL
);
900 r
= dns_packet_append_uint16(p
, rr
->mx
.priority
, NULL
);
904 r
= dns_packet_append_name(p
, rr
->mx
.exchange
, true, false, NULL
);
908 r
= dns_packet_append_uint8(p
, rr
->loc
.version
, NULL
);
912 r
= dns_packet_append_uint8(p
, rr
->loc
.size
, NULL
);
916 r
= dns_packet_append_uint8(p
, rr
->loc
.horiz_pre
, NULL
);
920 r
= dns_packet_append_uint8(p
, rr
->loc
.vert_pre
, NULL
);
924 r
= dns_packet_append_uint32(p
, rr
->loc
.latitude
, NULL
);
928 r
= dns_packet_append_uint32(p
, rr
->loc
.longitude
, NULL
);
932 r
= dns_packet_append_uint32(p
, rr
->loc
.altitude
, NULL
);
936 r
= dns_packet_append_uint16(p
, rr
->ds
.key_tag
, NULL
);
940 r
= dns_packet_append_uint8(p
, rr
->ds
.algorithm
, NULL
);
944 r
= dns_packet_append_uint8(p
, rr
->ds
.digest_type
, NULL
);
948 r
= dns_packet_append_blob(p
, rr
->ds
.digest
, rr
->ds
.digest_size
, NULL
);
952 r
= dns_packet_append_uint8(p
, rr
->sshfp
.algorithm
, NULL
);
956 r
= dns_packet_append_uint8(p
, rr
->sshfp
.fptype
, NULL
);
960 r
= dns_packet_append_blob(p
, rr
->sshfp
.fingerprint
, rr
->sshfp
.fingerprint_size
, NULL
);
963 case DNS_TYPE_DNSKEY
:
964 r
= dns_packet_append_uint16(p
, rr
->dnskey
.flags
, NULL
);
968 r
= dns_packet_append_uint8(p
, rr
->dnskey
.protocol
, NULL
);
972 r
= dns_packet_append_uint8(p
, rr
->dnskey
.algorithm
, NULL
);
976 r
= dns_packet_append_blob(p
, rr
->dnskey
.key
, rr
->dnskey
.key_size
, NULL
);
980 r
= dns_packet_append_uint16(p
, rr
->rrsig
.type_covered
, NULL
);
984 r
= dns_packet_append_uint8(p
, rr
->rrsig
.algorithm
, NULL
);
988 r
= dns_packet_append_uint8(p
, rr
->rrsig
.labels
, NULL
);
992 r
= dns_packet_append_uint32(p
, rr
->rrsig
.original_ttl
, NULL
);
996 r
= dns_packet_append_uint32(p
, rr
->rrsig
.expiration
, NULL
);
1000 r
= dns_packet_append_uint32(p
, rr
->rrsig
.inception
, NULL
);
1004 r
= dns_packet_append_uint16(p
, rr
->rrsig
.key_tag
, NULL
);
1008 r
= dns_packet_append_name(p
, rr
->rrsig
.signer
, false, true, NULL
);
1012 r
= dns_packet_append_blob(p
, rr
->rrsig
.signature
, rr
->rrsig
.signature_size
, NULL
);
1016 r
= dns_packet_append_name(p
, rr
->nsec
.next_domain_name
, false, false, NULL
);
1020 r
= dns_packet_append_types(p
, rr
->nsec
.types
, NULL
);
1026 case DNS_TYPE_NSEC3
:
1027 r
= dns_packet_append_uint8(p
, rr
->nsec3
.algorithm
, NULL
);
1031 r
= dns_packet_append_uint8(p
, rr
->nsec3
.flags
, NULL
);
1035 r
= dns_packet_append_uint16(p
, rr
->nsec3
.iterations
, NULL
);
1039 r
= dns_packet_append_uint8(p
, rr
->nsec3
.salt_size
, NULL
);
1043 r
= dns_packet_append_blob(p
, rr
->nsec3
.salt
, rr
->nsec3
.salt_size
, NULL
);
1047 r
= dns_packet_append_uint8(p
, rr
->nsec3
.next_hashed_name_size
, NULL
);
1051 r
= dns_packet_append_blob(p
, rr
->nsec3
.next_hashed_name
, rr
->nsec3
.next_hashed_name_size
, NULL
);
1055 r
= dns_packet_append_types(p
, rr
->nsec3
.types
, NULL
);
1062 r
= dns_packet_append_uint8(p
, rr
->tlsa
.cert_usage
, NULL
);
1066 r
= dns_packet_append_uint8(p
, rr
->tlsa
.selector
, NULL
);
1070 r
= dns_packet_append_uint8(p
, rr
->tlsa
.matching_type
, NULL
);
1074 r
= dns_packet_append_blob(p
, rr
->tlsa
.data
, rr
->tlsa
.data_size
, NULL
);
1078 case DNS_TYPE_OPENPGPKEY
:
1079 case _DNS_TYPE_INVALID
: /* unparseable */
1082 r
= dns_packet_append_blob(p
, rr
->generic
.data
, rr
->generic
.data_size
, NULL
);
1088 /* Let's calculate the actual data size and update the field */
1089 rdlength
= p
->size
- rdlength_offset
- sizeof(uint16_t);
1090 if (rdlength
> 0xFFFF) {
1096 p
->size
= rdlength_offset
;
1097 r
= dns_packet_append_uint16(p
, rdlength
, NULL
);
1103 *start
= saved_size
;
1111 dns_packet_truncate(p
, saved_size
);
1115 int dns_packet_read(DnsPacket
*p
, size_t sz
, const void **ret
, size_t *start
) {
1118 if (p
->rindex
+ sz
> p
->size
)
1122 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->rindex
;
1131 void dns_packet_rewind(DnsPacket
*p
, size_t idx
) {
1133 assert(idx
<= p
->size
);
1134 assert(idx
>= DNS_PACKET_HEADER_SIZE
);
1139 int dns_packet_read_blob(DnsPacket
*p
, void *d
, size_t sz
, size_t *start
) {
1146 r
= dns_packet_read(p
, sz
, &q
, start
);
1154 static int dns_packet_read_memdup(
1155 DnsPacket
*p
, size_t size
,
1156 void **ret
, size_t *ret_size
,
1157 size_t *ret_start
) {
1166 r
= dns_packet_read(p
, size
, &src
, &start
);
1175 copy
= memdup(src
, size
);
1190 int dns_packet_read_uint8(DnsPacket
*p
, uint8_t *ret
, size_t *start
) {
1196 r
= dns_packet_read(p
, sizeof(uint8_t), &d
, start
);
1200 *ret
= ((uint8_t*) d
)[0];
1204 int dns_packet_read_uint16(DnsPacket
*p
, uint16_t *ret
, size_t *start
) {
1210 r
= dns_packet_read(p
, sizeof(uint16_t), &d
, start
);
1214 *ret
= unaligned_read_be16(d
);
1219 int dns_packet_read_uint32(DnsPacket
*p
, uint32_t *ret
, size_t *start
) {
1225 r
= dns_packet_read(p
, sizeof(uint32_t), &d
, start
);
1229 *ret
= unaligned_read_be32(d
);
1234 int dns_packet_read_string(DnsPacket
*p
, char **ret
, size_t *start
) {
1235 size_t saved_rindex
;
1243 saved_rindex
= p
->rindex
;
1245 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1249 r
= dns_packet_read(p
, c
, &d
, NULL
);
1253 if (memchr(d
, 0, c
)) {
1264 if (!utf8_is_valid(t
)) {
1273 *start
= saved_rindex
;
1278 dns_packet_rewind(p
, saved_rindex
);
1282 int dns_packet_read_raw_string(DnsPacket
*p
, const void **ret
, size_t *size
, size_t *start
) {
1283 size_t saved_rindex
;
1289 saved_rindex
= p
->rindex
;
1291 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1295 r
= dns_packet_read(p
, c
, ret
, NULL
);
1302 *start
= saved_rindex
;
1307 dns_packet_rewind(p
, saved_rindex
);
1311 int dns_packet_read_name(
1314 bool allow_compression
,
1317 size_t saved_rindex
, after_rindex
= 0, jump_barrier
;
1318 _cleanup_free_
char *ret
= NULL
;
1319 size_t n
= 0, allocated
= 0;
1326 if (p
->refuse_compression
)
1327 allow_compression
= false;
1329 saved_rindex
= p
->rindex
;
1330 jump_barrier
= p
->rindex
;
1335 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1346 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
1350 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ DNS_LABEL_ESCAPED_MAX
)) {
1360 r
= dns_label_escape(label
, c
, ret
+ n
, DNS_LABEL_ESCAPED_MAX
);
1366 } else if (allow_compression
&& (c
& 0xc0) == 0xc0) {
1370 r
= dns_packet_read_uint8(p
, &d
, NULL
);
1374 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
1375 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= jump_barrier
) {
1380 if (after_rindex
== 0)
1381 after_rindex
= p
->rindex
;
1383 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1392 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1)) {
1399 if (after_rindex
!= 0)
1400 p
->rindex
= after_rindex
;
1406 *start
= saved_rindex
;
1411 dns_packet_rewind(p
, saved_rindex
);
1415 static int dns_packet_read_type_window(DnsPacket
*p
, Bitmap
**types
, size_t *start
) {
1418 const uint8_t *bitmap
;
1422 size_t saved_rindex
;
1428 saved_rindex
= p
->rindex
;
1430 r
= bitmap_ensure_allocated(types
);
1434 r
= dns_packet_read_uint8(p
, &window
, NULL
);
1438 r
= dns_packet_read_uint8(p
, &length
, NULL
);
1442 if (length
== 0 || length
> 32)
1445 r
= dns_packet_read(p
, length
, (const void **)&bitmap
, NULL
);
1449 for (i
= 0; i
< length
; i
++) {
1450 uint8_t bitmask
= 1 << 7;
1461 if (bitmap
[i
] & bitmask
) {
1464 n
= (uint16_t) window
<< 8 | (uint16_t) bit
;
1466 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1467 if (dns_type_is_pseudo(n
))
1470 r
= bitmap_set(*types
, n
);
1484 *start
= saved_rindex
;
1488 dns_packet_rewind(p
, saved_rindex
);
1492 static int dns_packet_read_type_windows(DnsPacket
*p
, Bitmap
**types
, size_t size
, size_t *start
) {
1493 size_t saved_rindex
;
1496 saved_rindex
= p
->rindex
;
1498 while (p
->rindex
< saved_rindex
+ size
) {
1499 r
= dns_packet_read_type_window(p
, types
, NULL
);
1503 /* don't read past end of current RR */
1504 if (p
->rindex
> saved_rindex
+ size
) {
1510 if (p
->rindex
!= saved_rindex
+ size
) {
1516 *start
= saved_rindex
;
1520 dns_packet_rewind(p
, saved_rindex
);
1524 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, bool *ret_cache_flush
, size_t *start
) {
1525 _cleanup_free_
char *name
= NULL
;
1526 bool cache_flush
= false;
1527 uint16_t class, type
;
1528 DnsResourceKey
*key
;
1529 size_t saved_rindex
;
1535 saved_rindex
= p
->rindex
;
1537 r
= dns_packet_read_name(p
, &name
, true, NULL
);
1541 r
= dns_packet_read_uint16(p
, &type
, NULL
);
1545 r
= dns_packet_read_uint16(p
, &class, NULL
);
1549 if (p
->protocol
== DNS_PROTOCOL_MDNS
) {
1550 /* See RFC6762, Section 10.2 */
1552 if (type
!= DNS_TYPE_OPT
&& (class & MDNS_RR_CACHE_FLUSH
)) {
1553 class &= ~MDNS_RR_CACHE_FLUSH
;
1558 key
= dns_resource_key_new_consume(class, type
, name
);
1567 if (ret_cache_flush
)
1568 *ret_cache_flush
= cache_flush
;
1570 *start
= saved_rindex
;
1574 dns_packet_rewind(p
, saved_rindex
);
1578 static bool loc_size_ok(uint8_t size
) {
1579 uint8_t m
= size
>> 4, e
= size
& 0xF;
1581 return m
<= 9 && e
<= 9 && (m
> 0 || e
== 0);
1584 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, bool *ret_cache_flush
, size_t *start
) {
1585 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1586 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1587 size_t saved_rindex
, offset
;
1595 saved_rindex
= p
->rindex
;
1597 r
= dns_packet_read_key(p
, &key
, &cache_flush
, NULL
);
1601 if (!dns_class_is_valid_rr(key
->class)||
1602 !dns_type_is_valid_rr(key
->type
)) {
1607 rr
= dns_resource_record_new(key
);
1613 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
1617 /* RFC 2181, Section 8, suggests to
1618 * treat a TTL with the MSB set as a zero TTL. */
1619 if (rr
->ttl
& UINT32_C(0x80000000))
1622 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
1626 if (p
->rindex
+ rdlength
> p
->size
) {
1633 switch (rr
->key
->type
) {
1636 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
1639 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
1642 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
1645 r
= dns_packet_read_name(p
, &rr
->srv
.name
, true, NULL
);
1650 case DNS_TYPE_CNAME
:
1651 case DNS_TYPE_DNAME
:
1652 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, true, NULL
);
1655 case DNS_TYPE_HINFO
:
1656 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1660 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1663 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1665 if (rdlength
<= 0) {
1667 /* RFC 6763, section 6.1 suggests to treat
1668 * empty TXT RRs as equivalent to a TXT record
1669 * with a single empty string. */
1671 i
= malloc0(offsetof(DnsTxtItem
, data
) + 1); /* for safety reasons we add an extra NUL byte */
1677 DnsTxtItem
*last
= NULL
;
1679 while (p
->rindex
< offset
+ rdlength
) {
1684 r
= dns_packet_read_raw_string(p
, &data
, &sz
, NULL
);
1688 i
= malloc0(offsetof(DnsTxtItem
, data
) + sz
+ 1); /* extra NUL byte at the end */
1692 memcpy(i
->data
, data
, sz
);
1695 LIST_INSERT_AFTER(items
, rr
->txt
.items
, last
, i
);
1704 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1708 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1712 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, true, NULL
);
1716 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, true, NULL
);
1720 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1724 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1728 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1732 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1736 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1740 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1744 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, true, NULL
);
1747 case DNS_TYPE_LOC
: {
1751 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1756 rr
->loc
.version
= t
;
1758 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1762 if (!loc_size_ok(rr
->loc
.size
)) {
1767 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1771 if (!loc_size_ok(rr
->loc
.horiz_pre
)) {
1776 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1780 if (!loc_size_ok(rr
->loc
.vert_pre
)) {
1785 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1789 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1793 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1799 dns_packet_rewind(p
, pos
);
1800 rr
->unparseable
= true;
1806 r
= dns_packet_read_uint16(p
, &rr
->ds
.key_tag
, NULL
);
1810 r
= dns_packet_read_uint8(p
, &rr
->ds
.algorithm
, NULL
);
1814 r
= dns_packet_read_uint8(p
, &rr
->ds
.digest_type
, NULL
);
1818 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1819 &rr
->ds
.digest
, &rr
->ds
.digest_size
,
1824 if (rr
->ds
.digest_size
<= 0) {
1825 /* the accepted size depends on the algorithm, but for now
1826 just ensure that the value is greater than zero */
1833 case DNS_TYPE_SSHFP
:
1834 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1838 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1842 r
= dns_packet_read_memdup(p
, rdlength
- 2,
1843 &rr
->sshfp
.fingerprint
, &rr
->sshfp
.fingerprint_size
,
1846 if (rr
->sshfp
.fingerprint_size
<= 0) {
1847 /* the accepted size depends on the algorithm, but for now
1848 just ensure that the value is greater than zero */
1855 case DNS_TYPE_DNSKEY
:
1856 r
= dns_packet_read_uint16(p
, &rr
->dnskey
.flags
, NULL
);
1860 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.protocol
, NULL
);
1864 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.algorithm
, NULL
);
1868 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1869 &rr
->dnskey
.key
, &rr
->dnskey
.key_size
,
1872 if (rr
->dnskey
.key_size
<= 0) {
1873 /* the accepted size depends on the algorithm, but for now
1874 just ensure that the value is greater than zero */
1881 case DNS_TYPE_RRSIG
:
1882 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.type_covered
, NULL
);
1886 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.algorithm
, NULL
);
1890 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.labels
, NULL
);
1894 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.original_ttl
, NULL
);
1898 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.expiration
, NULL
);
1902 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.inception
, NULL
);
1906 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.key_tag
, NULL
);
1910 r
= dns_packet_read_name(p
, &rr
->rrsig
.signer
, false, NULL
);
1914 r
= dns_packet_read_memdup(p
, offset
+ rdlength
- p
->rindex
,
1915 &rr
->rrsig
.signature
, &rr
->rrsig
.signature_size
,
1918 if (rr
->rrsig
.signature_size
<= 0) {
1919 /* the accepted size depends on the algorithm, but for now
1920 just ensure that the value is greater than zero */
1927 case DNS_TYPE_NSEC
: {
1930 * RFC6762, section 18.14 explictly states mDNS should use name compression.
1931 * This contradicts RFC3845, section 2.1.1
1934 bool allow_compressed
= p
->protocol
== DNS_PROTOCOL_MDNS
;
1936 r
= dns_packet_read_name(p
, &rr
->nsec
.next_domain_name
, allow_compressed
, NULL
);
1940 r
= dns_packet_read_type_windows(p
, &rr
->nsec
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1944 /* We accept empty NSEC bitmaps. The bit indicating the presence of the NSEC record itself
1945 * is redundant and in e.g., RFC4956 this fact is used to define a use for NSEC records
1946 * without the NSEC bit set. */
1950 case DNS_TYPE_NSEC3
: {
1953 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.algorithm
, NULL
);
1957 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.flags
, NULL
);
1961 r
= dns_packet_read_uint16(p
, &rr
->nsec3
.iterations
, NULL
);
1965 /* this may be zero */
1966 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1970 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.salt
, &rr
->nsec3
.salt_size
, NULL
);
1974 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1983 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.next_hashed_name
, &rr
->nsec3
.next_hashed_name_size
, NULL
);
1987 r
= dns_packet_read_type_windows(p
, &rr
->nsec3
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1991 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
1997 r
= dns_packet_read_uint8(p
, &rr
->tlsa
.cert_usage
, NULL
);
2001 r
= dns_packet_read_uint8(p
, &rr
->tlsa
.selector
, NULL
);
2005 r
= dns_packet_read_uint8(p
, &rr
->tlsa
.matching_type
, NULL
);
2009 r
= dns_packet_read_memdup(p
, rdlength
- 3,
2010 &rr
->tlsa
.data
, &rr
->tlsa
.data_size
,
2012 if (rr
->tlsa
.data_size
<= 0) {
2013 /* the accepted size depends on the algorithm, but for now
2014 just ensure that the value is greater than zero */
2021 case DNS_TYPE_OPT
: /* we only care about the header of OPT for now. */
2022 case DNS_TYPE_OPENPGPKEY
:
2025 r
= dns_packet_read_memdup(p
, rdlength
, &rr
->generic
.data
, &rr
->generic
.data_size
, NULL
);
2032 if (p
->rindex
!= offset
+ rdlength
) {
2040 if (ret_cache_flush
)
2041 *ret_cache_flush
= cache_flush
;
2043 *start
= saved_rindex
;
2047 dns_packet_rewind(p
, saved_rindex
);
2051 static bool opt_is_good(DnsResourceRecord
*rr
, bool *rfc6975
) {
2053 bool found_dau_dhu_n3u
= false;
2056 /* Checks whether the specified OPT RR is well-formed and whether it contains RFC6975 data (which is not OK in
2060 assert(rr
->key
->type
== DNS_TYPE_OPT
);
2062 /* Check that the version is 0 */
2063 if (((rr
->ttl
>> 16) & UINT32_C(0xFF)) != 0)
2067 l
= rr
->opt
.data_size
;
2069 uint16_t option_code
, option_length
;
2071 /* At least four bytes for OPTION-CODE and OPTION-LENGTH are required */
2075 option_code
= unaligned_read_be16(p
);
2076 option_length
= unaligned_read_be16(p
+ 2);
2078 if (l
< option_length
+ 4U)
2081 /* RFC 6975 DAU, DHU or N3U fields found. */
2082 if (IN_SET(option_code
, 5, 6, 7))
2083 found_dau_dhu_n3u
= true;
2085 p
+= option_length
+ 4U;
2086 l
-= option_length
+ 4U;
2089 *rfc6975
= found_dau_dhu_n3u
;
2093 int dns_packet_extract(DnsPacket
*p
) {
2094 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
2095 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
2096 size_t saved_rindex
;
2103 saved_rindex
= p
->rindex
;
2104 dns_packet_rewind(p
, DNS_PACKET_HEADER_SIZE
);
2106 n
= DNS_PACKET_QDCOUNT(p
);
2108 question
= dns_question_new(n
);
2114 for (i
= 0; i
< n
; i
++) {
2115 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
2118 r
= dns_packet_read_key(p
, &key
, &cache_flush
, NULL
);
2127 if (!dns_type_is_valid_query(key
->type
)) {
2132 r
= dns_question_add(question
, key
);
2138 n
= DNS_PACKET_RRCOUNT(p
);
2140 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*previous
= NULL
;
2141 bool bad_opt
= false;
2143 answer
= dns_answer_new(n
);
2149 for (i
= 0; i
< n
; i
++) {
2150 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
2153 r
= dns_packet_read_rr(p
, &rr
, &cache_flush
, NULL
);
2157 /* Try to reduce memory usage a bit */
2159 dns_resource_key_reduce(&rr
->key
, &previous
->key
);
2161 if (rr
->key
->type
== DNS_TYPE_OPT
) {
2164 if (p
->opt
|| bad_opt
) {
2165 /* Multiple OPT RRs? if so, let's ignore all, because there's something wrong
2166 * with the server, and if one is valid we wouldn't know which one. */
2167 log_debug("Multiple OPT RRs detected, ignoring all.");
2172 if (!dns_name_is_root(DNS_RESOURCE_KEY_NAME(rr
->key
))) {
2173 /* If the OPT RR qis not owned by the root domain, then it is bad, let's ignore
2175 log_debug("OPT RR is not owned by root domain, ignoring.");
2180 if (i
< DNS_PACKET_ANCOUNT(p
) + DNS_PACKET_NSCOUNT(p
)) {
2181 /* OPT RR is in the wrong section? Some Belkin routers do this. This is a hint
2182 * the EDNS implementation is borked, like the Belkin one is, hence ignore
2184 log_debug("OPT RR in wrong section, ignoring.");
2189 if (!opt_is_good(rr
, &has_rfc6975
)) {
2190 log_debug("Malformed OPT RR, ignoring.");
2196 /* If the OPT RR contains RFC6975 algorithm data, then this is indication that
2197 * the server just copied the OPT it got from us (which contained that data)
2198 * back into the reply. If so, then it doesn't properly support EDNS, as
2199 * RFC6975 makes it very clear that the algorithm data should only be contained
2200 * in questions, never in replies. Crappy Belkin routers copy the OPT data for
2201 * example, hence let's detect this so that we downgrade early. */
2202 log_debug("OPT RR contained RFC6975 data, ignoring.");
2207 p
->opt
= dns_resource_record_ref(rr
);
2210 /* According to RFC 4795, section 2.9. only the RRs from the Answer section shall be
2211 * cached. Hence mark only those RRs as cacheable by default, but not the ones from the
2212 * Additional or Authority sections. */
2214 r
= dns_answer_add(answer
, rr
, p
->ifindex
,
2215 (i
< DNS_PACKET_ANCOUNT(p
) ? DNS_ANSWER_CACHEABLE
: 0) |
2216 (p
->protocol
== DNS_PROTOCOL_MDNS
&& !cache_flush
? DNS_ANSWER_SHARED_OWNER
: 0));
2221 /* Remember this RR, so that we potentically can merge it's ->key object with the next RR. Note
2222 * that we only do this if we actually decided to keep the RR around. */
2223 dns_resource_record_unref(previous
);
2224 previous
= dns_resource_record_ref(rr
);
2228 p
->opt
= dns_resource_record_unref(p
->opt
);
2231 p
->question
= question
;
2237 p
->extracted
= true;
2242 p
->rindex
= saved_rindex
;
2246 int dns_packet_is_reply_for(DnsPacket
*p
, const DnsResourceKey
*key
) {
2252 /* Checks if the specified packet is a reply for the specified
2253 * key and the specified key is the only one in the question
2256 if (DNS_PACKET_QR(p
) != 1)
2259 /* Let's unpack the packet, if that hasn't happened yet. */
2260 r
= dns_packet_extract(p
);
2264 if (p
->question
->n_keys
!= 1)
2267 return dns_resource_key_equal(p
->question
->keys
[0], key
);
2270 static const char* const dns_rcode_table
[_DNS_RCODE_MAX_DEFINED
] = {
2271 [DNS_RCODE_SUCCESS
] = "SUCCESS",
2272 [DNS_RCODE_FORMERR
] = "FORMERR",
2273 [DNS_RCODE_SERVFAIL
] = "SERVFAIL",
2274 [DNS_RCODE_NXDOMAIN
] = "NXDOMAIN",
2275 [DNS_RCODE_NOTIMP
] = "NOTIMP",
2276 [DNS_RCODE_REFUSED
] = "REFUSED",
2277 [DNS_RCODE_YXDOMAIN
] = "YXDOMAIN",
2278 [DNS_RCODE_YXRRSET
] = "YRRSET",
2279 [DNS_RCODE_NXRRSET
] = "NXRRSET",
2280 [DNS_RCODE_NOTAUTH
] = "NOTAUTH",
2281 [DNS_RCODE_NOTZONE
] = "NOTZONE",
2282 [DNS_RCODE_BADVERS
] = "BADVERS",
2283 [DNS_RCODE_BADKEY
] = "BADKEY",
2284 [DNS_RCODE_BADTIME
] = "BADTIME",
2285 [DNS_RCODE_BADMODE
] = "BADMODE",
2286 [DNS_RCODE_BADNAME
] = "BADNAME",
2287 [DNS_RCODE_BADALG
] = "BADALG",
2288 [DNS_RCODE_BADTRUNC
] = "BADTRUNC",
2290 DEFINE_STRING_TABLE_LOOKUP(dns_rcode
, int);
2292 static const char* const dns_protocol_table
[_DNS_PROTOCOL_MAX
] = {
2293 [DNS_PROTOCOL_DNS
] = "dns",
2294 [DNS_PROTOCOL_MDNS
] = "mdns",
2295 [DNS_PROTOCOL_LLMNR
] = "llmnr",
2297 DEFINE_STRING_TABLE_LOOKUP(dns_protocol
, DnsProtocol
);