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 "dns-domain.h"
23 #include "resolved-dns-packet.h"
24 #include "string-table.h"
26 #include "unaligned.h"
30 int dns_packet_new(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
36 if (mtu
<= UDP_PACKET_HEADER_SIZE
)
37 a
= DNS_PACKET_SIZE_START
;
39 a
= mtu
- UDP_PACKET_HEADER_SIZE
;
41 if (a
< DNS_PACKET_HEADER_SIZE
)
42 a
= DNS_PACKET_HEADER_SIZE
;
44 /* round up to next page size */
45 a
= PAGE_ALIGN(ALIGN(sizeof(DnsPacket
)) + a
) - ALIGN(sizeof(DnsPacket
));
47 /* make sure we never allocate more than useful */
48 if (a
> DNS_PACKET_SIZE_MAX
)
49 a
= DNS_PACKET_SIZE_MAX
;
51 p
= malloc0(ALIGN(sizeof(DnsPacket
)) + a
);
55 p
->size
= p
->rindex
= DNS_PACKET_HEADER_SIZE
;
57 p
->protocol
= protocol
;
65 int dns_packet_new_query(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
72 r
= dns_packet_new(&p
, protocol
, mtu
);
76 h
= DNS_PACKET_HEADER(p
);
78 if (protocol
== DNS_PROTOCOL_LLMNR
)
79 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
89 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
93 1 /* rd (ask for recursion) */,
103 DnsPacket
*dns_packet_ref(DnsPacket
*p
) {
108 assert(p
->n_ref
> 0);
113 static void dns_packet_free(DnsPacket
*p
) {
118 dns_question_unref(p
->question
);
119 dns_answer_unref(p
->answer
);
121 while ((s
= hashmap_steal_first_key(p
->names
)))
123 hashmap_free(p
->names
);
129 DnsPacket
*dns_packet_unref(DnsPacket
*p
) {
133 assert(p
->n_ref
> 0);
143 int dns_packet_validate(DnsPacket
*p
) {
146 if (p
->size
< DNS_PACKET_HEADER_SIZE
)
149 if (p
->size
> DNS_PACKET_SIZE_MAX
)
155 int dns_packet_validate_reply(DnsPacket
*p
) {
160 r
= dns_packet_validate(p
);
164 if (DNS_PACKET_QR(p
) != 1)
167 if (DNS_PACKET_OPCODE(p
) != 0)
170 switch (p
->protocol
) {
171 case DNS_PROTOCOL_LLMNR
:
172 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
173 if (DNS_PACKET_QDCOUNT(p
) != 1)
185 int dns_packet_validate_query(DnsPacket
*p
) {
190 r
= dns_packet_validate(p
);
194 if (DNS_PACKET_QR(p
) != 0)
197 if (DNS_PACKET_OPCODE(p
) != 0)
200 if (DNS_PACKET_TC(p
))
203 switch (p
->protocol
) {
204 case DNS_PROTOCOL_LLMNR
:
205 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
206 if (DNS_PACKET_QDCOUNT(p
) != 1)
209 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
210 if (DNS_PACKET_ANCOUNT(p
) > 0)
213 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
214 if (DNS_PACKET_NSCOUNT(p
) > 0)
226 static int dns_packet_extend(DnsPacket
*p
, size_t add
, void **ret
, size_t *start
) {
229 if (p
->size
+ add
> p
->allocated
) {
232 a
= PAGE_ALIGN((p
->size
+ add
) * 2);
233 if (a
> DNS_PACKET_SIZE_MAX
)
234 a
= DNS_PACKET_SIZE_MAX
;
236 if (p
->size
+ add
> a
)
242 d
= realloc(p
->_data
, a
);
248 p
->_data
= malloc(a
);
252 memcpy(p
->_data
, (uint8_t*) p
+ ALIGN(sizeof(DnsPacket
)), p
->size
);
253 memzero((uint8_t*) p
->_data
+ p
->size
, a
- p
->size
);
263 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->size
;
269 static void dns_packet_truncate(DnsPacket
*p
, size_t sz
) {
279 HASHMAP_FOREACH_KEY(n
, s
, p
->names
, i
) {
281 if (PTR_TO_SIZE(n
) < sz
)
284 hashmap_remove(p
->names
, s
);
291 int dns_packet_append_blob(DnsPacket
*p
, const void *d
, size_t l
, size_t *start
) {
297 r
= dns_packet_extend(p
, l
, &q
, start
);
305 int dns_packet_append_uint8(DnsPacket
*p
, uint8_t v
, size_t *start
) {
311 r
= dns_packet_extend(p
, sizeof(uint8_t), &d
, start
);
315 ((uint8_t*) d
)[0] = v
;
320 int dns_packet_append_uint16(DnsPacket
*p
, uint16_t v
, size_t *start
) {
326 r
= dns_packet_extend(p
, sizeof(uint16_t), &d
, start
);
330 unaligned_write_be16(d
, v
);
335 int dns_packet_append_uint32(DnsPacket
*p
, uint32_t v
, size_t *start
) {
341 r
= dns_packet_extend(p
, sizeof(uint32_t), &d
, start
);
345 unaligned_write_be32(d
, v
);
350 int dns_packet_append_string(DnsPacket
*p
, const char *s
, size_t *start
) {
362 r
= dns_packet_extend(p
, 1 + l
, &d
, start
);
366 ((uint8_t*) d
)[0] = (uint8_t) l
;
367 memcpy(((uint8_t*) d
) + 1, s
, l
);
372 int dns_packet_append_label(DnsPacket
*p
, const char *d
, size_t l
, size_t *start
) {
379 if (l
> DNS_LABEL_MAX
)
382 r
= dns_packet_extend(p
, 1 + l
, &w
, start
);
386 ((uint8_t*) w
)[0] = (uint8_t) l
;
387 memcpy(((uint8_t*) w
) + 1, d
, l
);
392 int dns_packet_append_name(
395 bool allow_compression
,
404 if (p
->refuse_compression
)
405 allow_compression
= false;
407 saved_size
= p
->size
;
410 _cleanup_free_
char *s
= NULL
;
411 char label
[DNS_LABEL_MAX
];
415 if (allow_compression
)
416 n
= PTR_TO_SIZE(hashmap_get(p
->names
, name
));
421 r
= dns_packet_append_uint16(p
, 0xC000 | n
, NULL
);
435 r
= dns_label_unescape(&name
, label
, sizeof(label
));
439 if (p
->protocol
== DNS_PROTOCOL_DNS
)
440 k
= dns_label_apply_idna(label
, r
, label
, sizeof(label
));
442 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
450 r
= dns_packet_append_label(p
, label
, r
, &n
);
454 if (allow_compression
) {
455 r
= hashmap_ensure_allocated(&p
->names
, &dns_name_hash_ops
);
459 r
= hashmap_put(p
->names
, s
, SIZE_TO_PTR(n
));
467 r
= dns_packet_append_uint8(p
, 0, NULL
);
478 dns_packet_truncate(p
, saved_size
);
482 int dns_packet_append_key(DnsPacket
*p
, const DnsResourceKey
*k
, size_t *start
) {
489 saved_size
= p
->size
;
491 r
= dns_packet_append_name(p
, DNS_RESOURCE_KEY_NAME(k
), true, NULL
);
495 r
= dns_packet_append_uint16(p
, k
->type
, NULL
);
499 r
= dns_packet_append_uint16(p
, k
->class, NULL
);
509 dns_packet_truncate(p
, saved_size
);
513 static int dns_packet_append_type_window(DnsPacket
*p
, uint8_t window
, uint8_t length
, uint8_t *types
, size_t *start
) {
521 saved_size
= p
->size
;
523 r
= dns_packet_append_uint8(p
, window
, NULL
);
527 r
= dns_packet_append_uint8(p
, length
, NULL
);
531 r
= dns_packet_append_blob(p
, types
, length
, NULL
);
540 dns_packet_truncate(p
, saved_size
);
544 static int dns_packet_append_types(DnsPacket
*p
, Bitmap
*types
, size_t *start
) {
548 uint8_t bitmaps
[32] = {};
556 saved_size
= p
->size
;
558 BITMAP_FOREACH(n
, types
, i
) {
561 if ((n
>> 8) != window
&& bitmaps
[entry
/ 8] != 0) {
562 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
573 bitmaps
[entry
/ 8] |= 1 << (7 - (entry
% 8));
576 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
585 dns_packet_truncate(p
, saved_size
);
589 int dns_packet_append_rr(DnsPacket
*p
, const DnsResourceRecord
*rr
, size_t *start
) {
590 size_t saved_size
, rdlength_offset
, end
, rdlength
;
596 saved_size
= p
->size
;
598 r
= dns_packet_append_key(p
, rr
->key
, NULL
);
602 r
= dns_packet_append_uint32(p
, rr
->ttl
, NULL
);
606 /* Initially we write 0 here */
607 r
= dns_packet_append_uint16(p
, 0, &rdlength_offset
);
611 switch (rr
->unparseable
? _DNS_TYPE_INVALID
: rr
->key
->type
) {
614 r
= dns_packet_append_uint16(p
, rr
->srv
.priority
, NULL
);
618 r
= dns_packet_append_uint16(p
, rr
->srv
.weight
, NULL
);
622 r
= dns_packet_append_uint16(p
, rr
->srv
.port
, NULL
);
626 r
= dns_packet_append_name(p
, rr
->srv
.name
, true, NULL
);
633 r
= dns_packet_append_name(p
, rr
->ptr
.name
, true, NULL
);
637 r
= dns_packet_append_string(p
, rr
->hinfo
.cpu
, NULL
);
641 r
= dns_packet_append_string(p
, rr
->hinfo
.os
, NULL
);
644 case DNS_TYPE_SPF
: /* exactly the same as TXT */
648 if (strv_isempty(rr
->txt
.strings
)) {
649 /* RFC 6763, section 6.1 suggests to generate
650 * single empty string for an empty array. */
652 r
= dns_packet_append_string(p
, "", NULL
);
656 STRV_FOREACH(s
, rr
->txt
.strings
) {
657 r
= dns_packet_append_string(p
, *s
, NULL
);
668 r
= dns_packet_append_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
672 r
= dns_packet_append_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
676 r
= dns_packet_append_name(p
, rr
->soa
.mname
, true, NULL
);
680 r
= dns_packet_append_name(p
, rr
->soa
.rname
, true, NULL
);
684 r
= dns_packet_append_uint32(p
, rr
->soa
.serial
, NULL
);
688 r
= dns_packet_append_uint32(p
, rr
->soa
.refresh
, NULL
);
692 r
= dns_packet_append_uint32(p
, rr
->soa
.retry
, NULL
);
696 r
= dns_packet_append_uint32(p
, rr
->soa
.expire
, NULL
);
700 r
= dns_packet_append_uint32(p
, rr
->soa
.minimum
, NULL
);
704 r
= dns_packet_append_uint16(p
, rr
->mx
.priority
, NULL
);
708 r
= dns_packet_append_name(p
, rr
->mx
.exchange
, true, NULL
);
712 r
= dns_packet_append_uint8(p
, rr
->loc
.version
, NULL
);
716 r
= dns_packet_append_uint8(p
, rr
->loc
.size
, NULL
);
720 r
= dns_packet_append_uint8(p
, rr
->loc
.horiz_pre
, NULL
);
724 r
= dns_packet_append_uint8(p
, rr
->loc
.vert_pre
, NULL
);
728 r
= dns_packet_append_uint32(p
, rr
->loc
.latitude
, NULL
);
732 r
= dns_packet_append_uint32(p
, rr
->loc
.longitude
, NULL
);
736 r
= dns_packet_append_uint32(p
, rr
->loc
.altitude
, NULL
);
740 r
= dns_packet_append_uint16(p
, rr
->ds
.key_tag
, NULL
);
744 r
= dns_packet_append_uint8(p
, rr
->ds
.algorithm
, NULL
);
748 r
= dns_packet_append_uint8(p
, rr
->ds
.digest_type
, NULL
);
752 r
= dns_packet_append_blob(p
, rr
->ds
.digest
, rr
->ds
.digest_size
, NULL
);
756 r
= dns_packet_append_uint8(p
, rr
->sshfp
.algorithm
, NULL
);
760 r
= dns_packet_append_uint8(p
, rr
->sshfp
.fptype
, NULL
);
764 r
= dns_packet_append_blob(p
, rr
->sshfp
.fingerprint
, rr
->sshfp
.fingerprint_size
, NULL
);
767 case DNS_TYPE_DNSKEY
:
768 r
= dns_packet_append_uint16(p
, dnskey_to_flags(rr
), NULL
);
772 r
= dns_packet_append_uint8(p
, 3u, NULL
);
776 r
= dns_packet_append_uint8(p
, rr
->dnskey
.algorithm
, NULL
);
780 r
= dns_packet_append_blob(p
, rr
->dnskey
.key
, rr
->dnskey
.key_size
, NULL
);
784 r
= dns_packet_append_uint16(p
, rr
->rrsig
.type_covered
, NULL
);
788 r
= dns_packet_append_uint8(p
, rr
->rrsig
.algorithm
, NULL
);
792 r
= dns_packet_append_uint8(p
, rr
->rrsig
.labels
, NULL
);
796 r
= dns_packet_append_uint32(p
, rr
->rrsig
.original_ttl
, NULL
);
800 r
= dns_packet_append_uint32(p
, rr
->rrsig
.expiration
, NULL
);
804 r
= dns_packet_append_uint32(p
, rr
->rrsig
.inception
, NULL
);
808 r
= dns_packet_append_uint16(p
, rr
->rrsig
.key_tag
, NULL
);
812 r
= dns_packet_append_name(p
, rr
->rrsig
.signer
, false, NULL
);
816 r
= dns_packet_append_blob(p
, rr
->rrsig
.signature
, rr
->rrsig
.signature_size
, NULL
);
820 r
= dns_packet_append_name(p
, rr
->nsec
.next_domain_name
, false, NULL
);
824 r
= dns_packet_append_types(p
, rr
->nsec
.types
, NULL
);
830 r
= dns_packet_append_uint8(p
, rr
->nsec3
.algorithm
, NULL
);
834 r
= dns_packet_append_uint8(p
, rr
->nsec3
.flags
, NULL
);
838 r
= dns_packet_append_uint16(p
, rr
->nsec3
.iterations
, NULL
);
842 r
= dns_packet_append_uint8(p
, rr
->nsec3
.salt_size
, NULL
);
846 r
= dns_packet_append_blob(p
, rr
->nsec3
.salt
, rr
->nsec3
.salt_size
, NULL
);
850 r
= dns_packet_append_uint8(p
, rr
->nsec3
.next_hashed_name_size
, NULL
);
854 r
= dns_packet_append_blob(p
, rr
->nsec3
.next_hashed_name
, rr
->nsec3
.next_hashed_name_size
, NULL
);
858 r
= dns_packet_append_types(p
, rr
->nsec3
.types
, NULL
);
863 case _DNS_TYPE_INVALID
: /* unparseable */
866 r
= dns_packet_append_blob(p
, rr
->generic
.data
, rr
->generic
.size
, NULL
);
872 /* Let's calculate the actual data size and update the field */
873 rdlength
= p
->size
- rdlength_offset
- sizeof(uint16_t);
874 if (rdlength
> 0xFFFF) {
880 p
->size
= rdlength_offset
;
881 r
= dns_packet_append_uint16(p
, rdlength
, NULL
);
892 dns_packet_truncate(p
, saved_size
);
897 int dns_packet_read(DnsPacket
*p
, size_t sz
, const void **ret
, size_t *start
) {
900 if (p
->rindex
+ sz
> p
->size
)
904 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->rindex
;
913 void dns_packet_rewind(DnsPacket
*p
, size_t idx
) {
915 assert(idx
<= p
->size
);
916 assert(idx
>= DNS_PACKET_HEADER_SIZE
);
921 int dns_packet_read_blob(DnsPacket
*p
, void *d
, size_t sz
, size_t *start
) {
928 r
= dns_packet_read(p
, sz
, &q
, start
);
936 static int dns_packet_read_memdup(
937 DnsPacket
*p
, size_t size
,
938 void **ret
, size_t *ret_size
,
948 r
= dns_packet_read(p
, size
, &src
, &start
);
957 copy
= memdup(src
, size
);
972 int dns_packet_read_uint8(DnsPacket
*p
, uint8_t *ret
, size_t *start
) {
978 r
= dns_packet_read(p
, sizeof(uint8_t), &d
, start
);
982 *ret
= ((uint8_t*) d
)[0];
986 int dns_packet_read_uint16(DnsPacket
*p
, uint16_t *ret
, size_t *start
) {
992 r
= dns_packet_read(p
, sizeof(uint16_t), &d
, start
);
996 *ret
= unaligned_read_be16(d
);
1001 int dns_packet_read_uint32(DnsPacket
*p
, uint32_t *ret
, size_t *start
) {
1007 r
= dns_packet_read(p
, sizeof(uint32_t), &d
, start
);
1011 *ret
= unaligned_read_be32(d
);
1016 int dns_packet_read_string(DnsPacket
*p
, char **ret
, size_t *start
) {
1017 size_t saved_rindex
;
1025 saved_rindex
= p
->rindex
;
1027 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1031 r
= dns_packet_read(p
, c
, &d
, NULL
);
1035 if (memchr(d
, 0, c
)) {
1046 if (!utf8_is_valid(t
)) {
1055 *start
= saved_rindex
;
1060 dns_packet_rewind(p
, saved_rindex
);
1064 int dns_packet_read_name(
1067 bool allow_compression
,
1070 size_t saved_rindex
, after_rindex
= 0, jump_barrier
;
1071 _cleanup_free_
char *ret
= NULL
;
1072 size_t n
= 0, allocated
= 0;
1079 if (p
->refuse_compression
)
1080 allow_compression
= false;
1082 saved_rindex
= p
->rindex
;
1083 jump_barrier
= p
->rindex
;
1088 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1096 _cleanup_free_
char *t
= NULL
;
1100 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
1104 r
= dns_label_escape(label
, c
, &t
);
1108 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ strlen(t
) + 1)) {
1118 memcpy(ret
+ n
, t
, r
);
1121 } else if (allow_compression
&& (c
& 0xc0) == 0xc0) {
1125 r
= dns_packet_read_uint8(p
, &d
, NULL
);
1129 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
1130 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= jump_barrier
) {
1135 if (after_rindex
== 0)
1136 after_rindex
= p
->rindex
;
1138 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1147 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1)) {
1154 if (after_rindex
!= 0)
1155 p
->rindex
= after_rindex
;
1161 *start
= saved_rindex
;
1166 dns_packet_rewind(p
, saved_rindex
);
1170 static int dns_packet_read_type_window(DnsPacket
*p
, Bitmap
**types
, size_t *start
) {
1173 const uint8_t *bitmap
;
1177 size_t saved_rindex
;
1183 saved_rindex
= p
->rindex
;
1185 r
= bitmap_ensure_allocated(types
);
1189 r
= dns_packet_read_uint8(p
, &window
, NULL
);
1193 r
= dns_packet_read_uint8(p
, &length
, NULL
);
1197 if (length
== 0 || length
> 32)
1200 r
= dns_packet_read(p
, length
, (const void **)&bitmap
, NULL
);
1204 for (i
= 0; i
< length
; i
++) {
1205 uint8_t bitmask
= 1 << 7;
1216 if (bitmap
[i
] & bitmask
) {
1219 n
= (uint16_t) window
<< 8 | (uint16_t) bit
;
1221 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1222 if (dns_type_is_pseudo(n
))
1225 r
= bitmap_set(*types
, n
);
1239 *start
= saved_rindex
;
1243 dns_packet_rewind(p
, saved_rindex
);
1247 static int dns_packet_read_type_windows(DnsPacket
*p
, Bitmap
**types
, size_t size
, size_t *start
) {
1248 size_t saved_rindex
;
1251 saved_rindex
= p
->rindex
;
1253 while (p
->rindex
< saved_rindex
+ size
) {
1254 r
= dns_packet_read_type_window(p
, types
, NULL
);
1258 /* don't read past end of current RR */
1259 if (p
->rindex
> saved_rindex
+ size
) {
1265 if (p
->rindex
!= saved_rindex
+ size
) {
1271 *start
= saved_rindex
;
1275 dns_packet_rewind(p
, saved_rindex
);
1279 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, size_t *start
) {
1280 _cleanup_free_
char *name
= NULL
;
1281 uint16_t class, type
;
1282 DnsResourceKey
*key
;
1283 size_t saved_rindex
;
1289 saved_rindex
= p
->rindex
;
1291 r
= dns_packet_read_name(p
, &name
, true, NULL
);
1295 r
= dns_packet_read_uint16(p
, &type
, NULL
);
1299 r
= dns_packet_read_uint16(p
, &class, NULL
);
1303 key
= dns_resource_key_new_consume(class, type
, name
);
1313 *start
= saved_rindex
;
1317 dns_packet_rewind(p
, saved_rindex
);
1321 static bool loc_size_ok(uint8_t size
) {
1322 uint8_t m
= size
>> 4, e
= size
& 0xF;
1324 return m
<= 9 && e
<= 9 && (m
> 0 || e
== 0);
1327 static int dnskey_parse_flags(DnsResourceRecord
*rr
, uint16_t flags
) {
1330 if (flags
& ~(DNSKEY_FLAG_SEP
| DNSKEY_FLAG_ZONE_KEY
))
1333 rr
->dnskey
.zone_key_flag
= flags
& DNSKEY_FLAG_ZONE_KEY
;
1334 rr
->dnskey
.sep_flag
= flags
& DNSKEY_FLAG_SEP
;
1338 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, size_t *start
) {
1339 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1340 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1341 size_t saved_rindex
, offset
;
1348 saved_rindex
= p
->rindex
;
1350 r
= dns_packet_read_key(p
, &key
, NULL
);
1354 if (key
->class == DNS_CLASS_ANY
||
1355 key
->type
== DNS_TYPE_ANY
) {
1360 rr
= dns_resource_record_new(key
);
1366 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
1370 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
1374 if (p
->rindex
+ rdlength
> p
->size
) {
1381 switch (rr
->key
->type
) {
1384 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
1387 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
1390 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
1393 r
= dns_packet_read_name(p
, &rr
->srv
.name
, true, NULL
);
1398 case DNS_TYPE_CNAME
:
1399 case DNS_TYPE_DNAME
:
1400 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, true, NULL
);
1403 case DNS_TYPE_HINFO
:
1404 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1408 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1411 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1413 if (rdlength
<= 0) {
1414 /* RFC 6763, section 6.1 suggests to treat
1415 * empty TXT RRs as equivalent to a TXT record
1416 * with a single empty string. */
1418 r
= strv_extend(&rr
->txt
.strings
, "");
1422 while (p
->rindex
< offset
+ rdlength
) {
1425 r
= dns_packet_read_string(p
, &s
, NULL
);
1429 r
= strv_consume(&rr
->txt
.strings
, s
);
1439 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1443 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1447 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, true, NULL
);
1451 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, true, NULL
);
1455 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1459 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1463 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1467 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1471 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1475 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1479 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, true, NULL
);
1482 case DNS_TYPE_LOC
: {
1486 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1491 rr
->loc
.version
= t
;
1493 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1497 if (!loc_size_ok(rr
->loc
.size
)) {
1502 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1506 if (!loc_size_ok(rr
->loc
.horiz_pre
)) {
1511 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1515 if (!loc_size_ok(rr
->loc
.vert_pre
)) {
1520 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1524 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1528 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1534 dns_packet_rewind(p
, pos
);
1535 rr
->unparseable
= true;
1541 r
= dns_packet_read_uint16(p
, &rr
->ds
.key_tag
, NULL
);
1545 r
= dns_packet_read_uint8(p
, &rr
->ds
.algorithm
, NULL
);
1549 r
= dns_packet_read_uint8(p
, &rr
->ds
.digest_type
, NULL
);
1553 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1554 &rr
->ds
.digest
, &rr
->ds
.digest_size
,
1559 if (rr
->ds
.digest_size
<= 0) {
1560 /* the accepted size depends on the algorithm, but for now
1561 just ensure that the value is greater than zero */
1567 case DNS_TYPE_SSHFP
:
1568 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1572 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1576 r
= dns_packet_read_memdup(p
, rdlength
- 2,
1577 &rr
->sshfp
.fingerprint
, &rr
->sshfp
.fingerprint_size
,
1580 if (rr
->sshfp
.fingerprint_size
<= 0) {
1581 /* the accepted size depends on the algorithm, but for now
1582 just ensure that the value is greater than zero */
1589 case DNS_TYPE_DNSKEY
: {
1593 r
= dns_packet_read_uint16(p
, &flags
, NULL
);
1597 r
= dnskey_parse_flags(rr
, flags
);
1601 r
= dns_packet_read_uint8(p
, &proto
, NULL
);
1605 /* protocol is required to be always 3 */
1611 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.algorithm
, NULL
);
1615 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1616 &rr
->dnskey
.key
, &rr
->dnskey
.key_size
,
1619 if (rr
->dnskey
.key_size
<= 0) {
1620 /* the accepted size depends on the algorithm, but for now
1621 just ensure that the value is greater than zero */
1629 case DNS_TYPE_RRSIG
:
1630 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.type_covered
, NULL
);
1634 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.algorithm
, NULL
);
1638 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.labels
, NULL
);
1642 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.original_ttl
, NULL
);
1646 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.expiration
, NULL
);
1650 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.inception
, NULL
);
1654 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.key_tag
, NULL
);
1658 r
= dns_packet_read_name(p
, &rr
->rrsig
.signer
, false, NULL
);
1662 r
= dns_packet_read_memdup(p
, offset
+ rdlength
- p
->rindex
,
1663 &rr
->rrsig
.signature
, &rr
->rrsig
.signature_size
,
1666 if (rr
->rrsig
.signature_size
<= 0) {
1667 /* the accepted size depends on the algorithm, but for now
1668 just ensure that the value is greater than zero */
1676 r
= dns_packet_read_name(p
, &rr
->nsec
.next_domain_name
, false, NULL
);
1680 r
= dns_packet_read_type_windows(p
, &rr
->nsec
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1684 /* The types bitmap must contain at least the NSEC record itself, so an empty bitmap means
1685 something went wrong */
1686 if (bitmap_isclear(rr
->nsec
.types
)) {
1693 case DNS_TYPE_NSEC3
: {
1696 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.algorithm
, NULL
);
1700 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.flags
, NULL
);
1704 r
= dns_packet_read_uint16(p
, &rr
->nsec3
.iterations
, NULL
);
1708 /* this may be zero */
1709 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1713 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.salt
, &rr
->nsec3
.salt_size
, NULL
);
1717 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1726 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.next_hashed_name
, &rr
->nsec3
.next_hashed_name_size
, NULL
);
1730 r
= dns_packet_read_type_windows(p
, &rr
->nsec3
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1734 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
1740 r
= dns_packet_read_memdup(p
, rdlength
, &rr
->generic
.data
, &rr
->generic
.size
, NULL
);
1747 if (p
->rindex
!= offset
+ rdlength
) {
1756 *start
= saved_rindex
;
1760 dns_packet_rewind(p
, saved_rindex
);
1764 int dns_packet_extract(DnsPacket
*p
) {
1765 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1766 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1767 size_t saved_rindex
;
1774 saved_rindex
= p
->rindex
;
1775 dns_packet_rewind(p
, DNS_PACKET_HEADER_SIZE
);
1777 n
= DNS_PACKET_QDCOUNT(p
);
1779 question
= dns_question_new(n
);
1785 for (i
= 0; i
< n
; i
++) {
1786 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1788 r
= dns_packet_read_key(p
, &key
, NULL
);
1792 r
= dns_question_add(question
, key
);
1798 n
= DNS_PACKET_RRCOUNT(p
);
1800 answer
= dns_answer_new(n
);
1806 for (i
= 0; i
< n
; i
++) {
1807 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1809 r
= dns_packet_read_rr(p
, &rr
, NULL
);
1813 r
= dns_answer_add(answer
, rr
, p
->ifindex
);
1819 p
->question
= question
;
1825 p
->extracted
= true;
1830 p
->rindex
= saved_rindex
;
1834 static const char* const dns_rcode_table
[_DNS_RCODE_MAX_DEFINED
] = {
1835 [DNS_RCODE_SUCCESS
] = "SUCCESS",
1836 [DNS_RCODE_FORMERR
] = "FORMERR",
1837 [DNS_RCODE_SERVFAIL
] = "SERVFAIL",
1838 [DNS_RCODE_NXDOMAIN
] = "NXDOMAIN",
1839 [DNS_RCODE_NOTIMP
] = "NOTIMP",
1840 [DNS_RCODE_REFUSED
] = "REFUSED",
1841 [DNS_RCODE_YXDOMAIN
] = "YXDOMAIN",
1842 [DNS_RCODE_YXRRSET
] = "YRRSET",
1843 [DNS_RCODE_NXRRSET
] = "NXRRSET",
1844 [DNS_RCODE_NOTAUTH
] = "NOTAUTH",
1845 [DNS_RCODE_NOTZONE
] = "NOTZONE",
1846 [DNS_RCODE_BADVERS
] = "BADVERS",
1847 [DNS_RCODE_BADKEY
] = "BADKEY",
1848 [DNS_RCODE_BADTIME
] = "BADTIME",
1849 [DNS_RCODE_BADMODE
] = "BADMODE",
1850 [DNS_RCODE_BADNAME
] = "BADNAME",
1851 [DNS_RCODE_BADALG
] = "BADALG",
1852 [DNS_RCODE_BADTRUNC
] = "BADTRUNC",
1854 DEFINE_STRING_TABLE_LOOKUP(dns_rcode
, int);
1856 static const char* const dns_protocol_table
[_DNS_PROTOCOL_MAX
] = {
1857 [DNS_PROTOCOL_DNS
] = "dns",
1858 [DNS_PROTOCOL_MDNS
] = "mdns",
1859 [DNS_PROTOCOL_LLMNR
] = "llmnr",
1861 DEFINE_STRING_TABLE_LOOKUP(dns_protocol
, DnsProtocol
);
1863 static const char* const dnssec_algorithm_table
[_DNSSEC_ALGORITHM_MAX_DEFINED
] = {
1864 [DNSSEC_ALGORITHM_RSAMD5
] = "RSAMD5",
1865 [DNSSEC_ALGORITHM_DH
] = "DH",
1866 [DNSSEC_ALGORITHM_DSA
] = "DSA",
1867 [DNSSEC_ALGORITHM_ECC
] = "ECC",
1868 [DNSSEC_ALGORITHM_RSASHA1
] = "RSASHA1",
1869 [DNSSEC_ALGORITHM_DSA_NSEC3_SHA1
] = "DSA-NSEC3-SHA1",
1870 [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1
] = "RSASHA1-NSEC3-SHA1",
1871 [DNSSEC_ALGORITHM_INDIRECT
] = "INDIRECT",
1872 [DNSSEC_ALGORITHM_PRIVATEDNS
] = "PRIVATEDNS",
1873 [DNSSEC_ALGORITHM_PRIVATEOID
] = "PRIVATEOID",
1875 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm
, int);