2 This file is part of systemd.
4 Copyright 2014 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 #include "alloc-util.h"
21 #include "dns-domain.h"
22 #include "resolved-dns-packet.h"
23 #include "string-table.h"
25 #include "unaligned.h"
29 #define EDNS0_OPT_DO (1<<15)
31 typedef struct DnsPacketRewinder
{
36 static void rewind_dns_packet(DnsPacketRewinder
*rewinder
) {
38 dns_packet_rewind(rewinder
->packet
, rewinder
->saved_rindex
);
41 #define INIT_REWINDER(rewinder, p) do { rewinder.packet = p; rewinder.saved_rindex = p->rindex; } while(0)
42 #define CANCEL_REWINDER(rewinder) do { rewinder.packet = NULL; } while(0)
44 int dns_packet_new(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
50 if (mtu
<= UDP_PACKET_HEADER_SIZE
)
51 a
= DNS_PACKET_SIZE_START
;
53 a
= mtu
- UDP_PACKET_HEADER_SIZE
;
55 if (a
< DNS_PACKET_HEADER_SIZE
)
56 a
= DNS_PACKET_HEADER_SIZE
;
58 /* round up to next page size */
59 a
= PAGE_ALIGN(ALIGN(sizeof(DnsPacket
)) + a
) - ALIGN(sizeof(DnsPacket
));
61 /* make sure we never allocate more than useful */
62 if (a
> DNS_PACKET_SIZE_MAX
)
63 a
= DNS_PACKET_SIZE_MAX
;
65 p
= malloc0(ALIGN(sizeof(DnsPacket
)) + a
);
69 p
->size
= p
->rindex
= DNS_PACKET_HEADER_SIZE
;
71 p
->protocol
= protocol
;
72 p
->opt_start
= p
->opt_size
= (size_t) -1;
80 void dns_packet_set_flags(DnsPacket
*p
, bool dnssec_checking_disabled
, bool truncated
) {
86 h
= DNS_PACKET_HEADER(p
);
89 case DNS_PROTOCOL_LLMNR
:
92 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
103 case DNS_PROTOCOL_MDNS
:
104 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
108 0 /* rd (ask for recursion) */,
118 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
122 1 /* rd (ask for recursion) */,
125 dnssec_checking_disabled
/* cd */,
130 int dns_packet_new_query(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
, bool dnssec_checking_disabled
) {
136 r
= dns_packet_new(&p
, protocol
, mtu
);
140 /* Always set the TC bit to 0 initially.
141 * If there are multiple packets later, we'll update the bit shortly before sending.
143 dns_packet_set_flags(p
, dnssec_checking_disabled
, false);
149 DnsPacket
*dns_packet_ref(DnsPacket
*p
) {
154 assert(!p
->on_stack
);
156 assert(p
->n_ref
> 0);
161 static void dns_packet_free(DnsPacket
*p
) {
166 dns_question_unref(p
->question
);
167 dns_answer_unref(p
->answer
);
168 dns_resource_record_unref(p
->opt
);
170 while ((s
= hashmap_steal_first_key(p
->names
)))
172 hashmap_free(p
->names
);
180 DnsPacket
*dns_packet_unref(DnsPacket
*p
) {
184 assert(p
->n_ref
> 0);
186 dns_packet_unref(p
->more
);
196 int dns_packet_validate(DnsPacket
*p
) {
199 if (p
->size
< DNS_PACKET_HEADER_SIZE
)
202 if (p
->size
> DNS_PACKET_SIZE_MAX
)
208 int dns_packet_validate_reply(DnsPacket
*p
) {
213 r
= dns_packet_validate(p
);
217 if (DNS_PACKET_QR(p
) != 1)
220 if (DNS_PACKET_OPCODE(p
) != 0)
223 switch (p
->protocol
) {
225 case DNS_PROTOCOL_LLMNR
:
226 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
227 if (DNS_PACKET_QDCOUNT(p
) != 1)
232 case DNS_PROTOCOL_MDNS
:
233 /* RFC 6762, Section 18 */
234 if (DNS_PACKET_RCODE(p
) != 0)
246 int dns_packet_validate_query(DnsPacket
*p
) {
251 r
= dns_packet_validate(p
);
255 if (DNS_PACKET_QR(p
) != 0)
258 if (DNS_PACKET_OPCODE(p
) != 0)
261 if (DNS_PACKET_TC(p
))
264 switch (p
->protocol
) {
266 case DNS_PROTOCOL_LLMNR
:
267 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
268 if (DNS_PACKET_QDCOUNT(p
) != 1)
271 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
272 if (DNS_PACKET_ANCOUNT(p
) > 0)
275 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
276 if (DNS_PACKET_NSCOUNT(p
) > 0)
281 case DNS_PROTOCOL_MDNS
:
282 /* RFC 6762, Section 18 */
283 if (DNS_PACKET_AA(p
) != 0 ||
284 DNS_PACKET_RD(p
) != 0 ||
285 DNS_PACKET_RA(p
) != 0 ||
286 DNS_PACKET_AD(p
) != 0 ||
287 DNS_PACKET_CD(p
) != 0 ||
288 DNS_PACKET_RCODE(p
) != 0)
300 static int dns_packet_extend(DnsPacket
*p
, size_t add
, void **ret
, size_t *start
) {
303 if (p
->size
+ add
> p
->allocated
) {
306 a
= PAGE_ALIGN((p
->size
+ add
) * 2);
307 if (a
> DNS_PACKET_SIZE_MAX
)
308 a
= DNS_PACKET_SIZE_MAX
;
310 if (p
->size
+ add
> a
)
316 d
= realloc(p
->_data
, a
);
322 p
->_data
= malloc(a
);
326 memcpy(p
->_data
, (uint8_t*) p
+ ALIGN(sizeof(DnsPacket
)), p
->size
);
327 memzero((uint8_t*) p
->_data
+ p
->size
, a
- p
->size
);
337 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->size
;
343 void dns_packet_truncate(DnsPacket
*p
, size_t sz
) {
353 HASHMAP_FOREACH_KEY(n
, s
, p
->names
, i
) {
355 if (PTR_TO_SIZE(n
) < sz
)
358 hashmap_remove(p
->names
, s
);
365 int dns_packet_append_blob(DnsPacket
*p
, const void *d
, size_t l
, size_t *start
) {
371 r
= dns_packet_extend(p
, l
, &q
, start
);
379 int dns_packet_append_uint8(DnsPacket
*p
, uint8_t v
, size_t *start
) {
385 r
= dns_packet_extend(p
, sizeof(uint8_t), &d
, start
);
389 ((uint8_t*) d
)[0] = v
;
394 int dns_packet_append_uint16(DnsPacket
*p
, uint16_t v
, size_t *start
) {
400 r
= dns_packet_extend(p
, sizeof(uint16_t), &d
, start
);
404 unaligned_write_be16(d
, v
);
409 int dns_packet_append_uint32(DnsPacket
*p
, uint32_t v
, size_t *start
) {
415 r
= dns_packet_extend(p
, sizeof(uint32_t), &d
, start
);
419 unaligned_write_be32(d
, v
);
424 int dns_packet_append_string(DnsPacket
*p
, const char *s
, size_t *start
) {
428 return dns_packet_append_raw_string(p
, s
, strlen(s
), start
);
431 int dns_packet_append_raw_string(DnsPacket
*p
, const void *s
, size_t size
, size_t *start
) {
436 assert(s
|| size
== 0);
441 r
= dns_packet_extend(p
, 1 + size
, &d
, start
);
445 ((uint8_t*) d
)[0] = (uint8_t) size
;
447 memcpy_safe(((uint8_t*) d
) + 1, s
, size
);
452 int dns_packet_append_label(DnsPacket
*p
, const char *d
, size_t l
, bool canonical_candidate
, size_t *start
) {
456 /* Append a label to a packet. Optionally, does this in DNSSEC
457 * canonical form, if this label is marked as a candidate for
458 * it, and the canonical form logic is enabled for the
464 if (l
> DNS_LABEL_MAX
)
467 r
= dns_packet_extend(p
, 1 + l
, (void**) &w
, start
);
471 *(w
++) = (uint8_t) l
;
473 if (p
->canonical_form
&& canonical_candidate
) {
476 /* Generate in canonical form, as defined by DNSSEC
477 * RFC 4034, Section 6.2, i.e. all lower-case. */
479 for (i
= 0; i
< l
; i
++)
480 w
[i
] = (uint8_t) ascii_tolower(d
[i
]);
482 /* Otherwise, just copy the string unaltered. This is
483 * essential for DNS-SD, where the casing of labels
484 * matters and needs to be retained. */
490 int dns_packet_append_name(
493 bool allow_compression
,
494 bool canonical_candidate
,
503 if (p
->refuse_compression
)
504 allow_compression
= false;
506 saved_size
= p
->size
;
508 while (!dns_name_is_root(name
)) {
509 const char *z
= name
;
510 char label
[DNS_LABEL_MAX
];
513 if (allow_compression
)
514 n
= PTR_TO_SIZE(hashmap_get(p
->names
, name
));
519 r
= dns_packet_append_uint16(p
, 0xC000 | n
, NULL
);
527 r
= dns_label_unescape(&name
, label
, sizeof(label
));
531 r
= dns_packet_append_label(p
, label
, r
, canonical_candidate
, &n
);
535 if (allow_compression
) {
536 _cleanup_free_
char *s
= NULL
;
544 r
= hashmap_ensure_allocated(&p
->names
, &dns_name_hash_ops
);
548 r
= hashmap_put(p
->names
, s
, SIZE_TO_PTR(n
));
556 r
= dns_packet_append_uint8(p
, 0, NULL
);
567 dns_packet_truncate(p
, saved_size
);
571 int dns_packet_append_key(DnsPacket
*p
, const DnsResourceKey
*k
, size_t *start
) {
578 saved_size
= p
->size
;
580 r
= dns_packet_append_name(p
, dns_resource_key_name(k
), true, true, NULL
);
584 r
= dns_packet_append_uint16(p
, k
->type
, NULL
);
588 r
= dns_packet_append_uint16(p
, k
->class, NULL
);
598 dns_packet_truncate(p
, saved_size
);
602 static int dns_packet_append_type_window(DnsPacket
*p
, uint8_t window
, uint8_t length
, const uint8_t *types
, size_t *start
) {
610 saved_size
= p
->size
;
612 r
= dns_packet_append_uint8(p
, window
, NULL
);
616 r
= dns_packet_append_uint8(p
, length
, NULL
);
620 r
= dns_packet_append_blob(p
, types
, length
, NULL
);
629 dns_packet_truncate(p
, saved_size
);
633 static int dns_packet_append_types(DnsPacket
*p
, Bitmap
*types
, size_t *start
) {
637 uint8_t bitmaps
[32] = {};
644 saved_size
= p
->size
;
646 BITMAP_FOREACH(n
, types
, i
) {
649 if ((n
>> 8) != window
&& bitmaps
[entry
/ 8] != 0) {
650 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
660 bitmaps
[entry
/ 8] |= 1 << (7 - (entry
% 8));
663 if (bitmaps
[entry
/ 8] != 0) {
664 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
674 dns_packet_truncate(p
, saved_size
);
678 /* Append the OPT pseudo-RR described in RFC6891 */
679 int dns_packet_append_opt(DnsPacket
*p
, uint16_t max_udp_size
, bool edns0_do
, size_t *start
) {
684 /* we must never advertise supported packet size smaller than the legacy max */
685 assert(max_udp_size
>= DNS_PACKET_UNICAST_SIZE_MAX
);
687 if (p
->opt_start
!= (size_t) -1)
690 assert(p
->opt_size
== (size_t) -1);
692 saved_size
= p
->size
;
695 r
= dns_packet_append_uint8(p
, 0, NULL
);
700 r
= dns_packet_append_uint16(p
, DNS_TYPE_OPT
, NULL
);
704 /* maximum udp packet that can be received */
705 r
= dns_packet_append_uint16(p
, max_udp_size
, NULL
);
709 /* extended RCODE and VERSION */
710 r
= dns_packet_append_uint16(p
, 0, NULL
);
714 /* flags: DNSSEC OK (DO), see RFC3225 */
715 r
= dns_packet_append_uint16(p
, edns0_do
? EDNS0_OPT_DO
: 0, NULL
);
722 /* If DO is on, also append RFC6975 Algorithm data */
724 static const uint8_t rfc6975
[] = {
726 0, 5, /* OPTION_CODE: DAU */
727 0, 6, /* LIST_LENGTH */
728 DNSSEC_ALGORITHM_RSASHA1
,
729 DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1
,
730 DNSSEC_ALGORITHM_RSASHA256
,
731 DNSSEC_ALGORITHM_RSASHA512
,
732 DNSSEC_ALGORITHM_ECDSAP256SHA256
,
733 DNSSEC_ALGORITHM_ECDSAP384SHA384
,
735 0, 6, /* OPTION_CODE: DHU */
736 0, 3, /* LIST_LENGTH */
738 DNSSEC_DIGEST_SHA256
,
739 DNSSEC_DIGEST_SHA384
,
741 0, 7, /* OPTION_CODE: N3U */
742 0, 1, /* LIST_LENGTH */
743 NSEC3_ALGORITHM_SHA1
,
746 r
= dns_packet_append_uint16(p
, sizeof(rfc6975
), NULL
);
750 r
= dns_packet_append_blob(p
, rfc6975
, sizeof(rfc6975
), NULL
);
752 r
= dns_packet_append_uint16(p
, 0, NULL
);
757 DNS_PACKET_HEADER(p
)->arcount
= htobe16(DNS_PACKET_ARCOUNT(p
) + 1);
759 p
->opt_start
= saved_size
;
760 p
->opt_size
= p
->size
- saved_size
;
768 dns_packet_truncate(p
, saved_size
);
772 int dns_packet_truncate_opt(DnsPacket
*p
) {
775 if (p
->opt_start
== (size_t) -1) {
776 assert(p
->opt_size
== (size_t) -1);
780 assert(p
->opt_size
!= (size_t) -1);
781 assert(DNS_PACKET_ARCOUNT(p
) > 0);
783 if (p
->opt_start
+ p
->opt_size
!= p
->size
)
786 dns_packet_truncate(p
, p
->opt_start
);
787 DNS_PACKET_HEADER(p
)->arcount
= htobe16(DNS_PACKET_ARCOUNT(p
) - 1);
788 p
->opt_start
= p
->opt_size
= (size_t) -1;
793 int dns_packet_append_rr(DnsPacket
*p
, const DnsResourceRecord
*rr
, size_t *start
, size_t *rdata_start
) {
794 size_t saved_size
, rdlength_offset
, end
, rdlength
, rds
;
800 saved_size
= p
->size
;
802 r
= dns_packet_append_key(p
, rr
->key
, NULL
);
806 r
= dns_packet_append_uint32(p
, rr
->ttl
, NULL
);
810 /* Initially we write 0 here */
811 r
= dns_packet_append_uint16(p
, 0, &rdlength_offset
);
815 rds
= p
->size
- saved_size
;
817 switch (rr
->unparseable
? _DNS_TYPE_INVALID
: rr
->key
->type
) {
820 r
= dns_packet_append_uint16(p
, rr
->srv
.priority
, NULL
);
824 r
= dns_packet_append_uint16(p
, rr
->srv
.weight
, NULL
);
828 r
= dns_packet_append_uint16(p
, rr
->srv
.port
, NULL
);
832 r
= dns_packet_append_name(p
, rr
->srv
.name
, true, false, NULL
);
839 r
= dns_packet_append_name(p
, rr
->ptr
.name
, true, false, NULL
);
843 r
= dns_packet_append_string(p
, rr
->hinfo
.cpu
, NULL
);
847 r
= dns_packet_append_string(p
, rr
->hinfo
.os
, NULL
);
850 case DNS_TYPE_SPF
: /* exactly the same as TXT */
853 if (!rr
->txt
.items
) {
854 /* RFC 6763, section 6.1 suggests to generate
855 * single empty string for an empty array. */
857 r
= dns_packet_append_raw_string(p
, NULL
, 0, NULL
);
863 LIST_FOREACH(items
, i
, rr
->txt
.items
) {
864 r
= dns_packet_append_raw_string(p
, i
->data
, i
->length
, NULL
);
874 r
= dns_packet_append_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
878 r
= dns_packet_append_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
882 r
= dns_packet_append_name(p
, rr
->soa
.mname
, true, false, NULL
);
886 r
= dns_packet_append_name(p
, rr
->soa
.rname
, true, false, NULL
);
890 r
= dns_packet_append_uint32(p
, rr
->soa
.serial
, NULL
);
894 r
= dns_packet_append_uint32(p
, rr
->soa
.refresh
, NULL
);
898 r
= dns_packet_append_uint32(p
, rr
->soa
.retry
, NULL
);
902 r
= dns_packet_append_uint32(p
, rr
->soa
.expire
, NULL
);
906 r
= dns_packet_append_uint32(p
, rr
->soa
.minimum
, NULL
);
910 r
= dns_packet_append_uint16(p
, rr
->mx
.priority
, NULL
);
914 r
= dns_packet_append_name(p
, rr
->mx
.exchange
, true, false, NULL
);
918 r
= dns_packet_append_uint8(p
, rr
->loc
.version
, NULL
);
922 r
= dns_packet_append_uint8(p
, rr
->loc
.size
, NULL
);
926 r
= dns_packet_append_uint8(p
, rr
->loc
.horiz_pre
, NULL
);
930 r
= dns_packet_append_uint8(p
, rr
->loc
.vert_pre
, NULL
);
934 r
= dns_packet_append_uint32(p
, rr
->loc
.latitude
, NULL
);
938 r
= dns_packet_append_uint32(p
, rr
->loc
.longitude
, NULL
);
942 r
= dns_packet_append_uint32(p
, rr
->loc
.altitude
, NULL
);
946 r
= dns_packet_append_uint16(p
, rr
->ds
.key_tag
, NULL
);
950 r
= dns_packet_append_uint8(p
, rr
->ds
.algorithm
, NULL
);
954 r
= dns_packet_append_uint8(p
, rr
->ds
.digest_type
, NULL
);
958 r
= dns_packet_append_blob(p
, rr
->ds
.digest
, rr
->ds
.digest_size
, NULL
);
962 r
= dns_packet_append_uint8(p
, rr
->sshfp
.algorithm
, NULL
);
966 r
= dns_packet_append_uint8(p
, rr
->sshfp
.fptype
, NULL
);
970 r
= dns_packet_append_blob(p
, rr
->sshfp
.fingerprint
, rr
->sshfp
.fingerprint_size
, NULL
);
973 case DNS_TYPE_DNSKEY
:
974 r
= dns_packet_append_uint16(p
, rr
->dnskey
.flags
, NULL
);
978 r
= dns_packet_append_uint8(p
, rr
->dnskey
.protocol
, NULL
);
982 r
= dns_packet_append_uint8(p
, rr
->dnskey
.algorithm
, NULL
);
986 r
= dns_packet_append_blob(p
, rr
->dnskey
.key
, rr
->dnskey
.key_size
, NULL
);
990 r
= dns_packet_append_uint16(p
, rr
->rrsig
.type_covered
, NULL
);
994 r
= dns_packet_append_uint8(p
, rr
->rrsig
.algorithm
, NULL
);
998 r
= dns_packet_append_uint8(p
, rr
->rrsig
.labels
, NULL
);
1002 r
= dns_packet_append_uint32(p
, rr
->rrsig
.original_ttl
, NULL
);
1006 r
= dns_packet_append_uint32(p
, rr
->rrsig
.expiration
, NULL
);
1010 r
= dns_packet_append_uint32(p
, rr
->rrsig
.inception
, NULL
);
1014 r
= dns_packet_append_uint16(p
, rr
->rrsig
.key_tag
, NULL
);
1018 r
= dns_packet_append_name(p
, rr
->rrsig
.signer
, false, true, NULL
);
1022 r
= dns_packet_append_blob(p
, rr
->rrsig
.signature
, rr
->rrsig
.signature_size
, NULL
);
1026 r
= dns_packet_append_name(p
, rr
->nsec
.next_domain_name
, false, false, NULL
);
1030 r
= dns_packet_append_types(p
, rr
->nsec
.types
, NULL
);
1036 case DNS_TYPE_NSEC3
:
1037 r
= dns_packet_append_uint8(p
, rr
->nsec3
.algorithm
, NULL
);
1041 r
= dns_packet_append_uint8(p
, rr
->nsec3
.flags
, NULL
);
1045 r
= dns_packet_append_uint16(p
, rr
->nsec3
.iterations
, NULL
);
1049 r
= dns_packet_append_uint8(p
, rr
->nsec3
.salt_size
, NULL
);
1053 r
= dns_packet_append_blob(p
, rr
->nsec3
.salt
, rr
->nsec3
.salt_size
, NULL
);
1057 r
= dns_packet_append_uint8(p
, rr
->nsec3
.next_hashed_name_size
, NULL
);
1061 r
= dns_packet_append_blob(p
, rr
->nsec3
.next_hashed_name
, rr
->nsec3
.next_hashed_name_size
, NULL
);
1065 r
= dns_packet_append_types(p
, rr
->nsec3
.types
, NULL
);
1072 r
= dns_packet_append_uint8(p
, rr
->tlsa
.cert_usage
, NULL
);
1076 r
= dns_packet_append_uint8(p
, rr
->tlsa
.selector
, NULL
);
1080 r
= dns_packet_append_uint8(p
, rr
->tlsa
.matching_type
, NULL
);
1084 r
= dns_packet_append_blob(p
, rr
->tlsa
.data
, rr
->tlsa
.data_size
, NULL
);
1088 r
= dns_packet_append_uint8(p
, rr
->caa
.flags
, NULL
);
1092 r
= dns_packet_append_string(p
, rr
->caa
.tag
, NULL
);
1096 r
= dns_packet_append_blob(p
, rr
->caa
.value
, rr
->caa
.value_size
, NULL
);
1100 case DNS_TYPE_OPENPGPKEY
:
1101 case _DNS_TYPE_INVALID
: /* unparseable */
1104 r
= dns_packet_append_blob(p
, rr
->generic
.data
, rr
->generic
.data_size
, NULL
);
1110 /* Let's calculate the actual data size and update the field */
1111 rdlength
= p
->size
- rdlength_offset
- sizeof(uint16_t);
1112 if (rdlength
> 0xFFFF) {
1118 p
->size
= rdlength_offset
;
1119 r
= dns_packet_append_uint16(p
, rdlength
, NULL
);
1125 *start
= saved_size
;
1133 dns_packet_truncate(p
, saved_size
);
1137 int dns_packet_read(DnsPacket
*p
, size_t sz
, const void **ret
, size_t *start
) {
1140 if (p
->rindex
+ sz
> p
->size
)
1144 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->rindex
;
1153 void dns_packet_rewind(DnsPacket
*p
, size_t idx
) {
1155 assert(idx
<= p
->size
);
1156 assert(idx
>= DNS_PACKET_HEADER_SIZE
);
1161 int dns_packet_read_blob(DnsPacket
*p
, void *d
, size_t sz
, size_t *start
) {
1168 r
= dns_packet_read(p
, sz
, &q
, start
);
1176 static int dns_packet_read_memdup(
1177 DnsPacket
*p
, size_t size
,
1178 void **ret
, size_t *ret_size
,
1179 size_t *ret_start
) {
1188 r
= dns_packet_read(p
, size
, &src
, &start
);
1197 copy
= memdup(src
, size
);
1212 int dns_packet_read_uint8(DnsPacket
*p
, uint8_t *ret
, size_t *start
) {
1218 r
= dns_packet_read(p
, sizeof(uint8_t), &d
, start
);
1222 *ret
= ((uint8_t*) d
)[0];
1226 int dns_packet_read_uint16(DnsPacket
*p
, uint16_t *ret
, size_t *start
) {
1232 r
= dns_packet_read(p
, sizeof(uint16_t), &d
, start
);
1236 *ret
= unaligned_read_be16(d
);
1241 int dns_packet_read_uint32(DnsPacket
*p
, uint32_t *ret
, size_t *start
) {
1247 r
= dns_packet_read(p
, sizeof(uint32_t), &d
, start
);
1251 *ret
= unaligned_read_be32(d
);
1256 int dns_packet_read_string(DnsPacket
*p
, char **ret
, size_t *start
) {
1257 _cleanup_(rewind_dns_packet
) DnsPacketRewinder rewinder
;
1264 INIT_REWINDER(rewinder
, p
);
1266 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1270 r
= dns_packet_read(p
, c
, &d
, NULL
);
1274 if (memchr(d
, 0, c
))
1281 if (!utf8_is_valid(t
)) {
1289 *start
= rewinder
.saved_rindex
;
1290 CANCEL_REWINDER(rewinder
);
1295 int dns_packet_read_raw_string(DnsPacket
*p
, const void **ret
, size_t *size
, size_t *start
) {
1296 _cleanup_(rewind_dns_packet
) DnsPacketRewinder rewinder
;
1301 INIT_REWINDER(rewinder
, p
);
1303 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1307 r
= dns_packet_read(p
, c
, ret
, NULL
);
1314 *start
= rewinder
.saved_rindex
;
1315 CANCEL_REWINDER(rewinder
);
1320 int dns_packet_read_name(
1323 bool allow_compression
,
1326 _cleanup_(rewind_dns_packet
) DnsPacketRewinder rewinder
;
1327 size_t after_rindex
= 0, jump_barrier
;
1328 _cleanup_free_
char *ret
= NULL
;
1329 size_t n
= 0, allocated
= 0;
1335 INIT_REWINDER(rewinder
, p
);
1336 jump_barrier
= p
->rindex
;
1338 if (p
->refuse_compression
)
1339 allow_compression
= false;
1344 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1355 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
1359 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ DNS_LABEL_ESCAPED_MAX
))
1367 r
= dns_label_escape(label
, c
, ret
+ n
, DNS_LABEL_ESCAPED_MAX
);
1373 } else if (allow_compression
&& (c
& 0xc0) == 0xc0) {
1377 r
= dns_packet_read_uint8(p
, &d
, NULL
);
1381 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
1382 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= jump_barrier
)
1385 if (after_rindex
== 0)
1386 after_rindex
= p
->rindex
;
1388 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1395 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1))
1400 if (after_rindex
!= 0)
1401 p
->rindex
= after_rindex
;
1407 *start
= rewinder
.saved_rindex
;
1408 CANCEL_REWINDER(rewinder
);
1413 static int dns_packet_read_type_window(DnsPacket
*p
, Bitmap
**types
, size_t *start
) {
1416 const uint8_t *bitmap
;
1420 _cleanup_(rewind_dns_packet
) DnsPacketRewinder rewinder
;
1425 INIT_REWINDER(rewinder
, p
);
1427 r
= bitmap_ensure_allocated(types
);
1431 r
= dns_packet_read_uint8(p
, &window
, NULL
);
1435 r
= dns_packet_read_uint8(p
, &length
, NULL
);
1439 if (length
== 0 || length
> 32)
1442 r
= dns_packet_read(p
, length
, (const void **)&bitmap
, NULL
);
1446 for (i
= 0; i
< length
; i
++) {
1447 uint8_t bitmask
= 1 << 7;
1458 if (bitmap
[i
] & bitmask
) {
1461 n
= (uint16_t) window
<< 8 | (uint16_t) bit
;
1463 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1464 if (dns_type_is_pseudo(n
))
1467 r
= bitmap_set(*types
, n
);
1481 *start
= rewinder
.saved_rindex
;
1482 CANCEL_REWINDER(rewinder
);
1487 static int dns_packet_read_type_windows(DnsPacket
*p
, Bitmap
**types
, size_t size
, size_t *start
) {
1488 _cleanup_(rewind_dns_packet
) DnsPacketRewinder rewinder
;
1491 INIT_REWINDER(rewinder
, p
);
1493 while (p
->rindex
< rewinder
.saved_rindex
+ size
) {
1494 r
= dns_packet_read_type_window(p
, types
, NULL
);
1498 /* don't read past end of current RR */
1499 if (p
->rindex
> rewinder
.saved_rindex
+ size
)
1503 if (p
->rindex
!= rewinder
.saved_rindex
+ size
)
1507 *start
= rewinder
.saved_rindex
;
1508 CANCEL_REWINDER(rewinder
);
1513 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, bool *ret_cache_flush
, size_t *start
) {
1514 _cleanup_(rewind_dns_packet
) DnsPacketRewinder rewinder
;
1515 _cleanup_free_
char *name
= NULL
;
1516 bool cache_flush
= false;
1517 uint16_t class, type
;
1518 DnsResourceKey
*key
;
1523 INIT_REWINDER(rewinder
, p
);
1525 r
= dns_packet_read_name(p
, &name
, true, NULL
);
1529 r
= dns_packet_read_uint16(p
, &type
, NULL
);
1533 r
= dns_packet_read_uint16(p
, &class, NULL
);
1537 if (p
->protocol
== DNS_PROTOCOL_MDNS
) {
1538 /* See RFC6762, Section 10.2 */
1540 if (type
!= DNS_TYPE_OPT
&& (class & MDNS_RR_CACHE_FLUSH
)) {
1541 class &= ~MDNS_RR_CACHE_FLUSH
;
1546 key
= dns_resource_key_new_consume(class, type
, name
);
1553 if (ret_cache_flush
)
1554 *ret_cache_flush
= cache_flush
;
1556 *start
= rewinder
.saved_rindex
;
1557 CANCEL_REWINDER(rewinder
);
1562 static bool loc_size_ok(uint8_t size
) {
1563 uint8_t m
= size
>> 4, e
= size
& 0xF;
1565 return m
<= 9 && e
<= 9 && (m
> 0 || e
== 0);
1568 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, bool *ret_cache_flush
, size_t *start
) {
1569 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1570 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1571 _cleanup_(rewind_dns_packet
) DnsPacketRewinder rewinder
;
1580 INIT_REWINDER(rewinder
, p
);
1582 r
= dns_packet_read_key(p
, &key
, &cache_flush
, NULL
);
1586 if (!dns_class_is_valid_rr(key
->class) || !dns_type_is_valid_rr(key
->type
))
1589 rr
= dns_resource_record_new(key
);
1593 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
1597 /* RFC 2181, Section 8, suggests to
1598 * treat a TTL with the MSB set as a zero TTL. */
1599 if (rr
->ttl
& UINT32_C(0x80000000))
1602 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
1606 if (p
->rindex
+ rdlength
> p
->size
)
1611 switch (rr
->key
->type
) {
1614 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
1617 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
1620 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
1623 r
= dns_packet_read_name(p
, &rr
->srv
.name
, true, NULL
);
1628 case DNS_TYPE_CNAME
:
1629 case DNS_TYPE_DNAME
:
1630 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, true, NULL
);
1633 case DNS_TYPE_HINFO
:
1634 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1638 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1641 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1643 if (rdlength
<= 0) {
1645 /* RFC 6763, section 6.1 suggests to treat
1646 * empty TXT RRs as equivalent to a TXT record
1647 * with a single empty string. */
1649 i
= malloc0(offsetof(DnsTxtItem
, data
) + 1); /* for safety reasons we add an extra NUL byte */
1655 DnsTxtItem
*last
= NULL
;
1657 while (p
->rindex
< offset
+ rdlength
) {
1662 r
= dns_packet_read_raw_string(p
, &data
, &sz
, NULL
);
1666 i
= malloc0(offsetof(DnsTxtItem
, data
) + sz
+ 1); /* extra NUL byte at the end */
1670 memcpy(i
->data
, data
, sz
);
1673 LIST_INSERT_AFTER(items
, rr
->txt
.items
, last
, i
);
1682 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1686 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1690 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, true, NULL
);
1694 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, true, NULL
);
1698 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1702 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1706 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1710 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1714 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1718 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1722 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, true, NULL
);
1725 case DNS_TYPE_LOC
: {
1729 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1734 rr
->loc
.version
= t
;
1736 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1740 if (!loc_size_ok(rr
->loc
.size
))
1743 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1747 if (!loc_size_ok(rr
->loc
.horiz_pre
))
1750 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1754 if (!loc_size_ok(rr
->loc
.vert_pre
))
1757 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1761 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1765 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1771 dns_packet_rewind(p
, pos
);
1772 rr
->unparseable
= true;
1778 r
= dns_packet_read_uint16(p
, &rr
->ds
.key_tag
, NULL
);
1782 r
= dns_packet_read_uint8(p
, &rr
->ds
.algorithm
, NULL
);
1786 r
= dns_packet_read_uint8(p
, &rr
->ds
.digest_type
, NULL
);
1790 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1791 &rr
->ds
.digest
, &rr
->ds
.digest_size
,
1796 if (rr
->ds
.digest_size
<= 0)
1797 /* the accepted size depends on the algorithm, but for now
1798 just ensure that the value is greater than zero */
1803 case DNS_TYPE_SSHFP
:
1804 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1808 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1812 r
= dns_packet_read_memdup(p
, rdlength
- 2,
1813 &rr
->sshfp
.fingerprint
, &rr
->sshfp
.fingerprint_size
,
1816 if (rr
->sshfp
.fingerprint_size
<= 0)
1817 /* the accepted size depends on the algorithm, but for now
1818 just ensure that the value is greater than zero */
1823 case DNS_TYPE_DNSKEY
:
1824 r
= dns_packet_read_uint16(p
, &rr
->dnskey
.flags
, NULL
);
1828 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.protocol
, NULL
);
1832 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.algorithm
, NULL
);
1836 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1837 &rr
->dnskey
.key
, &rr
->dnskey
.key_size
,
1840 if (rr
->dnskey
.key_size
<= 0)
1841 /* the accepted size depends on the algorithm, but for now
1842 just ensure that the value is greater than zero */
1847 case DNS_TYPE_RRSIG
:
1848 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.type_covered
, NULL
);
1852 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.algorithm
, NULL
);
1856 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.labels
, NULL
);
1860 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.original_ttl
, NULL
);
1864 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.expiration
, NULL
);
1868 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.inception
, NULL
);
1872 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.key_tag
, NULL
);
1876 r
= dns_packet_read_name(p
, &rr
->rrsig
.signer
, false, NULL
);
1880 r
= dns_packet_read_memdup(p
, offset
+ rdlength
- p
->rindex
,
1881 &rr
->rrsig
.signature
, &rr
->rrsig
.signature_size
,
1884 if (rr
->rrsig
.signature_size
<= 0)
1885 /* the accepted size depends on the algorithm, but for now
1886 just ensure that the value is greater than zero */
1891 case DNS_TYPE_NSEC
: {
1894 * RFC6762, section 18.14 explictly states mDNS should use name compression.
1895 * This contradicts RFC3845, section 2.1.1
1898 bool allow_compressed
= p
->protocol
== DNS_PROTOCOL_MDNS
;
1900 r
= dns_packet_read_name(p
, &rr
->nsec
.next_domain_name
, allow_compressed
, NULL
);
1904 r
= dns_packet_read_type_windows(p
, &rr
->nsec
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1906 /* We accept empty NSEC bitmaps. The bit indicating the presence of the NSEC record itself
1907 * is redundant and in e.g., RFC4956 this fact is used to define a use for NSEC records
1908 * without the NSEC bit set. */
1912 case DNS_TYPE_NSEC3
: {
1915 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.algorithm
, NULL
);
1919 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.flags
, NULL
);
1923 r
= dns_packet_read_uint16(p
, &rr
->nsec3
.iterations
, NULL
);
1927 /* this may be zero */
1928 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1932 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.salt
, &rr
->nsec3
.salt_size
, NULL
);
1936 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1943 r
= dns_packet_read_memdup(p
, size
,
1944 &rr
->nsec3
.next_hashed_name
, &rr
->nsec3
.next_hashed_name_size
,
1949 r
= dns_packet_read_type_windows(p
, &rr
->nsec3
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1951 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
1957 r
= dns_packet_read_uint8(p
, &rr
->tlsa
.cert_usage
, NULL
);
1961 r
= dns_packet_read_uint8(p
, &rr
->tlsa
.selector
, NULL
);
1965 r
= dns_packet_read_uint8(p
, &rr
->tlsa
.matching_type
, NULL
);
1969 r
= dns_packet_read_memdup(p
, rdlength
- 3,
1970 &rr
->tlsa
.data
, &rr
->tlsa
.data_size
,
1973 if (rr
->tlsa
.data_size
<= 0)
1974 /* the accepted size depends on the algorithm, but for now
1975 just ensure that the value is greater than zero */
1981 r
= dns_packet_read_uint8(p
, &rr
->caa
.flags
, NULL
);
1985 r
= dns_packet_read_string(p
, &rr
->caa
.tag
, NULL
);
1989 r
= dns_packet_read_memdup(p
,
1990 rdlength
+ offset
- p
->rindex
,
1991 &rr
->caa
.value
, &rr
->caa
.value_size
, NULL
);
1995 case DNS_TYPE_OPT
: /* we only care about the header of OPT for now. */
1996 case DNS_TYPE_OPENPGPKEY
:
1999 r
= dns_packet_read_memdup(p
, rdlength
, &rr
->generic
.data
, &rr
->generic
.data_size
, NULL
);
2005 if (p
->rindex
!= offset
+ rdlength
)
2011 if (ret_cache_flush
)
2012 *ret_cache_flush
= cache_flush
;
2014 *start
= rewinder
.saved_rindex
;
2015 CANCEL_REWINDER(rewinder
);
2020 static bool opt_is_good(DnsResourceRecord
*rr
, bool *rfc6975
) {
2022 bool found_dau_dhu_n3u
= false;
2025 /* Checks whether the specified OPT RR is well-formed and whether it contains RFC6975 data (which is not OK in
2029 assert(rr
->key
->type
== DNS_TYPE_OPT
);
2031 /* Check that the version is 0 */
2032 if (((rr
->ttl
>> 16) & UINT32_C(0xFF)) != 0)
2036 l
= rr
->opt
.data_size
;
2038 uint16_t option_code
, option_length
;
2040 /* At least four bytes for OPTION-CODE and OPTION-LENGTH are required */
2044 option_code
= unaligned_read_be16(p
);
2045 option_length
= unaligned_read_be16(p
+ 2);
2047 if (l
< option_length
+ 4U)
2050 /* RFC 6975 DAU, DHU or N3U fields found. */
2051 if (IN_SET(option_code
, 5, 6, 7))
2052 found_dau_dhu_n3u
= true;
2054 p
+= option_length
+ 4U;
2055 l
-= option_length
+ 4U;
2058 *rfc6975
= found_dau_dhu_n3u
;
2062 int dns_packet_extract(DnsPacket
*p
) {
2063 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
2064 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
2065 _cleanup_(rewind_dns_packet
) DnsPacketRewinder rewinder
= {};
2072 INIT_REWINDER(rewinder
, p
);
2073 dns_packet_rewind(p
, DNS_PACKET_HEADER_SIZE
);
2075 n
= DNS_PACKET_QDCOUNT(p
);
2077 question
= dns_question_new(n
);
2081 for (i
= 0; i
< n
; i
++) {
2082 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
2085 r
= dns_packet_read_key(p
, &key
, &cache_flush
, NULL
);
2092 if (!dns_type_is_valid_query(key
->type
))
2095 r
= dns_question_add(question
, key
);
2101 n
= DNS_PACKET_RRCOUNT(p
);
2103 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*previous
= NULL
;
2104 bool bad_opt
= false;
2106 answer
= dns_answer_new(n
);
2110 for (i
= 0; i
< n
; i
++) {
2111 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
2114 r
= dns_packet_read_rr(p
, &rr
, &cache_flush
, NULL
);
2118 /* Try to reduce memory usage a bit */
2120 dns_resource_key_reduce(&rr
->key
, &previous
->key
);
2122 if (rr
->key
->type
== DNS_TYPE_OPT
) {
2125 if (p
->opt
|| bad_opt
) {
2126 /* Multiple OPT RRs? if so, let's ignore all, because there's something wrong
2127 * with the server, and if one is valid we wouldn't know which one. */
2128 log_debug("Multiple OPT RRs detected, ignoring all.");
2133 if (!dns_name_is_root(dns_resource_key_name(rr
->key
))) {
2134 /* If the OPT RR is not owned by the root domain, then it is bad, let's ignore
2136 log_debug("OPT RR is not owned by root domain, ignoring.");
2141 if (i
< DNS_PACKET_ANCOUNT(p
) + DNS_PACKET_NSCOUNT(p
)) {
2142 /* OPT RR is in the wrong section? Some Belkin routers do this. This is a hint
2143 * the EDNS implementation is borked, like the Belkin one is, hence ignore
2145 log_debug("OPT RR in wrong section, ignoring.");
2150 if (!opt_is_good(rr
, &has_rfc6975
)) {
2151 log_debug("Malformed OPT RR, ignoring.");
2157 /* If the OPT RR contains RFC6975 algorithm data, then this is indication that
2158 * the server just copied the OPT it got from us (which contained that data)
2159 * back into the reply. If so, then it doesn't properly support EDNS, as
2160 * RFC6975 makes it very clear that the algorithm data should only be contained
2161 * in questions, never in replies. Crappy Belkin routers copy the OPT data for
2162 * example, hence let's detect this so that we downgrade early. */
2163 log_debug("OPT RR contained RFC6975 data, ignoring.");
2168 p
->opt
= dns_resource_record_ref(rr
);
2171 /* According to RFC 4795, section 2.9. only the RRs from the Answer section shall be
2172 * cached. Hence mark only those RRs as cacheable by default, but not the ones from the
2173 * Additional or Authority sections. */
2175 r
= dns_answer_add(answer
, rr
, p
->ifindex
,
2176 (i
< DNS_PACKET_ANCOUNT(p
) ? DNS_ANSWER_CACHEABLE
: 0) |
2177 (p
->protocol
== DNS_PROTOCOL_MDNS
&& !cache_flush
? DNS_ANSWER_SHARED_OWNER
: 0));
2182 /* Remember this RR, so that we potentically can merge it's ->key object with the next RR. Note
2183 * that we only do this if we actually decided to keep the RR around. */
2184 dns_resource_record_unref(previous
);
2185 previous
= dns_resource_record_ref(rr
);
2189 p
->opt
= dns_resource_record_unref(p
->opt
);
2192 p
->question
= question
;
2198 p
->extracted
= true;
2200 /* no CANCEL, always rewind */
2204 int dns_packet_is_reply_for(DnsPacket
*p
, const DnsResourceKey
*key
) {
2210 /* Checks if the specified packet is a reply for the specified
2211 * key and the specified key is the only one in the question
2214 if (DNS_PACKET_QR(p
) != 1)
2217 /* Let's unpack the packet, if that hasn't happened yet. */
2218 r
= dns_packet_extract(p
);
2222 if (p
->question
->n_keys
!= 1)
2225 return dns_resource_key_equal(p
->question
->keys
[0], key
);
2228 static const char* const dns_rcode_table
[_DNS_RCODE_MAX_DEFINED
] = {
2229 [DNS_RCODE_SUCCESS
] = "SUCCESS",
2230 [DNS_RCODE_FORMERR
] = "FORMERR",
2231 [DNS_RCODE_SERVFAIL
] = "SERVFAIL",
2232 [DNS_RCODE_NXDOMAIN
] = "NXDOMAIN",
2233 [DNS_RCODE_NOTIMP
] = "NOTIMP",
2234 [DNS_RCODE_REFUSED
] = "REFUSED",
2235 [DNS_RCODE_YXDOMAIN
] = "YXDOMAIN",
2236 [DNS_RCODE_YXRRSET
] = "YRRSET",
2237 [DNS_RCODE_NXRRSET
] = "NXRRSET",
2238 [DNS_RCODE_NOTAUTH
] = "NOTAUTH",
2239 [DNS_RCODE_NOTZONE
] = "NOTZONE",
2240 [DNS_RCODE_BADVERS
] = "BADVERS",
2241 [DNS_RCODE_BADKEY
] = "BADKEY",
2242 [DNS_RCODE_BADTIME
] = "BADTIME",
2243 [DNS_RCODE_BADMODE
] = "BADMODE",
2244 [DNS_RCODE_BADNAME
] = "BADNAME",
2245 [DNS_RCODE_BADALG
] = "BADALG",
2246 [DNS_RCODE_BADTRUNC
] = "BADTRUNC",
2248 DEFINE_STRING_TABLE_LOOKUP(dns_rcode
, int);
2250 static const char* const dns_protocol_table
[_DNS_PROTOCOL_MAX
] = {
2251 [DNS_PROTOCOL_DNS
] = "dns",
2252 [DNS_PROTOCOL_MDNS
] = "mdns",
2253 [DNS_PROTOCOL_LLMNR
] = "llmnr",
2255 DEFINE_STRING_TABLE_LOOKUP(dns_protocol
, DnsProtocol
);