1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include "unaligned.h"
26 #include "dns-domain.h"
27 #include "resolved-dns-packet.h"
29 int dns_packet_new(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
35 if (mtu
<= UDP_PACKET_HEADER_SIZE
)
36 a
= DNS_PACKET_SIZE_START
;
38 a
= mtu
- UDP_PACKET_HEADER_SIZE
;
40 if (a
< DNS_PACKET_HEADER_SIZE
)
41 a
= DNS_PACKET_HEADER_SIZE
;
43 /* round up to next page size */
44 a
= PAGE_ALIGN(ALIGN(sizeof(DnsPacket
)) + a
) - ALIGN(sizeof(DnsPacket
));
46 /* make sure we never allocate more than useful */
47 if (a
> DNS_PACKET_SIZE_MAX
)
48 a
= DNS_PACKET_SIZE_MAX
;
50 p
= malloc0(ALIGN(sizeof(DnsPacket
)) + a
);
54 p
->size
= p
->rindex
= DNS_PACKET_HEADER_SIZE
;
56 p
->protocol
= protocol
;
64 int dns_packet_new_query(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
71 r
= dns_packet_new(&p
, protocol
, mtu
);
75 h
= DNS_PACKET_HEADER(p
);
77 if (protocol
== DNS_PROTOCOL_LLMNR
)
78 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
88 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
92 1 /* rd (ask for recursion) */,
102 DnsPacket
*dns_packet_ref(DnsPacket
*p
) {
107 assert(p
->n_ref
> 0);
112 static void dns_packet_free(DnsPacket
*p
) {
117 dns_question_unref(p
->question
);
118 dns_answer_unref(p
->answer
);
120 while ((s
= hashmap_steal_first_key(p
->names
)))
122 hashmap_free(p
->names
);
128 DnsPacket
*dns_packet_unref(DnsPacket
*p
) {
132 assert(p
->n_ref
> 0);
142 int dns_packet_validate(DnsPacket
*p
) {
145 if (p
->size
< DNS_PACKET_HEADER_SIZE
)
148 if (p
->size
> DNS_PACKET_SIZE_MAX
)
154 int dns_packet_validate_reply(DnsPacket
*p
) {
159 r
= dns_packet_validate(p
);
163 if (DNS_PACKET_QR(p
) != 1)
166 if (DNS_PACKET_OPCODE(p
) != 0)
169 switch (p
->protocol
) {
170 case DNS_PROTOCOL_LLMNR
:
171 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
172 if (DNS_PACKET_QDCOUNT(p
) != 1)
184 int dns_packet_validate_query(DnsPacket
*p
) {
189 r
= dns_packet_validate(p
);
193 if (DNS_PACKET_QR(p
) != 0)
196 if (DNS_PACKET_OPCODE(p
) != 0)
199 if (DNS_PACKET_TC(p
))
202 switch (p
->protocol
) {
203 case DNS_PROTOCOL_LLMNR
:
204 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
205 if (DNS_PACKET_QDCOUNT(p
) != 1)
208 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
209 if (DNS_PACKET_ANCOUNT(p
) > 0)
212 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
213 if (DNS_PACKET_NSCOUNT(p
) > 0)
225 static int dns_packet_extend(DnsPacket
*p
, size_t add
, void **ret
, size_t *start
) {
228 if (p
->size
+ add
> p
->allocated
) {
231 a
= PAGE_ALIGN((p
->size
+ add
) * 2);
232 if (a
> DNS_PACKET_SIZE_MAX
)
233 a
= DNS_PACKET_SIZE_MAX
;
235 if (p
->size
+ add
> a
)
241 d
= realloc(p
->_data
, a
);
247 p
->_data
= malloc(a
);
251 memcpy(p
->_data
, (uint8_t*) p
+ ALIGN(sizeof(DnsPacket
)), p
->size
);
252 memzero((uint8_t*) p
->_data
+ p
->size
, a
- p
->size
);
262 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->size
;
268 static void dns_packet_truncate(DnsPacket
*p
, size_t sz
) {
278 HASHMAP_FOREACH_KEY(n
, s
, p
->names
, i
) {
280 if (PTR_TO_SIZE(n
) < sz
)
283 hashmap_remove(p
->names
, s
);
290 int dns_packet_append_blob(DnsPacket
*p
, const void *d
, size_t l
, size_t *start
) {
296 r
= dns_packet_extend(p
, l
, &q
, start
);
304 int dns_packet_append_uint8(DnsPacket
*p
, uint8_t v
, size_t *start
) {
310 r
= dns_packet_extend(p
, sizeof(uint8_t), &d
, start
);
314 ((uint8_t*) d
)[0] = v
;
319 int dns_packet_append_uint16(DnsPacket
*p
, uint16_t v
, size_t *start
) {
325 r
= dns_packet_extend(p
, sizeof(uint16_t), &d
, start
);
329 unaligned_write_be16(d
, v
);
334 int dns_packet_append_uint32(DnsPacket
*p
, uint32_t v
, size_t *start
) {
340 r
= dns_packet_extend(p
, sizeof(uint32_t), &d
, start
);
344 unaligned_write_be32(d
, v
);
349 int dns_packet_append_string(DnsPacket
*p
, const char *s
, size_t *start
) {
361 r
= dns_packet_extend(p
, 1 + l
, &d
, start
);
365 ((uint8_t*) d
)[0] = (uint8_t) l
;
366 memcpy(((uint8_t*) d
) + 1, s
, l
);
371 int dns_packet_append_label(DnsPacket
*p
, const char *d
, size_t l
, size_t *start
) {
378 if (l
> DNS_LABEL_MAX
)
381 r
= dns_packet_extend(p
, 1 + l
, &w
, start
);
385 ((uint8_t*) w
)[0] = (uint8_t) l
;
386 memcpy(((uint8_t*) w
) + 1, d
, l
);
391 int dns_packet_append_name(DnsPacket
*p
, const char *name
,
392 bool allow_compression
, size_t *start
) {
399 saved_size
= p
->size
;
402 _cleanup_free_
char *s
= NULL
;
403 char label
[DNS_LABEL_MAX
];
407 if (allow_compression
)
408 n
= PTR_TO_SIZE(hashmap_get(p
->names
, name
));
413 r
= dns_packet_append_uint16(p
, 0xC000 | n
, NULL
);
427 r
= dns_label_unescape(&name
, label
, sizeof(label
));
431 if (p
->protocol
== DNS_PROTOCOL_DNS
)
432 k
= dns_label_apply_idna(label
, r
, label
, sizeof(label
));
434 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
442 r
= dns_packet_append_label(p
, label
, r
, &n
);
446 if (allow_compression
) {
447 r
= hashmap_ensure_allocated(&p
->names
, &dns_name_hash_ops
);
451 r
= hashmap_put(p
->names
, s
, SIZE_TO_PTR(n
));
459 r
= dns_packet_append_uint8(p
, 0, NULL
);
470 dns_packet_truncate(p
, saved_size
);
474 int dns_packet_append_key(DnsPacket
*p
, const DnsResourceKey
*k
, size_t *start
) {
481 saved_size
= p
->size
;
483 r
= dns_packet_append_name(p
, DNS_RESOURCE_KEY_NAME(k
), true, NULL
);
487 r
= dns_packet_append_uint16(p
, k
->type
, NULL
);
491 r
= dns_packet_append_uint16(p
, k
->class, NULL
);
501 dns_packet_truncate(p
, saved_size
);
505 static int dns_packet_append_type_window(DnsPacket
*p
, uint8_t window
, uint8_t length
, uint8_t *types
, size_t *start
) {
513 saved_size
= p
->size
;
515 r
= dns_packet_append_uint8(p
, window
, NULL
);
519 r
= dns_packet_append_uint8(p
, length
, NULL
);
523 r
= dns_packet_append_blob(p
, types
, length
, NULL
);
532 dns_packet_truncate(p
, saved_size
);
536 static int dns_packet_append_types(DnsPacket
*p
, Bitmap
*types
, size_t *start
) {
540 uint8_t bitmaps
[32] = {};
548 saved_size
= p
->size
;
550 BITMAP_FOREACH(n
, types
, i
) {
553 if ((n
>> 8) != window
&& bitmaps
[entry
/ 8] != 0) {
554 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
565 bitmaps
[entry
/ 8] |= 1 << (7 - (entry
% 8));
568 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
577 dns_packet_truncate(p
, saved_size
);
581 int dns_packet_append_rr(DnsPacket
*p
, const DnsResourceRecord
*rr
, size_t *start
) {
582 size_t saved_size
, rdlength_offset
, end
, rdlength
;
588 saved_size
= p
->size
;
590 r
= dns_packet_append_key(p
, rr
->key
, NULL
);
594 r
= dns_packet_append_uint32(p
, rr
->ttl
, NULL
);
598 /* Initially we write 0 here */
599 r
= dns_packet_append_uint16(p
, 0, &rdlength_offset
);
603 switch (rr
->unparseable
? _DNS_TYPE_INVALID
: rr
->key
->type
) {
606 r
= dns_packet_append_uint16(p
, rr
->srv
.priority
, NULL
);
610 r
= dns_packet_append_uint16(p
, rr
->srv
.weight
, NULL
);
614 r
= dns_packet_append_uint16(p
, rr
->srv
.port
, NULL
);
618 r
= dns_packet_append_name(p
, rr
->srv
.name
, true, NULL
);
625 r
= dns_packet_append_name(p
, rr
->ptr
.name
, true, NULL
);
629 r
= dns_packet_append_string(p
, rr
->hinfo
.cpu
, NULL
);
633 r
= dns_packet_append_string(p
, rr
->hinfo
.os
, NULL
);
636 case DNS_TYPE_SPF
: /* exactly the same as TXT */
640 if (strv_isempty(rr
->txt
.strings
)) {
641 /* RFC 6763, section 6.1 suggests to generate
642 * single empty string for an empty array. */
644 r
= dns_packet_append_string(p
, "", NULL
);
648 STRV_FOREACH(s
, rr
->txt
.strings
) {
649 r
= dns_packet_append_string(p
, *s
, NULL
);
660 r
= dns_packet_append_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
664 r
= dns_packet_append_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
668 r
= dns_packet_append_name(p
, rr
->soa
.mname
, true, NULL
);
672 r
= dns_packet_append_name(p
, rr
->soa
.rname
, true, NULL
);
676 r
= dns_packet_append_uint32(p
, rr
->soa
.serial
, NULL
);
680 r
= dns_packet_append_uint32(p
, rr
->soa
.refresh
, NULL
);
684 r
= dns_packet_append_uint32(p
, rr
->soa
.retry
, NULL
);
688 r
= dns_packet_append_uint32(p
, rr
->soa
.expire
, NULL
);
692 r
= dns_packet_append_uint32(p
, rr
->soa
.minimum
, NULL
);
696 r
= dns_packet_append_uint16(p
, rr
->mx
.priority
, NULL
);
700 r
= dns_packet_append_name(p
, rr
->mx
.exchange
, true, NULL
);
704 r
= dns_packet_append_uint8(p
, rr
->loc
.version
, NULL
);
708 r
= dns_packet_append_uint8(p
, rr
->loc
.size
, NULL
);
712 r
= dns_packet_append_uint8(p
, rr
->loc
.horiz_pre
, NULL
);
716 r
= dns_packet_append_uint8(p
, rr
->loc
.vert_pre
, NULL
);
720 r
= dns_packet_append_uint32(p
, rr
->loc
.latitude
, NULL
);
724 r
= dns_packet_append_uint32(p
, rr
->loc
.longitude
, NULL
);
728 r
= dns_packet_append_uint32(p
, rr
->loc
.altitude
, NULL
);
732 r
= dns_packet_append_uint16(p
, rr
->ds
.key_tag
, NULL
);
736 r
= dns_packet_append_uint8(p
, rr
->ds
.algorithm
, NULL
);
740 r
= dns_packet_append_uint8(p
, rr
->ds
.digest_type
, NULL
);
744 r
= dns_packet_append_blob(p
, rr
->ds
.digest
, rr
->ds
.digest_size
, NULL
);
748 r
= dns_packet_append_uint8(p
, rr
->sshfp
.algorithm
, NULL
);
752 r
= dns_packet_append_uint8(p
, rr
->sshfp
.fptype
, NULL
);
756 r
= dns_packet_append_blob(p
, rr
->sshfp
.fingerprint
, rr
->sshfp
.fingerprint_size
, NULL
);
759 case DNS_TYPE_DNSKEY
:
760 r
= dns_packet_append_uint16(p
, dnskey_to_flags(rr
), NULL
);
764 r
= dns_packet_append_uint8(p
, 3u, NULL
);
768 r
= dns_packet_append_uint8(p
, rr
->dnskey
.algorithm
, NULL
);
772 r
= dns_packet_append_blob(p
, rr
->dnskey
.key
, rr
->dnskey
.key_size
, NULL
);
776 r
= dns_packet_append_uint16(p
, rr
->rrsig
.type_covered
, NULL
);
780 r
= dns_packet_append_uint8(p
, rr
->rrsig
.algorithm
, NULL
);
784 r
= dns_packet_append_uint8(p
, rr
->rrsig
.labels
, NULL
);
788 r
= dns_packet_append_uint32(p
, rr
->rrsig
.original_ttl
, NULL
);
792 r
= dns_packet_append_uint32(p
, rr
->rrsig
.expiration
, NULL
);
796 r
= dns_packet_append_uint32(p
, rr
->rrsig
.inception
, NULL
);
800 r
= dns_packet_append_uint16(p
, rr
->rrsig
.key_tag
, NULL
);
804 r
= dns_packet_append_name(p
, rr
->rrsig
.signer
, false, NULL
);
808 r
= dns_packet_append_blob(p
, rr
->rrsig
.signature
, rr
->rrsig
.signature_size
, NULL
);
812 r
= dns_packet_append_name(p
, rr
->nsec
.next_domain_name
, false, NULL
);
816 r
= dns_packet_append_types(p
, rr
->nsec
.types
, NULL
);
822 r
= dns_packet_append_uint8(p
, rr
->nsec3
.algorithm
, NULL
);
826 r
= dns_packet_append_uint8(p
, rr
->nsec3
.flags
, NULL
);
830 r
= dns_packet_append_uint16(p
, rr
->nsec3
.iterations
, NULL
);
834 r
= dns_packet_append_uint8(p
, rr
->nsec3
.salt_size
, NULL
);
838 r
= dns_packet_append_blob(p
, rr
->nsec3
.salt
, rr
->nsec3
.salt_size
, NULL
);
842 r
= dns_packet_append_uint8(p
, rr
->nsec3
.next_hashed_name_size
, NULL
);
846 r
= dns_packet_append_blob(p
, rr
->nsec3
.next_hashed_name
, rr
->nsec3
.next_hashed_name_size
, NULL
);
850 r
= dns_packet_append_types(p
, rr
->nsec3
.types
, NULL
);
855 case _DNS_TYPE_INVALID
: /* unparseable */
858 r
= dns_packet_append_blob(p
, rr
->generic
.data
, rr
->generic
.size
, NULL
);
864 /* Let's calculate the actual data size and update the field */
865 rdlength
= p
->size
- rdlength_offset
- sizeof(uint16_t);
866 if (rdlength
> 0xFFFF) {
872 p
->size
= rdlength_offset
;
873 r
= dns_packet_append_uint16(p
, rdlength
, NULL
);
884 dns_packet_truncate(p
, saved_size
);
889 int dns_packet_read(DnsPacket
*p
, size_t sz
, const void **ret
, size_t *start
) {
892 if (p
->rindex
+ sz
> p
->size
)
896 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->rindex
;
905 void dns_packet_rewind(DnsPacket
*p
, size_t idx
) {
907 assert(idx
<= p
->size
);
908 assert(idx
>= DNS_PACKET_HEADER_SIZE
);
913 int dns_packet_read_blob(DnsPacket
*p
, void *d
, size_t sz
, size_t *start
) {
920 r
= dns_packet_read(p
, sz
, &q
, start
);
928 static int dns_packet_read_memdup(
929 DnsPacket
*p
, size_t size
,
930 void **ret
, size_t *ret_size
,
940 r
= dns_packet_read(p
, size
, &src
, &start
);
949 copy
= memdup(src
, size
);
964 int dns_packet_read_uint8(DnsPacket
*p
, uint8_t *ret
, size_t *start
) {
970 r
= dns_packet_read(p
, sizeof(uint8_t), &d
, start
);
974 *ret
= ((uint8_t*) d
)[0];
978 int dns_packet_read_uint16(DnsPacket
*p
, uint16_t *ret
, size_t *start
) {
984 r
= dns_packet_read(p
, sizeof(uint16_t), &d
, start
);
988 *ret
= unaligned_read_be16(d
);
993 int dns_packet_read_uint32(DnsPacket
*p
, uint32_t *ret
, size_t *start
) {
999 r
= dns_packet_read(p
, sizeof(uint32_t), &d
, start
);
1003 *ret
= unaligned_read_be32(d
);
1008 int dns_packet_read_string(DnsPacket
*p
, char **ret
, size_t *start
) {
1009 size_t saved_rindex
;
1017 saved_rindex
= p
->rindex
;
1019 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1023 r
= dns_packet_read(p
, c
, &d
, NULL
);
1027 if (memchr(d
, 0, c
)) {
1038 if (!utf8_is_valid(t
)) {
1047 *start
= saved_rindex
;
1052 dns_packet_rewind(p
, saved_rindex
);
1056 int dns_packet_read_name(DnsPacket
*p
, char **_ret
,
1057 bool allow_compression
, size_t *start
) {
1058 size_t saved_rindex
, after_rindex
= 0, jump_barrier
;
1059 _cleanup_free_
char *ret
= NULL
;
1060 size_t n
= 0, allocated
= 0;
1067 saved_rindex
= p
->rindex
;
1068 jump_barrier
= p
->rindex
;
1073 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1081 _cleanup_free_
char *t
= NULL
;
1085 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
1089 r
= dns_label_escape(label
, c
, &t
);
1093 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ strlen(t
) + 1)) {
1103 memcpy(ret
+ n
, t
, r
);
1106 } else if (allow_compression
&& (c
& 0xc0) == 0xc0) {
1110 r
= dns_packet_read_uint8(p
, &d
, NULL
);
1114 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
1115 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= jump_barrier
) {
1120 if (after_rindex
== 0)
1121 after_rindex
= p
->rindex
;
1123 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1132 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1)) {
1139 if (after_rindex
!= 0)
1140 p
->rindex
= after_rindex
;
1146 *start
= saved_rindex
;
1151 dns_packet_rewind(p
, saved_rindex
);
1155 static int dns_packet_read_type_window(DnsPacket
*p
, Bitmap
**types
, size_t *start
) {
1158 const uint8_t *bitmap
;
1162 size_t saved_rindex
;
1168 saved_rindex
= p
->rindex
;
1170 r
= bitmap_ensure_allocated(types
);
1174 r
= dns_packet_read_uint8(p
, &window
, NULL
);
1178 r
= dns_packet_read_uint8(p
, &length
, NULL
);
1182 if (length
== 0 || length
> 32)
1185 r
= dns_packet_read(p
, length
, (const void **)&bitmap
, NULL
);
1189 for (i
= 0; i
< length
; i
++) {
1190 uint8_t bitmask
= 1 << 7;
1201 if (bitmap
[i
] & bitmask
) {
1204 n
= (uint16_t) window
<< 8 | (uint16_t) bit
;
1206 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1207 if (dns_type_is_pseudo(n
))
1210 r
= bitmap_set(*types
, n
);
1224 *start
= saved_rindex
;
1228 dns_packet_rewind(p
, saved_rindex
);
1232 static int dns_packet_read_type_windows(DnsPacket
*p
, Bitmap
**types
, size_t size
, size_t *start
) {
1233 size_t saved_rindex
;
1236 saved_rindex
= p
->rindex
;
1238 while (p
->rindex
< saved_rindex
+ size
) {
1239 r
= dns_packet_read_type_window(p
, types
, NULL
);
1243 /* don't read past end of current RR */
1244 if (p
->rindex
> saved_rindex
+ size
) {
1250 if (p
->rindex
!= saved_rindex
+ size
) {
1256 *start
= saved_rindex
;
1260 dns_packet_rewind(p
, saved_rindex
);
1264 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, size_t *start
) {
1265 _cleanup_free_
char *name
= NULL
;
1266 uint16_t class, type
;
1267 DnsResourceKey
*key
;
1268 size_t saved_rindex
;
1274 saved_rindex
= p
->rindex
;
1276 r
= dns_packet_read_name(p
, &name
, true, NULL
);
1280 r
= dns_packet_read_uint16(p
, &type
, NULL
);
1284 r
= dns_packet_read_uint16(p
, &class, NULL
);
1288 key
= dns_resource_key_new_consume(class, type
, name
);
1298 *start
= saved_rindex
;
1302 dns_packet_rewind(p
, saved_rindex
);
1306 static bool loc_size_ok(uint8_t size
) {
1307 uint8_t m
= size
>> 4, e
= size
& 0xF;
1309 return m
<= 9 && e
<= 9 && (m
> 0 || e
== 0);
1312 static int dnskey_parse_flags(DnsResourceRecord
*rr
, uint16_t flags
) {
1315 if (flags
& ~(DNSKEY_FLAG_SEP
| DNSKEY_FLAG_ZONE_KEY
))
1318 rr
->dnskey
.zone_key_flag
= flags
& DNSKEY_FLAG_ZONE_KEY
;
1319 rr
->dnskey
.sep_flag
= flags
& DNSKEY_FLAG_SEP
;
1323 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, size_t *start
) {
1324 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1325 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1326 size_t saved_rindex
, offset
;
1333 saved_rindex
= p
->rindex
;
1335 r
= dns_packet_read_key(p
, &key
, NULL
);
1339 if (key
->class == DNS_CLASS_ANY
||
1340 key
->type
== DNS_TYPE_ANY
) {
1345 rr
= dns_resource_record_new(key
);
1351 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
1355 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
1359 if (p
->rindex
+ rdlength
> p
->size
) {
1366 switch (rr
->key
->type
) {
1369 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
1372 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
1375 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
1378 r
= dns_packet_read_name(p
, &rr
->srv
.name
, true, NULL
);
1383 case DNS_TYPE_CNAME
:
1384 case DNS_TYPE_DNAME
:
1385 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, true, NULL
);
1388 case DNS_TYPE_HINFO
:
1389 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1393 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1396 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1398 if (rdlength
<= 0) {
1399 /* RFC 6763, section 6.1 suggests to treat
1400 * empty TXT RRs as equivalent to a TXT record
1401 * with a single empty string. */
1403 r
= strv_extend(&rr
->txt
.strings
, "");
1407 while (p
->rindex
< offset
+ rdlength
) {
1410 r
= dns_packet_read_string(p
, &s
, NULL
);
1414 r
= strv_consume(&rr
->txt
.strings
, s
);
1424 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1428 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1432 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, true, NULL
);
1436 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, true, NULL
);
1440 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1444 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1448 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1452 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1456 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1460 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1464 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, true, NULL
);
1467 case DNS_TYPE_LOC
: {
1471 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1476 rr
->loc
.version
= t
;
1478 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1482 if (!loc_size_ok(rr
->loc
.size
)) {
1487 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1491 if (!loc_size_ok(rr
->loc
.horiz_pre
)) {
1496 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1500 if (!loc_size_ok(rr
->loc
.vert_pre
)) {
1505 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1509 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1513 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1519 dns_packet_rewind(p
, pos
);
1520 rr
->unparseable
= true;
1526 r
= dns_packet_read_uint16(p
, &rr
->ds
.key_tag
, NULL
);
1530 r
= dns_packet_read_uint8(p
, &rr
->ds
.algorithm
, NULL
);
1534 r
= dns_packet_read_uint8(p
, &rr
->ds
.digest_type
, NULL
);
1538 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1539 &rr
->ds
.digest
, &rr
->ds
.digest_size
,
1544 if (rr
->ds
.digest_size
<= 0) {
1545 /* the accepted size depends on the algorithm, but for now
1546 just ensure that the value is greater than zero */
1552 case DNS_TYPE_SSHFP
:
1553 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1557 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1561 r
= dns_packet_read_memdup(p
, rdlength
- 2,
1562 &rr
->sshfp
.fingerprint
, &rr
->sshfp
.fingerprint_size
,
1565 if (rr
->sshfp
.fingerprint_size
<= 0) {
1566 /* the accepted size depends on the algorithm, but for now
1567 just ensure that the value is greater than zero */
1574 case DNS_TYPE_DNSKEY
: {
1578 r
= dns_packet_read_uint16(p
, &flags
, NULL
);
1582 r
= dnskey_parse_flags(rr
, flags
);
1586 r
= dns_packet_read_uint8(p
, &proto
, NULL
);
1590 /* protocol is required to be always 3 */
1596 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.algorithm
, NULL
);
1600 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1601 &rr
->dnskey
.key
, &rr
->dnskey
.key_size
,
1604 if (rr
->dnskey
.key_size
<= 0) {
1605 /* the accepted size depends on the algorithm, but for now
1606 just ensure that the value is greater than zero */
1614 case DNS_TYPE_RRSIG
:
1615 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.type_covered
, NULL
);
1619 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.algorithm
, NULL
);
1623 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.labels
, NULL
);
1627 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.original_ttl
, NULL
);
1631 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.expiration
, NULL
);
1635 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.inception
, NULL
);
1639 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.key_tag
, NULL
);
1643 r
= dns_packet_read_name(p
, &rr
->rrsig
.signer
, false, NULL
);
1647 r
= dns_packet_read_memdup(p
, offset
+ rdlength
- p
->rindex
,
1648 &rr
->rrsig
.signature
, &rr
->rrsig
.signature_size
,
1651 if (rr
->rrsig
.signature_size
<= 0) {
1652 /* the accepted size depends on the algorithm, but for now
1653 just ensure that the value is greater than zero */
1661 r
= dns_packet_read_name(p
, &rr
->nsec
.next_domain_name
, false, NULL
);
1665 r
= dns_packet_read_type_windows(p
, &rr
->nsec
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1669 /* The types bitmap must contain at least the NSEC record itself, so an empty bitmap means
1670 something went wrong */
1671 if (bitmap_isclear(rr
->nsec
.types
)) {
1678 case DNS_TYPE_NSEC3
: {
1681 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.algorithm
, NULL
);
1685 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.flags
, NULL
);
1689 r
= dns_packet_read_uint16(p
, &rr
->nsec3
.iterations
, NULL
);
1693 /* this may be zero */
1694 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1698 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.salt
, &rr
->nsec3
.salt_size
, NULL
);
1702 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1711 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.next_hashed_name
, &rr
->nsec3
.next_hashed_name_size
, NULL
);
1715 r
= dns_packet_read_type_windows(p
, &rr
->nsec
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1719 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
1725 r
= dns_packet_read_memdup(p
, rdlength
, &rr
->generic
.data
, &rr
->generic
.size
, NULL
);
1732 if (p
->rindex
!= offset
+ rdlength
) {
1741 *start
= saved_rindex
;
1745 dns_packet_rewind(p
, saved_rindex
);
1749 int dns_packet_extract(DnsPacket
*p
) {
1750 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1751 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1752 size_t saved_rindex
;
1759 saved_rindex
= p
->rindex
;
1760 dns_packet_rewind(p
, DNS_PACKET_HEADER_SIZE
);
1762 n
= DNS_PACKET_QDCOUNT(p
);
1764 question
= dns_question_new(n
);
1770 for (i
= 0; i
< n
; i
++) {
1771 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1773 r
= dns_packet_read_key(p
, &key
, NULL
);
1777 r
= dns_question_add(question
, key
);
1783 n
= DNS_PACKET_RRCOUNT(p
);
1785 answer
= dns_answer_new(n
);
1791 for (i
= 0; i
< n
; i
++) {
1792 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1794 r
= dns_packet_read_rr(p
, &rr
, NULL
);
1798 r
= dns_answer_add(answer
, rr
);
1804 p
->question
= question
;
1810 p
->extracted
= true;
1815 p
->rindex
= saved_rindex
;
1819 static const char* const dns_rcode_table
[_DNS_RCODE_MAX_DEFINED
] = {
1820 [DNS_RCODE_SUCCESS
] = "SUCCESS",
1821 [DNS_RCODE_FORMERR
] = "FORMERR",
1822 [DNS_RCODE_SERVFAIL
] = "SERVFAIL",
1823 [DNS_RCODE_NXDOMAIN
] = "NXDOMAIN",
1824 [DNS_RCODE_NOTIMP
] = "NOTIMP",
1825 [DNS_RCODE_REFUSED
] = "REFUSED",
1826 [DNS_RCODE_YXDOMAIN
] = "YXDOMAIN",
1827 [DNS_RCODE_YXRRSET
] = "YRRSET",
1828 [DNS_RCODE_NXRRSET
] = "NXRRSET",
1829 [DNS_RCODE_NOTAUTH
] = "NOTAUTH",
1830 [DNS_RCODE_NOTZONE
] = "NOTZONE",
1831 [DNS_RCODE_BADVERS
] = "BADVERS",
1832 [DNS_RCODE_BADKEY
] = "BADKEY",
1833 [DNS_RCODE_BADTIME
] = "BADTIME",
1834 [DNS_RCODE_BADMODE
] = "BADMODE",
1835 [DNS_RCODE_BADNAME
] = "BADNAME",
1836 [DNS_RCODE_BADALG
] = "BADALG",
1837 [DNS_RCODE_BADTRUNC
] = "BADTRUNC",
1839 DEFINE_STRING_TABLE_LOOKUP(dns_rcode
, int);
1841 static const char* const dns_protocol_table
[_DNS_PROTOCOL_MAX
] = {
1842 [DNS_PROTOCOL_DNS
] = "dns",
1843 [DNS_PROTOCOL_MDNS
] = "mdns",
1844 [DNS_PROTOCOL_LLMNR
] = "llmnr",
1846 DEFINE_STRING_TABLE_LOOKUP(dns_protocol
, DnsProtocol
);
1848 static const char* const dnssec_algorithm_table
[_DNSSEC_ALGORITHM_MAX_DEFINED
] = {
1849 [DNSSEC_ALGORITHM_RSAMD5
] = "RSAMD5",
1850 [DNSSEC_ALGORITHM_DH
] = "DH",
1851 [DNSSEC_ALGORITHM_DSA
] = "DSA",
1852 [DNSSEC_ALGORITHM_ECC
] = "ECC",
1853 [DNSSEC_ALGORITHM_RSASHA1
] = "RSASHA1",
1854 [DNSSEC_ALGORITHM_DSA_NSEC3_SHA1
] = "DSA-NSEC3-SHA1",
1855 [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1
] = "RSASHA1-NSEC3-SHA1",
1856 [DNSSEC_ALGORITHM_INDIRECT
] = "INDIRECT",
1857 [DNSSEC_ALGORITHM_PRIVATEDNS
] = "PRIVATEDNS",
1858 [DNSSEC_ALGORITHM_PRIVATEOID
] = "PRIVATEOID",
1860 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm
, int);