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 int dns_packet_new(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
37 if (mtu
<= UDP_PACKET_HEADER_SIZE
)
38 a
= DNS_PACKET_SIZE_START
;
40 a
= mtu
- UDP_PACKET_HEADER_SIZE
;
42 if (a
< DNS_PACKET_HEADER_SIZE
)
43 a
= DNS_PACKET_HEADER_SIZE
;
45 /* round up to next page size */
46 a
= PAGE_ALIGN(ALIGN(sizeof(DnsPacket
)) + a
) - ALIGN(sizeof(DnsPacket
));
48 /* make sure we never allocate more than useful */
49 if (a
> DNS_PACKET_SIZE_MAX
)
50 a
= DNS_PACKET_SIZE_MAX
;
52 p
= malloc0(ALIGN(sizeof(DnsPacket
)) + a
);
56 p
->size
= p
->rindex
= DNS_PACKET_HEADER_SIZE
;
58 p
->protocol
= protocol
;
66 int dns_packet_new_query(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
73 r
= dns_packet_new(&p
, protocol
, mtu
);
77 h
= DNS_PACKET_HEADER(p
);
79 if (protocol
== DNS_PROTOCOL_LLMNR
)
80 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
90 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
94 1 /* rd (ask for recursion) */,
104 DnsPacket
*dns_packet_ref(DnsPacket
*p
) {
109 assert(p
->n_ref
> 0);
114 static void dns_packet_free(DnsPacket
*p
) {
119 dns_question_unref(p
->question
);
120 dns_answer_unref(p
->answer
);
122 while ((s
= hashmap_steal_first_key(p
->names
)))
124 hashmap_free(p
->names
);
130 DnsPacket
*dns_packet_unref(DnsPacket
*p
) {
134 assert(p
->n_ref
> 0);
144 int dns_packet_validate(DnsPacket
*p
) {
147 if (p
->size
< DNS_PACKET_HEADER_SIZE
)
150 if (p
->size
> DNS_PACKET_SIZE_MAX
)
156 int dns_packet_validate_reply(DnsPacket
*p
) {
161 r
= dns_packet_validate(p
);
165 if (DNS_PACKET_QR(p
) != 1)
168 if (DNS_PACKET_OPCODE(p
) != 0)
171 switch (p
->protocol
) {
172 case DNS_PROTOCOL_LLMNR
:
173 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
174 if (DNS_PACKET_QDCOUNT(p
) != 1)
186 int dns_packet_validate_query(DnsPacket
*p
) {
191 r
= dns_packet_validate(p
);
195 if (DNS_PACKET_QR(p
) != 0)
198 if (DNS_PACKET_OPCODE(p
) != 0)
201 if (DNS_PACKET_TC(p
))
204 switch (p
->protocol
) {
205 case DNS_PROTOCOL_LLMNR
:
206 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
207 if (DNS_PACKET_QDCOUNT(p
) != 1)
210 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
211 if (DNS_PACKET_ANCOUNT(p
) > 0)
214 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
215 if (DNS_PACKET_NSCOUNT(p
) > 0)
227 static int dns_packet_extend(DnsPacket
*p
, size_t add
, void **ret
, size_t *start
) {
230 if (p
->size
+ add
> p
->allocated
) {
233 a
= PAGE_ALIGN((p
->size
+ add
) * 2);
234 if (a
> DNS_PACKET_SIZE_MAX
)
235 a
= DNS_PACKET_SIZE_MAX
;
237 if (p
->size
+ add
> a
)
243 d
= realloc(p
->_data
, a
);
249 p
->_data
= malloc(a
);
253 memcpy(p
->_data
, (uint8_t*) p
+ ALIGN(sizeof(DnsPacket
)), p
->size
);
254 memzero((uint8_t*) p
->_data
+ p
->size
, a
- p
->size
);
264 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->size
;
270 static void dns_packet_truncate(DnsPacket
*p
, size_t sz
) {
280 HASHMAP_FOREACH_KEY(n
, s
, p
->names
, i
) {
282 if (PTR_TO_SIZE(n
) < sz
)
285 hashmap_remove(p
->names
, s
);
292 int dns_packet_append_blob(DnsPacket
*p
, const void *d
, size_t l
, size_t *start
) {
298 r
= dns_packet_extend(p
, l
, &q
, start
);
306 int dns_packet_append_uint8(DnsPacket
*p
, uint8_t v
, size_t *start
) {
312 r
= dns_packet_extend(p
, sizeof(uint8_t), &d
, start
);
316 ((uint8_t*) d
)[0] = v
;
321 int dns_packet_append_uint16(DnsPacket
*p
, uint16_t v
, size_t *start
) {
327 r
= dns_packet_extend(p
, sizeof(uint16_t), &d
, start
);
331 unaligned_write_be16(d
, v
);
336 int dns_packet_append_uint32(DnsPacket
*p
, uint32_t v
, size_t *start
) {
342 r
= dns_packet_extend(p
, sizeof(uint32_t), &d
, start
);
346 unaligned_write_be32(d
, v
);
351 int dns_packet_append_string(DnsPacket
*p
, const char *s
, size_t *start
) {
363 r
= dns_packet_extend(p
, 1 + l
, &d
, start
);
367 ((uint8_t*) d
)[0] = (uint8_t) l
;
368 memcpy(((uint8_t*) d
) + 1, s
, l
);
373 int dns_packet_append_label(DnsPacket
*p
, const char *d
, size_t l
, size_t *start
) {
380 if (l
> DNS_LABEL_MAX
)
383 r
= dns_packet_extend(p
, 1 + l
, &w
, start
);
387 ((uint8_t*) w
)[0] = (uint8_t) l
;
388 memcpy(((uint8_t*) w
) + 1, d
, l
);
393 int dns_packet_append_name(
396 bool allow_compression
,
405 if (p
->refuse_compression
)
406 allow_compression
= false;
408 saved_size
= p
->size
;
411 _cleanup_free_
char *s
= NULL
;
412 char label
[DNS_LABEL_MAX
];
416 if (allow_compression
)
417 n
= PTR_TO_SIZE(hashmap_get(p
->names
, name
));
422 r
= dns_packet_append_uint16(p
, 0xC000 | n
, NULL
);
436 r
= dns_label_unescape(&name
, label
, sizeof(label
));
440 if (p
->protocol
== DNS_PROTOCOL_DNS
)
441 k
= dns_label_apply_idna(label
, r
, label
, sizeof(label
));
443 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
451 r
= dns_packet_append_label(p
, label
, r
, &n
);
455 if (allow_compression
) {
456 r
= hashmap_ensure_allocated(&p
->names
, &dns_name_hash_ops
);
460 r
= hashmap_put(p
->names
, s
, SIZE_TO_PTR(n
));
468 r
= dns_packet_append_uint8(p
, 0, NULL
);
479 dns_packet_truncate(p
, saved_size
);
483 int dns_packet_append_key(DnsPacket
*p
, const DnsResourceKey
*k
, size_t *start
) {
490 saved_size
= p
->size
;
492 r
= dns_packet_append_name(p
, DNS_RESOURCE_KEY_NAME(k
), true, NULL
);
496 r
= dns_packet_append_uint16(p
, k
->type
, NULL
);
500 r
= dns_packet_append_uint16(p
, k
->class, NULL
);
510 dns_packet_truncate(p
, saved_size
);
514 static int dns_packet_append_type_window(DnsPacket
*p
, uint8_t window
, uint8_t length
, uint8_t *types
, size_t *start
) {
522 saved_size
= p
->size
;
524 r
= dns_packet_append_uint8(p
, window
, NULL
);
528 r
= dns_packet_append_uint8(p
, length
, NULL
);
532 r
= dns_packet_append_blob(p
, types
, length
, NULL
);
541 dns_packet_truncate(p
, saved_size
);
545 static int dns_packet_append_types(DnsPacket
*p
, Bitmap
*types
, size_t *start
) {
549 uint8_t bitmaps
[32] = {};
557 saved_size
= p
->size
;
559 BITMAP_FOREACH(n
, types
, i
) {
562 if ((n
>> 8) != window
&& bitmaps
[entry
/ 8] != 0) {
563 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
574 bitmaps
[entry
/ 8] |= 1 << (7 - (entry
% 8));
577 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
586 dns_packet_truncate(p
, saved_size
);
590 int dns_packet_append_rr(DnsPacket
*p
, const DnsResourceRecord
*rr
, size_t *start
) {
591 size_t saved_size
, rdlength_offset
, end
, rdlength
;
597 saved_size
= p
->size
;
599 r
= dns_packet_append_key(p
, rr
->key
, NULL
);
603 r
= dns_packet_append_uint32(p
, rr
->ttl
, NULL
);
607 /* Initially we write 0 here */
608 r
= dns_packet_append_uint16(p
, 0, &rdlength_offset
);
612 switch (rr
->unparseable
? _DNS_TYPE_INVALID
: rr
->key
->type
) {
615 r
= dns_packet_append_uint16(p
, rr
->srv
.priority
, NULL
);
619 r
= dns_packet_append_uint16(p
, rr
->srv
.weight
, NULL
);
623 r
= dns_packet_append_uint16(p
, rr
->srv
.port
, NULL
);
627 r
= dns_packet_append_name(p
, rr
->srv
.name
, true, NULL
);
634 r
= dns_packet_append_name(p
, rr
->ptr
.name
, true, NULL
);
638 r
= dns_packet_append_string(p
, rr
->hinfo
.cpu
, NULL
);
642 r
= dns_packet_append_string(p
, rr
->hinfo
.os
, NULL
);
645 case DNS_TYPE_SPF
: /* exactly the same as TXT */
649 if (strv_isempty(rr
->txt
.strings
)) {
650 /* RFC 6763, section 6.1 suggests to generate
651 * single empty string for an empty array. */
653 r
= dns_packet_append_string(p
, "", NULL
);
657 STRV_FOREACH(s
, rr
->txt
.strings
) {
658 r
= dns_packet_append_string(p
, *s
, NULL
);
669 r
= dns_packet_append_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
673 r
= dns_packet_append_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
677 r
= dns_packet_append_name(p
, rr
->soa
.mname
, true, NULL
);
681 r
= dns_packet_append_name(p
, rr
->soa
.rname
, true, NULL
);
685 r
= dns_packet_append_uint32(p
, rr
->soa
.serial
, NULL
);
689 r
= dns_packet_append_uint32(p
, rr
->soa
.refresh
, NULL
);
693 r
= dns_packet_append_uint32(p
, rr
->soa
.retry
, NULL
);
697 r
= dns_packet_append_uint32(p
, rr
->soa
.expire
, NULL
);
701 r
= dns_packet_append_uint32(p
, rr
->soa
.minimum
, NULL
);
705 r
= dns_packet_append_uint16(p
, rr
->mx
.priority
, NULL
);
709 r
= dns_packet_append_name(p
, rr
->mx
.exchange
, true, NULL
);
713 r
= dns_packet_append_uint8(p
, rr
->loc
.version
, NULL
);
717 r
= dns_packet_append_uint8(p
, rr
->loc
.size
, NULL
);
721 r
= dns_packet_append_uint8(p
, rr
->loc
.horiz_pre
, NULL
);
725 r
= dns_packet_append_uint8(p
, rr
->loc
.vert_pre
, NULL
);
729 r
= dns_packet_append_uint32(p
, rr
->loc
.latitude
, NULL
);
733 r
= dns_packet_append_uint32(p
, rr
->loc
.longitude
, NULL
);
737 r
= dns_packet_append_uint32(p
, rr
->loc
.altitude
, NULL
);
741 r
= dns_packet_append_uint16(p
, rr
->ds
.key_tag
, NULL
);
745 r
= dns_packet_append_uint8(p
, rr
->ds
.algorithm
, NULL
);
749 r
= dns_packet_append_uint8(p
, rr
->ds
.digest_type
, NULL
);
753 r
= dns_packet_append_blob(p
, rr
->ds
.digest
, rr
->ds
.digest_size
, NULL
);
757 r
= dns_packet_append_uint8(p
, rr
->sshfp
.algorithm
, NULL
);
761 r
= dns_packet_append_uint8(p
, rr
->sshfp
.fptype
, NULL
);
765 r
= dns_packet_append_blob(p
, rr
->sshfp
.fingerprint
, rr
->sshfp
.fingerprint_size
, NULL
);
768 case DNS_TYPE_DNSKEY
:
769 r
= dns_packet_append_uint16(p
, dnskey_to_flags(rr
), NULL
);
773 r
= dns_packet_append_uint8(p
, 3u, NULL
);
777 r
= dns_packet_append_uint8(p
, rr
->dnskey
.algorithm
, NULL
);
781 r
= dns_packet_append_blob(p
, rr
->dnskey
.key
, rr
->dnskey
.key_size
, NULL
);
785 r
= dns_packet_append_uint16(p
, rr
->rrsig
.type_covered
, NULL
);
789 r
= dns_packet_append_uint8(p
, rr
->rrsig
.algorithm
, NULL
);
793 r
= dns_packet_append_uint8(p
, rr
->rrsig
.labels
, NULL
);
797 r
= dns_packet_append_uint32(p
, rr
->rrsig
.original_ttl
, NULL
);
801 r
= dns_packet_append_uint32(p
, rr
->rrsig
.expiration
, NULL
);
805 r
= dns_packet_append_uint32(p
, rr
->rrsig
.inception
, NULL
);
809 r
= dns_packet_append_uint16(p
, rr
->rrsig
.key_tag
, NULL
);
813 r
= dns_packet_append_name(p
, rr
->rrsig
.signer
, false, NULL
);
817 r
= dns_packet_append_blob(p
, rr
->rrsig
.signature
, rr
->rrsig
.signature_size
, NULL
);
821 r
= dns_packet_append_name(p
, rr
->nsec
.next_domain_name
, false, NULL
);
825 r
= dns_packet_append_types(p
, rr
->nsec
.types
, NULL
);
831 r
= dns_packet_append_uint8(p
, rr
->nsec3
.algorithm
, NULL
);
835 r
= dns_packet_append_uint8(p
, rr
->nsec3
.flags
, NULL
);
839 r
= dns_packet_append_uint16(p
, rr
->nsec3
.iterations
, NULL
);
843 r
= dns_packet_append_uint8(p
, rr
->nsec3
.salt_size
, NULL
);
847 r
= dns_packet_append_blob(p
, rr
->nsec3
.salt
, rr
->nsec3
.salt_size
, NULL
);
851 r
= dns_packet_append_uint8(p
, rr
->nsec3
.next_hashed_name_size
, NULL
);
855 r
= dns_packet_append_blob(p
, rr
->nsec3
.next_hashed_name
, rr
->nsec3
.next_hashed_name_size
, NULL
);
859 r
= dns_packet_append_types(p
, rr
->nsec3
.types
, NULL
);
864 case _DNS_TYPE_INVALID
: /* unparseable */
867 r
= dns_packet_append_blob(p
, rr
->generic
.data
, rr
->generic
.size
, NULL
);
873 /* Let's calculate the actual data size and update the field */
874 rdlength
= p
->size
- rdlength_offset
- sizeof(uint16_t);
875 if (rdlength
> 0xFFFF) {
881 p
->size
= rdlength_offset
;
882 r
= dns_packet_append_uint16(p
, rdlength
, NULL
);
893 dns_packet_truncate(p
, saved_size
);
898 int dns_packet_read(DnsPacket
*p
, size_t sz
, const void **ret
, size_t *start
) {
901 if (p
->rindex
+ sz
> p
->size
)
905 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->rindex
;
914 void dns_packet_rewind(DnsPacket
*p
, size_t idx
) {
916 assert(idx
<= p
->size
);
917 assert(idx
>= DNS_PACKET_HEADER_SIZE
);
922 int dns_packet_read_blob(DnsPacket
*p
, void *d
, size_t sz
, size_t *start
) {
929 r
= dns_packet_read(p
, sz
, &q
, start
);
937 static int dns_packet_read_memdup(
938 DnsPacket
*p
, size_t size
,
939 void **ret
, size_t *ret_size
,
949 r
= dns_packet_read(p
, size
, &src
, &start
);
958 copy
= memdup(src
, size
);
973 int dns_packet_read_uint8(DnsPacket
*p
, uint8_t *ret
, size_t *start
) {
979 r
= dns_packet_read(p
, sizeof(uint8_t), &d
, start
);
983 *ret
= ((uint8_t*) d
)[0];
987 int dns_packet_read_uint16(DnsPacket
*p
, uint16_t *ret
, size_t *start
) {
993 r
= dns_packet_read(p
, sizeof(uint16_t), &d
, start
);
997 *ret
= unaligned_read_be16(d
);
1002 int dns_packet_read_uint32(DnsPacket
*p
, uint32_t *ret
, size_t *start
) {
1008 r
= dns_packet_read(p
, sizeof(uint32_t), &d
, start
);
1012 *ret
= unaligned_read_be32(d
);
1017 int dns_packet_read_string(DnsPacket
*p
, char **ret
, size_t *start
) {
1018 size_t saved_rindex
;
1026 saved_rindex
= p
->rindex
;
1028 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1032 r
= dns_packet_read(p
, c
, &d
, NULL
);
1036 if (memchr(d
, 0, c
)) {
1047 if (!utf8_is_valid(t
)) {
1056 *start
= saved_rindex
;
1061 dns_packet_rewind(p
, saved_rindex
);
1065 int dns_packet_read_name(
1068 bool allow_compression
,
1071 size_t saved_rindex
, after_rindex
= 0, jump_barrier
;
1072 _cleanup_free_
char *ret
= NULL
;
1073 size_t n
= 0, allocated
= 0;
1080 if (p
->refuse_compression
)
1081 allow_compression
= false;
1083 saved_rindex
= p
->rindex
;
1084 jump_barrier
= p
->rindex
;
1089 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1097 _cleanup_free_
char *t
= NULL
;
1101 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
1105 r
= dns_label_escape(label
, c
, &t
);
1109 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ strlen(t
) + 1)) {
1119 memcpy(ret
+ n
, t
, r
);
1122 } else if (allow_compression
&& (c
& 0xc0) == 0xc0) {
1126 r
= dns_packet_read_uint8(p
, &d
, NULL
);
1130 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
1131 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= jump_barrier
) {
1136 if (after_rindex
== 0)
1137 after_rindex
= p
->rindex
;
1139 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1148 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1)) {
1155 if (after_rindex
!= 0)
1156 p
->rindex
= after_rindex
;
1162 *start
= saved_rindex
;
1167 dns_packet_rewind(p
, saved_rindex
);
1171 static int dns_packet_read_type_window(DnsPacket
*p
, Bitmap
**types
, size_t *start
) {
1174 const uint8_t *bitmap
;
1178 size_t saved_rindex
;
1184 saved_rindex
= p
->rindex
;
1186 r
= bitmap_ensure_allocated(types
);
1190 r
= dns_packet_read_uint8(p
, &window
, NULL
);
1194 r
= dns_packet_read_uint8(p
, &length
, NULL
);
1198 if (length
== 0 || length
> 32)
1201 r
= dns_packet_read(p
, length
, (const void **)&bitmap
, NULL
);
1205 for (i
= 0; i
< length
; i
++) {
1206 uint8_t bitmask
= 1 << 7;
1217 if (bitmap
[i
] & bitmask
) {
1220 n
= (uint16_t) window
<< 8 | (uint16_t) bit
;
1222 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1223 if (dns_type_is_pseudo(n
))
1226 r
= bitmap_set(*types
, n
);
1240 *start
= saved_rindex
;
1244 dns_packet_rewind(p
, saved_rindex
);
1248 static int dns_packet_read_type_windows(DnsPacket
*p
, Bitmap
**types
, size_t size
, size_t *start
) {
1249 size_t saved_rindex
;
1252 saved_rindex
= p
->rindex
;
1254 while (p
->rindex
< saved_rindex
+ size
) {
1255 r
= dns_packet_read_type_window(p
, types
, NULL
);
1259 /* don't read past end of current RR */
1260 if (p
->rindex
> saved_rindex
+ size
) {
1266 if (p
->rindex
!= saved_rindex
+ size
) {
1272 *start
= saved_rindex
;
1276 dns_packet_rewind(p
, saved_rindex
);
1280 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, size_t *start
) {
1281 _cleanup_free_
char *name
= NULL
;
1282 uint16_t class, type
;
1283 DnsResourceKey
*key
;
1284 size_t saved_rindex
;
1290 saved_rindex
= p
->rindex
;
1292 r
= dns_packet_read_name(p
, &name
, true, NULL
);
1296 r
= dns_packet_read_uint16(p
, &type
, NULL
);
1300 r
= dns_packet_read_uint16(p
, &class, NULL
);
1304 key
= dns_resource_key_new_consume(class, type
, name
);
1314 *start
= saved_rindex
;
1318 dns_packet_rewind(p
, saved_rindex
);
1322 static bool loc_size_ok(uint8_t size
) {
1323 uint8_t m
= size
>> 4, e
= size
& 0xF;
1325 return m
<= 9 && e
<= 9 && (m
> 0 || e
== 0);
1328 static int dnskey_parse_flags(DnsResourceRecord
*rr
, uint16_t flags
) {
1331 if (flags
& ~(DNSKEY_FLAG_SEP
| DNSKEY_FLAG_ZONE_KEY
))
1334 rr
->dnskey
.zone_key_flag
= flags
& DNSKEY_FLAG_ZONE_KEY
;
1335 rr
->dnskey
.sep_flag
= flags
& DNSKEY_FLAG_SEP
;
1339 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, size_t *start
) {
1340 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1341 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1342 size_t saved_rindex
, offset
;
1349 saved_rindex
= p
->rindex
;
1351 r
= dns_packet_read_key(p
, &key
, NULL
);
1355 if (key
->class == DNS_CLASS_ANY
||
1356 key
->type
== DNS_TYPE_ANY
) {
1361 rr
= dns_resource_record_new(key
);
1367 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
1371 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
1375 if (p
->rindex
+ rdlength
> p
->size
) {
1382 switch (rr
->key
->type
) {
1385 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
1388 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
1391 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
1394 r
= dns_packet_read_name(p
, &rr
->srv
.name
, true, NULL
);
1399 case DNS_TYPE_CNAME
:
1400 case DNS_TYPE_DNAME
:
1401 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, true, NULL
);
1404 case DNS_TYPE_HINFO
:
1405 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1409 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1412 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1414 if (rdlength
<= 0) {
1415 /* RFC 6763, section 6.1 suggests to treat
1416 * empty TXT RRs as equivalent to a TXT record
1417 * with a single empty string. */
1419 r
= strv_extend(&rr
->txt
.strings
, "");
1423 while (p
->rindex
< offset
+ rdlength
) {
1426 r
= dns_packet_read_string(p
, &s
, NULL
);
1430 r
= strv_consume(&rr
->txt
.strings
, s
);
1440 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1444 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1448 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, true, NULL
);
1452 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, true, NULL
);
1456 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1460 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1464 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1468 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1472 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1476 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1480 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, true, NULL
);
1483 case DNS_TYPE_LOC
: {
1487 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1492 rr
->loc
.version
= t
;
1494 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1498 if (!loc_size_ok(rr
->loc
.size
)) {
1503 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1507 if (!loc_size_ok(rr
->loc
.horiz_pre
)) {
1512 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1516 if (!loc_size_ok(rr
->loc
.vert_pre
)) {
1521 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1525 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1529 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1535 dns_packet_rewind(p
, pos
);
1536 rr
->unparseable
= true;
1542 r
= dns_packet_read_uint16(p
, &rr
->ds
.key_tag
, NULL
);
1546 r
= dns_packet_read_uint8(p
, &rr
->ds
.algorithm
, NULL
);
1550 r
= dns_packet_read_uint8(p
, &rr
->ds
.digest_type
, NULL
);
1554 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1555 &rr
->ds
.digest
, &rr
->ds
.digest_size
,
1560 if (rr
->ds
.digest_size
<= 0) {
1561 /* the accepted size depends on the algorithm, but for now
1562 just ensure that the value is greater than zero */
1568 case DNS_TYPE_SSHFP
:
1569 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1573 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1577 r
= dns_packet_read_memdup(p
, rdlength
- 2,
1578 &rr
->sshfp
.fingerprint
, &rr
->sshfp
.fingerprint_size
,
1581 if (rr
->sshfp
.fingerprint_size
<= 0) {
1582 /* the accepted size depends on the algorithm, but for now
1583 just ensure that the value is greater than zero */
1590 case DNS_TYPE_DNSKEY
: {
1594 r
= dns_packet_read_uint16(p
, &flags
, NULL
);
1598 r
= dnskey_parse_flags(rr
, flags
);
1602 r
= dns_packet_read_uint8(p
, &proto
, NULL
);
1606 /* protocol is required to be always 3 */
1612 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.algorithm
, NULL
);
1616 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1617 &rr
->dnskey
.key
, &rr
->dnskey
.key_size
,
1620 if (rr
->dnskey
.key_size
<= 0) {
1621 /* the accepted size depends on the algorithm, but for now
1622 just ensure that the value is greater than zero */
1630 case DNS_TYPE_RRSIG
:
1631 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.type_covered
, NULL
);
1635 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.algorithm
, NULL
);
1639 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.labels
, NULL
);
1643 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.original_ttl
, NULL
);
1647 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.expiration
, NULL
);
1651 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.inception
, NULL
);
1655 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.key_tag
, NULL
);
1659 r
= dns_packet_read_name(p
, &rr
->rrsig
.signer
, false, NULL
);
1663 r
= dns_packet_read_memdup(p
, offset
+ rdlength
- p
->rindex
,
1664 &rr
->rrsig
.signature
, &rr
->rrsig
.signature_size
,
1667 if (rr
->rrsig
.signature_size
<= 0) {
1668 /* the accepted size depends on the algorithm, but for now
1669 just ensure that the value is greater than zero */
1677 r
= dns_packet_read_name(p
, &rr
->nsec
.next_domain_name
, false, NULL
);
1681 r
= dns_packet_read_type_windows(p
, &rr
->nsec
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1685 /* The types bitmap must contain at least the NSEC record itself, so an empty bitmap means
1686 something went wrong */
1687 if (bitmap_isclear(rr
->nsec
.types
)) {
1694 case DNS_TYPE_NSEC3
: {
1697 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.algorithm
, NULL
);
1701 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.flags
, NULL
);
1705 r
= dns_packet_read_uint16(p
, &rr
->nsec3
.iterations
, NULL
);
1709 /* this may be zero */
1710 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1714 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.salt
, &rr
->nsec3
.salt_size
, NULL
);
1718 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1727 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.next_hashed_name
, &rr
->nsec3
.next_hashed_name_size
, NULL
);
1731 r
= dns_packet_read_type_windows(p
, &rr
->nsec3
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1735 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
1741 r
= dns_packet_read_memdup(p
, rdlength
, &rr
->generic
.data
, &rr
->generic
.size
, NULL
);
1748 if (p
->rindex
!= offset
+ rdlength
) {
1757 *start
= saved_rindex
;
1761 dns_packet_rewind(p
, saved_rindex
);
1765 int dns_packet_extract(DnsPacket
*p
) {
1766 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1767 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1768 size_t saved_rindex
;
1775 saved_rindex
= p
->rindex
;
1776 dns_packet_rewind(p
, DNS_PACKET_HEADER_SIZE
);
1778 n
= DNS_PACKET_QDCOUNT(p
);
1780 question
= dns_question_new(n
);
1786 for (i
= 0; i
< n
; i
++) {
1787 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1789 r
= dns_packet_read_key(p
, &key
, NULL
);
1793 r
= dns_question_add(question
, key
);
1799 n
= DNS_PACKET_RRCOUNT(p
);
1801 answer
= dns_answer_new(n
);
1807 for (i
= 0; i
< n
; i
++) {
1808 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1810 r
= dns_packet_read_rr(p
, &rr
, NULL
);
1814 r
= dns_answer_add(answer
, rr
, p
->ifindex
);
1820 p
->question
= question
;
1826 p
->extracted
= true;
1831 p
->rindex
= saved_rindex
;
1835 static const char* const dns_rcode_table
[_DNS_RCODE_MAX_DEFINED
] = {
1836 [DNS_RCODE_SUCCESS
] = "SUCCESS",
1837 [DNS_RCODE_FORMERR
] = "FORMERR",
1838 [DNS_RCODE_SERVFAIL
] = "SERVFAIL",
1839 [DNS_RCODE_NXDOMAIN
] = "NXDOMAIN",
1840 [DNS_RCODE_NOTIMP
] = "NOTIMP",
1841 [DNS_RCODE_REFUSED
] = "REFUSED",
1842 [DNS_RCODE_YXDOMAIN
] = "YXDOMAIN",
1843 [DNS_RCODE_YXRRSET
] = "YRRSET",
1844 [DNS_RCODE_NXRRSET
] = "NXRRSET",
1845 [DNS_RCODE_NOTAUTH
] = "NOTAUTH",
1846 [DNS_RCODE_NOTZONE
] = "NOTZONE",
1847 [DNS_RCODE_BADVERS
] = "BADVERS",
1848 [DNS_RCODE_BADKEY
] = "BADKEY",
1849 [DNS_RCODE_BADTIME
] = "BADTIME",
1850 [DNS_RCODE_BADMODE
] = "BADMODE",
1851 [DNS_RCODE_BADNAME
] = "BADNAME",
1852 [DNS_RCODE_BADALG
] = "BADALG",
1853 [DNS_RCODE_BADTRUNC
] = "BADTRUNC",
1855 DEFINE_STRING_TABLE_LOOKUP(dns_rcode
, int);
1857 static const char* const dns_protocol_table
[_DNS_PROTOCOL_MAX
] = {
1858 [DNS_PROTOCOL_DNS
] = "dns",
1859 [DNS_PROTOCOL_MDNS
] = "mdns",
1860 [DNS_PROTOCOL_LLMNR
] = "llmnr",
1862 DEFINE_STRING_TABLE_LOOKUP(dns_protocol
, DnsProtocol
);
1864 static const char* const dnssec_algorithm_table
[_DNSSEC_ALGORITHM_MAX_DEFINED
] = {
1865 [DNSSEC_ALGORITHM_RSAMD5
] = "RSAMD5",
1866 [DNSSEC_ALGORITHM_DH
] = "DH",
1867 [DNSSEC_ALGORITHM_DSA
] = "DSA",
1868 [DNSSEC_ALGORITHM_ECC
] = "ECC",
1869 [DNSSEC_ALGORITHM_RSASHA1
] = "RSASHA1",
1870 [DNSSEC_ALGORITHM_DSA_NSEC3_SHA1
] = "DSA-NSEC3-SHA1",
1871 [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1
] = "RSASHA1-NSEC3-SHA1",
1872 [DNSSEC_ALGORITHM_INDIRECT
] = "INDIRECT",
1873 [DNSSEC_ALGORITHM_PRIVATEDNS
] = "PRIVATEDNS",
1874 [DNSSEC_ALGORITHM_PRIVATEOID
] = "PRIVATEOID",
1876 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm
, int);