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(s
, n
, 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
) {
512 saved_size
= p
->size
;
516 r
= dns_packet_append_uint8(p
, window
, NULL
);
520 r
= dns_packet_append_uint8(p
, length
, NULL
);
524 r
= dns_packet_append_blob(p
, types
, length
, NULL
);
534 dns_packet_truncate(p
, saved_size
);
538 static int dns_packet_append_types(DnsPacket
*p
, Bitmap
*types
, size_t *start
) {
542 uint8_t bitmaps
[32] = {};
550 saved_size
= p
->size
;
552 BITMAP_FOREACH(n
, types
, i
) {
557 if ((n
<< 8) != window
) {
558 r
= dns_packet_append_type_window(p
, window
, len
, bitmaps
, NULL
);
573 bitmaps
[entry
/ 8] |= 1 << (7 - (entry
% 8));
576 r
= dns_packet_append_type_window(p
, window
, len
, 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(DnsPacket
*p
, char **_ret
,
1065 bool allow_compression
, size_t *start
) {
1066 size_t saved_rindex
, after_rindex
= 0, jump_barrier
;
1067 _cleanup_free_
char *ret
= NULL
;
1068 size_t n
= 0, allocated
= 0;
1075 saved_rindex
= p
->rindex
;
1076 jump_barrier
= p
->rindex
;
1081 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1089 _cleanup_free_
char *t
= NULL
;
1093 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
1097 r
= dns_label_escape(label
, c
, &t
);
1101 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ strlen(t
) + 1)) {
1111 memcpy(ret
+ n
, t
, r
);
1114 } else if (allow_compression
&& (c
& 0xc0) == 0xc0) {
1118 r
= dns_packet_read_uint8(p
, &d
, NULL
);
1122 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
1123 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= jump_barrier
) {
1128 if (after_rindex
== 0)
1129 after_rindex
= p
->rindex
;
1131 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1140 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1)) {
1147 if (after_rindex
!= 0)
1148 p
->rindex
= after_rindex
;
1154 *start
= saved_rindex
;
1159 dns_packet_rewind(p
, saved_rindex
);
1163 static int dns_packet_read_type_window(DnsPacket
*p
, Bitmap
**types
, size_t *start
) {
1166 const uint8_t *bitmap
;
1169 size_t saved_rindex
;
1175 saved_rindex
= p
->rindex
;
1177 r
= bitmap_ensure_allocated(types
);
1181 r
= dns_packet_read_uint8(p
, &window
, NULL
);
1185 r
= dns_packet_read_uint8(p
, &length
, NULL
);
1189 if (length
== 0 || length
> 32)
1192 r
= dns_packet_read(p
, length
, (const void **)&bitmap
, NULL
);
1196 for (i
= 0; i
< length
; i
++) {
1197 uint8_t bitmask
= 1 << 7;
1208 if (bitmap
[i
] & bitmask
) {
1211 /* XXX: ignore pseudo-types? see RFC4034 section 4.1.2 */
1212 n
= (uint16_t) window
<< 8 | (uint16_t) bit
;
1214 r
= bitmap_set(*types
, n
);
1228 *start
= saved_rindex
;
1232 dns_packet_rewind(p
, saved_rindex
);
1236 static int dns_packet_read_type_windows(DnsPacket
*p
, Bitmap
**types
, size_t size
, size_t *start
) {
1237 size_t saved_rindex
;
1240 saved_rindex
= p
->rindex
;
1242 while (p
->rindex
< saved_rindex
+ size
) {
1243 r
= dns_packet_read_type_window(p
, types
, NULL
);
1247 /* don't read past end of current RR */
1248 if (p
->rindex
> saved_rindex
+ size
) {
1254 if (p
->rindex
!= saved_rindex
+ size
) {
1260 *start
= saved_rindex
;
1264 dns_packet_rewind(p
, saved_rindex
);
1268 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, size_t *start
) {
1269 _cleanup_free_
char *name
= NULL
;
1270 uint16_t class, type
;
1271 DnsResourceKey
*key
;
1272 size_t saved_rindex
;
1278 saved_rindex
= p
->rindex
;
1280 r
= dns_packet_read_name(p
, &name
, true, NULL
);
1284 r
= dns_packet_read_uint16(p
, &type
, NULL
);
1288 r
= dns_packet_read_uint16(p
, &class, NULL
);
1292 key
= dns_resource_key_new_consume(class, type
, name
);
1302 *start
= saved_rindex
;
1306 dns_packet_rewind(p
, saved_rindex
);
1310 static bool loc_size_ok(uint8_t size
) {
1311 uint8_t m
= size
>> 4, e
= size
& 0xF;
1313 return m
<= 9 && e
<= 9 && (m
> 0 || e
== 0);
1316 static int dnskey_parse_flags(DnsResourceRecord
*rr
, uint16_t flags
) {
1319 if (flags
& ~(DNSKEY_FLAG_SEP
| DNSKEY_FLAG_ZONE_KEY
))
1322 rr
->dnskey
.zone_key_flag
= flags
& DNSKEY_FLAG_ZONE_KEY
;
1323 rr
->dnskey
.sep_flag
= flags
& DNSKEY_FLAG_SEP
;
1327 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, size_t *start
) {
1328 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1329 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1330 size_t saved_rindex
, offset
;
1337 saved_rindex
= p
->rindex
;
1339 r
= dns_packet_read_key(p
, &key
, NULL
);
1343 if (key
->class == DNS_CLASS_ANY
||
1344 key
->type
== DNS_TYPE_ANY
) {
1349 rr
= dns_resource_record_new(key
);
1355 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
1359 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
1363 if (p
->rindex
+ rdlength
> p
->size
) {
1370 switch (rr
->key
->type
) {
1373 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
1376 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
1379 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
1382 r
= dns_packet_read_name(p
, &rr
->srv
.name
, true, NULL
);
1387 case DNS_TYPE_CNAME
:
1388 case DNS_TYPE_DNAME
:
1389 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, true, NULL
);
1392 case DNS_TYPE_HINFO
:
1393 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1397 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1400 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1402 if (rdlength
<= 0) {
1403 /* RFC 6763, section 6.1 suggests to treat
1404 * empty TXT RRs as equivalent to a TXT record
1405 * with a single empty string. */
1407 r
= strv_extend(&rr
->txt
.strings
, "");
1411 while (p
->rindex
< offset
+ rdlength
) {
1414 r
= dns_packet_read_string(p
, &s
, NULL
);
1418 r
= strv_consume(&rr
->txt
.strings
, s
);
1428 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1432 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1436 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, true, NULL
);
1440 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, true, NULL
);
1444 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1448 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1452 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1456 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1460 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1464 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1468 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, true, NULL
);
1471 case DNS_TYPE_LOC
: {
1475 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1480 rr
->loc
.version
= t
;
1482 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1486 if (!loc_size_ok(rr
->loc
.size
)) {
1491 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1495 if (!loc_size_ok(rr
->loc
.horiz_pre
)) {
1500 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1504 if (!loc_size_ok(rr
->loc
.vert_pre
)) {
1509 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1513 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1517 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1523 dns_packet_rewind(p
, pos
);
1524 rr
->unparseable
= true;
1530 r
= dns_packet_read_uint16(p
, &rr
->ds
.key_tag
, NULL
);
1534 r
= dns_packet_read_uint8(p
, &rr
->ds
.algorithm
, NULL
);
1538 r
= dns_packet_read_uint8(p
, &rr
->ds
.digest_type
, NULL
);
1542 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1543 &rr
->ds
.digest
, &rr
->ds
.digest_size
,
1548 if (rr
->ds
.digest_size
<= 0) {
1549 /* the accepted size depends on the algorithm, but for now
1550 just ensure that the value is greater than zero */
1556 case DNS_TYPE_SSHFP
:
1557 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1561 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1565 r
= dns_packet_read_memdup(p
, rdlength
- 2,
1566 &rr
->sshfp
.fingerprint
, &rr
->sshfp
.fingerprint_size
,
1569 if (rr
->sshfp
.fingerprint_size
<= 0) {
1570 /* the accepted size depends on the algorithm, but for now
1571 just ensure that the value is greater than zero */
1578 case DNS_TYPE_DNSKEY
: {
1582 r
= dns_packet_read_uint16(p
, &flags
, NULL
);
1586 r
= dnskey_parse_flags(rr
, flags
);
1590 r
= dns_packet_read_uint8(p
, &proto
, NULL
);
1594 /* protocol is required to be always 3 */
1600 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.algorithm
, NULL
);
1604 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1605 &rr
->dnskey
.key
, &rr
->dnskey
.key_size
,
1608 if (rr
->dnskey
.key_size
<= 0) {
1609 /* the accepted size depends on the algorithm, but for now
1610 just ensure that the value is greater than zero */
1618 case DNS_TYPE_RRSIG
:
1619 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.type_covered
, NULL
);
1623 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.algorithm
, NULL
);
1627 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.labels
, NULL
);
1631 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.original_ttl
, NULL
);
1635 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.expiration
, NULL
);
1639 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.inception
, NULL
);
1643 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.key_tag
, NULL
);
1647 r
= dns_packet_read_name(p
, &rr
->rrsig
.signer
, false, NULL
);
1651 r
= dns_packet_read_memdup(p
, offset
+ rdlength
- p
->rindex
,
1652 &rr
->rrsig
.signature
, &rr
->rrsig
.signature_size
,
1655 if (rr
->rrsig
.signature_size
<= 0) {
1656 /* the accepted size depends on the algorithm, but for now
1657 just ensure that the value is greater than zero */
1665 r
= dns_packet_read_name(p
, &rr
->nsec
.next_domain_name
, false, NULL
);
1669 r
= dns_packet_read_type_windows(p
, &rr
->nsec
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1673 /* NSEC RRs with empty bitmpas makes no sense, but the RFC does not explicitly forbid them
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);