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_raw_string(DnsPacket
*p
, const void *s
, size_t size
, size_t *start
) {
378 assert(s
|| size
== 0);
383 r
= dns_packet_extend(p
, 1 + size
, &d
, start
);
387 ((uint8_t*) d
)[0] = (uint8_t) size
;
390 memcpy(((uint8_t*) d
) + 1, s
, size
);
395 int dns_packet_append_label(DnsPacket
*p
, const char *d
, size_t l
, size_t *start
) {
402 if (l
> DNS_LABEL_MAX
)
405 r
= dns_packet_extend(p
, 1 + l
, &w
, start
);
409 ((uint8_t*) w
)[0] = (uint8_t) l
;
410 memcpy(((uint8_t*) w
) + 1, d
, l
);
415 int dns_packet_append_name(
418 bool allow_compression
,
427 if (p
->refuse_compression
)
428 allow_compression
= false;
430 saved_size
= p
->size
;
433 _cleanup_free_
char *s
= NULL
;
434 char label
[DNS_LABEL_MAX
];
438 if (allow_compression
)
439 n
= PTR_TO_SIZE(hashmap_get(p
->names
, name
));
444 r
= dns_packet_append_uint16(p
, 0xC000 | n
, NULL
);
458 r
= dns_label_unescape(&name
, label
, sizeof(label
));
462 if (p
->protocol
== DNS_PROTOCOL_DNS
)
463 k
= dns_label_apply_idna(label
, r
, label
, sizeof(label
));
465 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
473 r
= dns_packet_append_label(p
, label
, r
, &n
);
477 if (allow_compression
) {
478 r
= hashmap_ensure_allocated(&p
->names
, &dns_name_hash_ops
);
482 r
= hashmap_put(p
->names
, s
, SIZE_TO_PTR(n
));
490 r
= dns_packet_append_uint8(p
, 0, NULL
);
501 dns_packet_truncate(p
, saved_size
);
505 int dns_packet_append_key(DnsPacket
*p
, const DnsResourceKey
*k
, size_t *start
) {
512 saved_size
= p
->size
;
514 r
= dns_packet_append_name(p
, DNS_RESOURCE_KEY_NAME(k
), true, NULL
);
518 r
= dns_packet_append_uint16(p
, k
->type
, NULL
);
522 r
= dns_packet_append_uint16(p
, k
->class, NULL
);
532 dns_packet_truncate(p
, saved_size
);
536 static int dns_packet_append_type_window(DnsPacket
*p
, uint8_t window
, uint8_t length
, uint8_t *types
, size_t *start
) {
544 saved_size
= p
->size
;
546 r
= dns_packet_append_uint8(p
, window
, NULL
);
550 r
= dns_packet_append_uint8(p
, length
, NULL
);
554 r
= dns_packet_append_blob(p
, types
, length
, NULL
);
563 dns_packet_truncate(p
, saved_size
);
567 static int dns_packet_append_types(DnsPacket
*p
, Bitmap
*types
, size_t *start
) {
571 uint8_t bitmaps
[32] = {};
579 saved_size
= p
->size
;
581 BITMAP_FOREACH(n
, types
, i
) {
584 if ((n
>> 8) != window
&& bitmaps
[entry
/ 8] != 0) {
585 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
596 bitmaps
[entry
/ 8] |= 1 << (7 - (entry
% 8));
599 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
608 dns_packet_truncate(p
, saved_size
);
612 int dns_packet_append_rr(DnsPacket
*p
, const DnsResourceRecord
*rr
, size_t *start
) {
613 size_t saved_size
, rdlength_offset
, end
, rdlength
;
619 saved_size
= p
->size
;
621 r
= dns_packet_append_key(p
, rr
->key
, NULL
);
625 r
= dns_packet_append_uint32(p
, rr
->ttl
, NULL
);
629 /* Initially we write 0 here */
630 r
= dns_packet_append_uint16(p
, 0, &rdlength_offset
);
634 switch (rr
->unparseable
? _DNS_TYPE_INVALID
: rr
->key
->type
) {
637 r
= dns_packet_append_uint16(p
, rr
->srv
.priority
, NULL
);
641 r
= dns_packet_append_uint16(p
, rr
->srv
.weight
, NULL
);
645 r
= dns_packet_append_uint16(p
, rr
->srv
.port
, NULL
);
649 r
= dns_packet_append_name(p
, rr
->srv
.name
, true, NULL
);
656 r
= dns_packet_append_name(p
, rr
->ptr
.name
, true, NULL
);
660 r
= dns_packet_append_string(p
, rr
->hinfo
.cpu
, NULL
);
664 r
= dns_packet_append_string(p
, rr
->hinfo
.os
, NULL
);
667 case DNS_TYPE_SPF
: /* exactly the same as TXT */
670 if (!rr
->txt
.items
) {
671 /* RFC 6763, section 6.1 suggests to generate
672 * single empty string for an empty array. */
674 r
= dns_packet_append_raw_string(p
, NULL
, 0, NULL
);
680 LIST_FOREACH(items
, i
, rr
->txt
.items
) {
681 r
= dns_packet_append_raw_string(p
, i
->data
, i
->length
, NULL
);
691 r
= dns_packet_append_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
695 r
= dns_packet_append_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
699 r
= dns_packet_append_name(p
, rr
->soa
.mname
, true, NULL
);
703 r
= dns_packet_append_name(p
, rr
->soa
.rname
, true, NULL
);
707 r
= dns_packet_append_uint32(p
, rr
->soa
.serial
, NULL
);
711 r
= dns_packet_append_uint32(p
, rr
->soa
.refresh
, NULL
);
715 r
= dns_packet_append_uint32(p
, rr
->soa
.retry
, NULL
);
719 r
= dns_packet_append_uint32(p
, rr
->soa
.expire
, NULL
);
723 r
= dns_packet_append_uint32(p
, rr
->soa
.minimum
, NULL
);
727 r
= dns_packet_append_uint16(p
, rr
->mx
.priority
, NULL
);
731 r
= dns_packet_append_name(p
, rr
->mx
.exchange
, true, NULL
);
735 r
= dns_packet_append_uint8(p
, rr
->loc
.version
, NULL
);
739 r
= dns_packet_append_uint8(p
, rr
->loc
.size
, NULL
);
743 r
= dns_packet_append_uint8(p
, rr
->loc
.horiz_pre
, NULL
);
747 r
= dns_packet_append_uint8(p
, rr
->loc
.vert_pre
, NULL
);
751 r
= dns_packet_append_uint32(p
, rr
->loc
.latitude
, NULL
);
755 r
= dns_packet_append_uint32(p
, rr
->loc
.longitude
, NULL
);
759 r
= dns_packet_append_uint32(p
, rr
->loc
.altitude
, NULL
);
763 r
= dns_packet_append_uint16(p
, rr
->ds
.key_tag
, NULL
);
767 r
= dns_packet_append_uint8(p
, rr
->ds
.algorithm
, NULL
);
771 r
= dns_packet_append_uint8(p
, rr
->ds
.digest_type
, NULL
);
775 r
= dns_packet_append_blob(p
, rr
->ds
.digest
, rr
->ds
.digest_size
, NULL
);
779 r
= dns_packet_append_uint8(p
, rr
->sshfp
.algorithm
, NULL
);
783 r
= dns_packet_append_uint8(p
, rr
->sshfp
.fptype
, NULL
);
787 r
= dns_packet_append_blob(p
, rr
->sshfp
.fingerprint
, rr
->sshfp
.fingerprint_size
, NULL
);
790 case DNS_TYPE_DNSKEY
:
791 r
= dns_packet_append_uint16(p
, dnskey_to_flags(rr
), NULL
);
795 r
= dns_packet_append_uint8(p
, 3u, NULL
);
799 r
= dns_packet_append_uint8(p
, rr
->dnskey
.algorithm
, NULL
);
803 r
= dns_packet_append_blob(p
, rr
->dnskey
.key
, rr
->dnskey
.key_size
, NULL
);
807 r
= dns_packet_append_uint16(p
, rr
->rrsig
.type_covered
, NULL
);
811 r
= dns_packet_append_uint8(p
, rr
->rrsig
.algorithm
, NULL
);
815 r
= dns_packet_append_uint8(p
, rr
->rrsig
.labels
, NULL
);
819 r
= dns_packet_append_uint32(p
, rr
->rrsig
.original_ttl
, NULL
);
823 r
= dns_packet_append_uint32(p
, rr
->rrsig
.expiration
, NULL
);
827 r
= dns_packet_append_uint32(p
, rr
->rrsig
.inception
, NULL
);
831 r
= dns_packet_append_uint16(p
, rr
->rrsig
.key_tag
, NULL
);
835 r
= dns_packet_append_name(p
, rr
->rrsig
.signer
, false, NULL
);
839 r
= dns_packet_append_blob(p
, rr
->rrsig
.signature
, rr
->rrsig
.signature_size
, NULL
);
843 r
= dns_packet_append_name(p
, rr
->nsec
.next_domain_name
, false, NULL
);
847 r
= dns_packet_append_types(p
, rr
->nsec
.types
, NULL
);
853 r
= dns_packet_append_uint8(p
, rr
->nsec3
.algorithm
, NULL
);
857 r
= dns_packet_append_uint8(p
, rr
->nsec3
.flags
, NULL
);
861 r
= dns_packet_append_uint16(p
, rr
->nsec3
.iterations
, NULL
);
865 r
= dns_packet_append_uint8(p
, rr
->nsec3
.salt_size
, NULL
);
869 r
= dns_packet_append_blob(p
, rr
->nsec3
.salt
, rr
->nsec3
.salt_size
, NULL
);
873 r
= dns_packet_append_uint8(p
, rr
->nsec3
.next_hashed_name_size
, NULL
);
877 r
= dns_packet_append_blob(p
, rr
->nsec3
.next_hashed_name
, rr
->nsec3
.next_hashed_name_size
, NULL
);
881 r
= dns_packet_append_types(p
, rr
->nsec3
.types
, NULL
);
886 case _DNS_TYPE_INVALID
: /* unparseable */
889 r
= dns_packet_append_blob(p
, rr
->generic
.data
, rr
->generic
.size
, NULL
);
895 /* Let's calculate the actual data size and update the field */
896 rdlength
= p
->size
- rdlength_offset
- sizeof(uint16_t);
897 if (rdlength
> 0xFFFF) {
903 p
->size
= rdlength_offset
;
904 r
= dns_packet_append_uint16(p
, rdlength
, NULL
);
915 dns_packet_truncate(p
, saved_size
);
920 int dns_packet_read(DnsPacket
*p
, size_t sz
, const void **ret
, size_t *start
) {
923 if (p
->rindex
+ sz
> p
->size
)
927 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->rindex
;
936 void dns_packet_rewind(DnsPacket
*p
, size_t idx
) {
938 assert(idx
<= p
->size
);
939 assert(idx
>= DNS_PACKET_HEADER_SIZE
);
944 int dns_packet_read_blob(DnsPacket
*p
, void *d
, size_t sz
, size_t *start
) {
951 r
= dns_packet_read(p
, sz
, &q
, start
);
959 static int dns_packet_read_memdup(
960 DnsPacket
*p
, size_t size
,
961 void **ret
, size_t *ret_size
,
971 r
= dns_packet_read(p
, size
, &src
, &start
);
980 copy
= memdup(src
, size
);
995 int dns_packet_read_uint8(DnsPacket
*p
, uint8_t *ret
, size_t *start
) {
1001 r
= dns_packet_read(p
, sizeof(uint8_t), &d
, start
);
1005 *ret
= ((uint8_t*) d
)[0];
1009 int dns_packet_read_uint16(DnsPacket
*p
, uint16_t *ret
, size_t *start
) {
1015 r
= dns_packet_read(p
, sizeof(uint16_t), &d
, start
);
1019 *ret
= unaligned_read_be16(d
);
1024 int dns_packet_read_uint32(DnsPacket
*p
, uint32_t *ret
, size_t *start
) {
1030 r
= dns_packet_read(p
, sizeof(uint32_t), &d
, start
);
1034 *ret
= unaligned_read_be32(d
);
1039 int dns_packet_read_string(DnsPacket
*p
, char **ret
, size_t *start
) {
1040 size_t saved_rindex
;
1048 saved_rindex
= p
->rindex
;
1050 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1054 r
= dns_packet_read(p
, c
, &d
, NULL
);
1058 if (memchr(d
, 0, c
)) {
1069 if (!utf8_is_valid(t
)) {
1078 *start
= saved_rindex
;
1083 dns_packet_rewind(p
, saved_rindex
);
1087 int dns_packet_read_raw_string(DnsPacket
*p
, const void **ret
, size_t *size
, size_t *start
) {
1088 size_t saved_rindex
;
1094 saved_rindex
= p
->rindex
;
1096 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1100 r
= dns_packet_read(p
, c
, ret
, NULL
);
1107 *start
= saved_rindex
;
1112 dns_packet_rewind(p
, saved_rindex
);
1116 int dns_packet_read_name(
1119 bool allow_compression
,
1122 size_t saved_rindex
, after_rindex
= 0, jump_barrier
;
1123 _cleanup_free_
char *ret
= NULL
;
1124 size_t n
= 0, allocated
= 0;
1131 if (p
->refuse_compression
)
1132 allow_compression
= false;
1134 saved_rindex
= p
->rindex
;
1135 jump_barrier
= p
->rindex
;
1140 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1151 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
1155 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ DNS_LABEL_ESCAPED_MAX
)) {
1165 r
= dns_label_escape(label
, c
, ret
+ n
, DNS_LABEL_ESCAPED_MAX
);
1171 } else if (allow_compression
&& (c
& 0xc0) == 0xc0) {
1175 r
= dns_packet_read_uint8(p
, &d
, NULL
);
1179 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
1180 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= jump_barrier
) {
1185 if (after_rindex
== 0)
1186 after_rindex
= p
->rindex
;
1188 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1197 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1)) {
1204 if (after_rindex
!= 0)
1205 p
->rindex
= after_rindex
;
1211 *start
= saved_rindex
;
1216 dns_packet_rewind(p
, saved_rindex
);
1220 static int dns_packet_read_type_window(DnsPacket
*p
, Bitmap
**types
, size_t *start
) {
1223 const uint8_t *bitmap
;
1227 size_t saved_rindex
;
1233 saved_rindex
= p
->rindex
;
1235 r
= bitmap_ensure_allocated(types
);
1239 r
= dns_packet_read_uint8(p
, &window
, NULL
);
1243 r
= dns_packet_read_uint8(p
, &length
, NULL
);
1247 if (length
== 0 || length
> 32)
1250 r
= dns_packet_read(p
, length
, (const void **)&bitmap
, NULL
);
1254 for (i
= 0; i
< length
; i
++) {
1255 uint8_t bitmask
= 1 << 7;
1266 if (bitmap
[i
] & bitmask
) {
1269 n
= (uint16_t) window
<< 8 | (uint16_t) bit
;
1271 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1272 if (dns_type_is_pseudo(n
))
1275 r
= bitmap_set(*types
, n
);
1289 *start
= saved_rindex
;
1293 dns_packet_rewind(p
, saved_rindex
);
1297 static int dns_packet_read_type_windows(DnsPacket
*p
, Bitmap
**types
, size_t size
, size_t *start
) {
1298 size_t saved_rindex
;
1301 saved_rindex
= p
->rindex
;
1303 while (p
->rindex
< saved_rindex
+ size
) {
1304 r
= dns_packet_read_type_window(p
, types
, NULL
);
1308 /* don't read past end of current RR */
1309 if (p
->rindex
> saved_rindex
+ size
) {
1315 if (p
->rindex
!= saved_rindex
+ size
) {
1321 *start
= saved_rindex
;
1325 dns_packet_rewind(p
, saved_rindex
);
1329 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, size_t *start
) {
1330 _cleanup_free_
char *name
= NULL
;
1331 uint16_t class, type
;
1332 DnsResourceKey
*key
;
1333 size_t saved_rindex
;
1339 saved_rindex
= p
->rindex
;
1341 r
= dns_packet_read_name(p
, &name
, true, NULL
);
1345 r
= dns_packet_read_uint16(p
, &type
, NULL
);
1349 r
= dns_packet_read_uint16(p
, &class, NULL
);
1353 key
= dns_resource_key_new_consume(class, type
, name
);
1363 *start
= saved_rindex
;
1367 dns_packet_rewind(p
, saved_rindex
);
1371 static bool loc_size_ok(uint8_t size
) {
1372 uint8_t m
= size
>> 4, e
= size
& 0xF;
1374 return m
<= 9 && e
<= 9 && (m
> 0 || e
== 0);
1377 static int dnskey_parse_flags(DnsResourceRecord
*rr
, uint16_t flags
) {
1380 if (flags
& ~(DNSKEY_FLAG_SEP
| DNSKEY_FLAG_ZONE_KEY
))
1383 rr
->dnskey
.zone_key_flag
= flags
& DNSKEY_FLAG_ZONE_KEY
;
1384 rr
->dnskey
.sep_flag
= flags
& DNSKEY_FLAG_SEP
;
1388 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, size_t *start
) {
1389 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1390 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1391 size_t saved_rindex
, offset
;
1398 saved_rindex
= p
->rindex
;
1400 r
= dns_packet_read_key(p
, &key
, NULL
);
1404 if (key
->class == DNS_CLASS_ANY
||
1405 key
->type
== DNS_TYPE_ANY
) {
1410 rr
= dns_resource_record_new(key
);
1416 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
1420 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
1424 if (p
->rindex
+ rdlength
> p
->size
) {
1431 switch (rr
->key
->type
) {
1434 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
1437 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
1440 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
1443 r
= dns_packet_read_name(p
, &rr
->srv
.name
, true, NULL
);
1448 case DNS_TYPE_CNAME
:
1449 case DNS_TYPE_DNAME
:
1450 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, true, NULL
);
1453 case DNS_TYPE_HINFO
:
1454 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1458 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1461 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1463 if (rdlength
<= 0) {
1465 /* RFC 6763, section 6.1 suggests to treat
1466 * empty TXT RRs as equivalent to a TXT record
1467 * with a single empty string. */
1469 i
= malloc0(offsetof(DnsTxtItem
, data
) + 1); /* for safety reasons we add an extra NUL byte */
1475 DnsTxtItem
*last
= NULL
;
1477 while (p
->rindex
< offset
+ rdlength
) {
1482 r
= dns_packet_read_raw_string(p
, &data
, &sz
, NULL
);
1486 i
= malloc0(offsetof(DnsTxtItem
, data
) + sz
+ 1); /* extra NUL byte at the end */
1490 memcpy(i
->data
, data
, sz
);
1493 LIST_INSERT_AFTER(items
, rr
->txt
.items
, last
, i
);
1502 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1506 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1510 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, true, NULL
);
1514 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, true, NULL
);
1518 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1522 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1526 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1530 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1534 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1538 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1542 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, true, NULL
);
1545 case DNS_TYPE_LOC
: {
1549 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1554 rr
->loc
.version
= t
;
1556 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1560 if (!loc_size_ok(rr
->loc
.size
)) {
1565 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1569 if (!loc_size_ok(rr
->loc
.horiz_pre
)) {
1574 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1578 if (!loc_size_ok(rr
->loc
.vert_pre
)) {
1583 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1587 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1591 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1597 dns_packet_rewind(p
, pos
);
1598 rr
->unparseable
= true;
1604 r
= dns_packet_read_uint16(p
, &rr
->ds
.key_tag
, NULL
);
1608 r
= dns_packet_read_uint8(p
, &rr
->ds
.algorithm
, NULL
);
1612 r
= dns_packet_read_uint8(p
, &rr
->ds
.digest_type
, NULL
);
1616 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1617 &rr
->ds
.digest
, &rr
->ds
.digest_size
,
1622 if (rr
->ds
.digest_size
<= 0) {
1623 /* the accepted size depends on the algorithm, but for now
1624 just ensure that the value is greater than zero */
1630 case DNS_TYPE_SSHFP
:
1631 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1635 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1639 r
= dns_packet_read_memdup(p
, rdlength
- 2,
1640 &rr
->sshfp
.fingerprint
, &rr
->sshfp
.fingerprint_size
,
1643 if (rr
->sshfp
.fingerprint_size
<= 0) {
1644 /* the accepted size depends on the algorithm, but for now
1645 just ensure that the value is greater than zero */
1652 case DNS_TYPE_DNSKEY
: {
1656 r
= dns_packet_read_uint16(p
, &flags
, NULL
);
1660 r
= dnskey_parse_flags(rr
, flags
);
1664 r
= dns_packet_read_uint8(p
, &proto
, NULL
);
1668 /* protocol is required to be always 3 */
1674 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.algorithm
, NULL
);
1678 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1679 &rr
->dnskey
.key
, &rr
->dnskey
.key_size
,
1682 if (rr
->dnskey
.key_size
<= 0) {
1683 /* the accepted size depends on the algorithm, but for now
1684 just ensure that the value is greater than zero */
1692 case DNS_TYPE_RRSIG
:
1693 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.type_covered
, NULL
);
1697 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.algorithm
, NULL
);
1701 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.labels
, NULL
);
1705 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.original_ttl
, NULL
);
1709 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.expiration
, NULL
);
1713 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.inception
, NULL
);
1717 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.key_tag
, NULL
);
1721 r
= dns_packet_read_name(p
, &rr
->rrsig
.signer
, false, NULL
);
1725 r
= dns_packet_read_memdup(p
, offset
+ rdlength
- p
->rindex
,
1726 &rr
->rrsig
.signature
, &rr
->rrsig
.signature_size
,
1729 if (rr
->rrsig
.signature_size
<= 0) {
1730 /* the accepted size depends on the algorithm, but for now
1731 just ensure that the value is greater than zero */
1739 r
= dns_packet_read_name(p
, &rr
->nsec
.next_domain_name
, false, NULL
);
1743 r
= dns_packet_read_type_windows(p
, &rr
->nsec
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1747 /* The types bitmap must contain at least the NSEC record itself, so an empty bitmap means
1748 something went wrong */
1749 if (bitmap_isclear(rr
->nsec
.types
)) {
1756 case DNS_TYPE_NSEC3
: {
1759 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.algorithm
, NULL
);
1763 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.flags
, NULL
);
1767 r
= dns_packet_read_uint16(p
, &rr
->nsec3
.iterations
, NULL
);
1771 /* this may be zero */
1772 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1776 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.salt
, &rr
->nsec3
.salt_size
, NULL
);
1780 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1789 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.next_hashed_name
, &rr
->nsec3
.next_hashed_name_size
, NULL
);
1793 r
= dns_packet_read_type_windows(p
, &rr
->nsec3
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1797 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
1803 r
= dns_packet_read_memdup(p
, rdlength
, &rr
->generic
.data
, &rr
->generic
.size
, NULL
);
1810 if (p
->rindex
!= offset
+ rdlength
) {
1819 *start
= saved_rindex
;
1823 dns_packet_rewind(p
, saved_rindex
);
1827 int dns_packet_extract(DnsPacket
*p
) {
1828 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1829 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1830 size_t saved_rindex
;
1837 saved_rindex
= p
->rindex
;
1838 dns_packet_rewind(p
, DNS_PACKET_HEADER_SIZE
);
1840 n
= DNS_PACKET_QDCOUNT(p
);
1842 question
= dns_question_new(n
);
1848 for (i
= 0; i
< n
; i
++) {
1849 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1851 r
= dns_packet_read_key(p
, &key
, NULL
);
1855 r
= dns_question_add(question
, key
);
1861 n
= DNS_PACKET_RRCOUNT(p
);
1863 answer
= dns_answer_new(n
);
1869 for (i
= 0; i
< n
; i
++) {
1870 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1872 r
= dns_packet_read_rr(p
, &rr
, NULL
);
1876 r
= dns_answer_add(answer
, rr
, p
->ifindex
);
1882 p
->question
= question
;
1888 p
->extracted
= true;
1893 p
->rindex
= saved_rindex
;
1897 static const char* const dns_rcode_table
[_DNS_RCODE_MAX_DEFINED
] = {
1898 [DNS_RCODE_SUCCESS
] = "SUCCESS",
1899 [DNS_RCODE_FORMERR
] = "FORMERR",
1900 [DNS_RCODE_SERVFAIL
] = "SERVFAIL",
1901 [DNS_RCODE_NXDOMAIN
] = "NXDOMAIN",
1902 [DNS_RCODE_NOTIMP
] = "NOTIMP",
1903 [DNS_RCODE_REFUSED
] = "REFUSED",
1904 [DNS_RCODE_YXDOMAIN
] = "YXDOMAIN",
1905 [DNS_RCODE_YXRRSET
] = "YRRSET",
1906 [DNS_RCODE_NXRRSET
] = "NXRRSET",
1907 [DNS_RCODE_NOTAUTH
] = "NOTAUTH",
1908 [DNS_RCODE_NOTZONE
] = "NOTZONE",
1909 [DNS_RCODE_BADVERS
] = "BADVERS",
1910 [DNS_RCODE_BADKEY
] = "BADKEY",
1911 [DNS_RCODE_BADTIME
] = "BADTIME",
1912 [DNS_RCODE_BADMODE
] = "BADMODE",
1913 [DNS_RCODE_BADNAME
] = "BADNAME",
1914 [DNS_RCODE_BADALG
] = "BADALG",
1915 [DNS_RCODE_BADTRUNC
] = "BADTRUNC",
1917 DEFINE_STRING_TABLE_LOOKUP(dns_rcode
, int);
1919 static const char* const dns_protocol_table
[_DNS_PROTOCOL_MAX
] = {
1920 [DNS_PROTOCOL_DNS
] = "dns",
1921 [DNS_PROTOCOL_MDNS
] = "mdns",
1922 [DNS_PROTOCOL_LLMNR
] = "llmnr",
1924 DEFINE_STRING_TABLE_LOOKUP(dns_protocol
, DnsProtocol
);
1926 static const char* const dnssec_algorithm_table
[_DNSSEC_ALGORITHM_MAX_DEFINED
] = {
1927 [DNSSEC_ALGORITHM_RSAMD5
] = "RSAMD5",
1928 [DNSSEC_ALGORITHM_DH
] = "DH",
1929 [DNSSEC_ALGORITHM_DSA
] = "DSA",
1930 [DNSSEC_ALGORITHM_ECC
] = "ECC",
1931 [DNSSEC_ALGORITHM_RSASHA1
] = "RSASHA1",
1932 [DNSSEC_ALGORITHM_DSA_NSEC3_SHA1
] = "DSA-NSEC3-SHA1",
1933 [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1
] = "RSASHA1-NSEC3-SHA1",
1934 [DNSSEC_ALGORITHM_INDIRECT
] = "INDIRECT",
1935 [DNSSEC_ALGORITHM_PRIVATEDNS
] = "PRIVATEDNS",
1936 [DNSSEC_ALGORITHM_PRIVATEOID
] = "PRIVATEOID",
1938 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm
, int);