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
);
1148 _cleanup_free_
char *t
= NULL
;
1152 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
1156 r
= dns_label_escape(label
, c
, &t
);
1160 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ strlen(t
) + 1)) {
1170 memcpy(ret
+ n
, t
, r
);
1173 } else if (allow_compression
&& (c
& 0xc0) == 0xc0) {
1177 r
= dns_packet_read_uint8(p
, &d
, NULL
);
1181 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
1182 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= jump_barrier
) {
1187 if (after_rindex
== 0)
1188 after_rindex
= p
->rindex
;
1190 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1199 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1)) {
1206 if (after_rindex
!= 0)
1207 p
->rindex
= after_rindex
;
1213 *start
= saved_rindex
;
1218 dns_packet_rewind(p
, saved_rindex
);
1222 static int dns_packet_read_type_window(DnsPacket
*p
, Bitmap
**types
, size_t *start
) {
1225 const uint8_t *bitmap
;
1229 size_t saved_rindex
;
1235 saved_rindex
= p
->rindex
;
1237 r
= bitmap_ensure_allocated(types
);
1241 r
= dns_packet_read_uint8(p
, &window
, NULL
);
1245 r
= dns_packet_read_uint8(p
, &length
, NULL
);
1249 if (length
== 0 || length
> 32)
1252 r
= dns_packet_read(p
, length
, (const void **)&bitmap
, NULL
);
1256 for (i
= 0; i
< length
; i
++) {
1257 uint8_t bitmask
= 1 << 7;
1268 if (bitmap
[i
] & bitmask
) {
1271 n
= (uint16_t) window
<< 8 | (uint16_t) bit
;
1273 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1274 if (dns_type_is_pseudo(n
))
1277 r
= bitmap_set(*types
, n
);
1291 *start
= saved_rindex
;
1295 dns_packet_rewind(p
, saved_rindex
);
1299 static int dns_packet_read_type_windows(DnsPacket
*p
, Bitmap
**types
, size_t size
, size_t *start
) {
1300 size_t saved_rindex
;
1303 saved_rindex
= p
->rindex
;
1305 while (p
->rindex
< saved_rindex
+ size
) {
1306 r
= dns_packet_read_type_window(p
, types
, NULL
);
1310 /* don't read past end of current RR */
1311 if (p
->rindex
> saved_rindex
+ size
) {
1317 if (p
->rindex
!= saved_rindex
+ size
) {
1323 *start
= saved_rindex
;
1327 dns_packet_rewind(p
, saved_rindex
);
1331 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, size_t *start
) {
1332 _cleanup_free_
char *name
= NULL
;
1333 uint16_t class, type
;
1334 DnsResourceKey
*key
;
1335 size_t saved_rindex
;
1341 saved_rindex
= p
->rindex
;
1343 r
= dns_packet_read_name(p
, &name
, true, NULL
);
1347 r
= dns_packet_read_uint16(p
, &type
, NULL
);
1351 r
= dns_packet_read_uint16(p
, &class, NULL
);
1355 key
= dns_resource_key_new_consume(class, type
, name
);
1365 *start
= saved_rindex
;
1369 dns_packet_rewind(p
, saved_rindex
);
1373 static bool loc_size_ok(uint8_t size
) {
1374 uint8_t m
= size
>> 4, e
= size
& 0xF;
1376 return m
<= 9 && e
<= 9 && (m
> 0 || e
== 0);
1379 static int dnskey_parse_flags(DnsResourceRecord
*rr
, uint16_t flags
) {
1382 if (flags
& ~(DNSKEY_FLAG_SEP
| DNSKEY_FLAG_ZONE_KEY
))
1385 rr
->dnskey
.zone_key_flag
= flags
& DNSKEY_FLAG_ZONE_KEY
;
1386 rr
->dnskey
.sep_flag
= flags
& DNSKEY_FLAG_SEP
;
1390 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, size_t *start
) {
1391 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1392 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1393 size_t saved_rindex
, offset
;
1400 saved_rindex
= p
->rindex
;
1402 r
= dns_packet_read_key(p
, &key
, NULL
);
1406 if (key
->class == DNS_CLASS_ANY
||
1407 key
->type
== DNS_TYPE_ANY
) {
1412 rr
= dns_resource_record_new(key
);
1418 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
1422 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
1426 if (p
->rindex
+ rdlength
> p
->size
) {
1433 switch (rr
->key
->type
) {
1436 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
1439 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
1442 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
1445 r
= dns_packet_read_name(p
, &rr
->srv
.name
, true, NULL
);
1450 case DNS_TYPE_CNAME
:
1451 case DNS_TYPE_DNAME
:
1452 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, true, NULL
);
1455 case DNS_TYPE_HINFO
:
1456 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1460 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1463 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1465 if (rdlength
<= 0) {
1467 /* RFC 6763, section 6.1 suggests to treat
1468 * empty TXT RRs as equivalent to a TXT record
1469 * with a single empty string. */
1471 i
= malloc0(offsetof(DnsTxtItem
, data
) + 1); /* for safety reasons we add an extra NUL byte */
1477 DnsTxtItem
*last
= NULL
;
1479 while (p
->rindex
< offset
+ rdlength
) {
1484 r
= dns_packet_read_raw_string(p
, &data
, &sz
, NULL
);
1488 i
= malloc0(offsetof(DnsTxtItem
, data
) + sz
+ 1); /* extra NUL byte at the end */
1492 memcpy(i
->data
, data
, sz
);
1495 LIST_INSERT_AFTER(items
, rr
->txt
.items
, last
, i
);
1504 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1508 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1512 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, true, NULL
);
1516 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, true, NULL
);
1520 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1524 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1528 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1532 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1536 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1540 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1544 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, true, NULL
);
1547 case DNS_TYPE_LOC
: {
1551 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1556 rr
->loc
.version
= t
;
1558 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1562 if (!loc_size_ok(rr
->loc
.size
)) {
1567 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1571 if (!loc_size_ok(rr
->loc
.horiz_pre
)) {
1576 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1580 if (!loc_size_ok(rr
->loc
.vert_pre
)) {
1585 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1589 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1593 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1599 dns_packet_rewind(p
, pos
);
1600 rr
->unparseable
= true;
1606 r
= dns_packet_read_uint16(p
, &rr
->ds
.key_tag
, NULL
);
1610 r
= dns_packet_read_uint8(p
, &rr
->ds
.algorithm
, NULL
);
1614 r
= dns_packet_read_uint8(p
, &rr
->ds
.digest_type
, NULL
);
1618 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1619 &rr
->ds
.digest
, &rr
->ds
.digest_size
,
1624 if (rr
->ds
.digest_size
<= 0) {
1625 /* the accepted size depends on the algorithm, but for now
1626 just ensure that the value is greater than zero */
1632 case DNS_TYPE_SSHFP
:
1633 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1637 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1641 r
= dns_packet_read_memdup(p
, rdlength
- 2,
1642 &rr
->sshfp
.fingerprint
, &rr
->sshfp
.fingerprint_size
,
1645 if (rr
->sshfp
.fingerprint_size
<= 0) {
1646 /* the accepted size depends on the algorithm, but for now
1647 just ensure that the value is greater than zero */
1654 case DNS_TYPE_DNSKEY
: {
1658 r
= dns_packet_read_uint16(p
, &flags
, NULL
);
1662 r
= dnskey_parse_flags(rr
, flags
);
1666 r
= dns_packet_read_uint8(p
, &proto
, NULL
);
1670 /* protocol is required to be always 3 */
1676 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.algorithm
, NULL
);
1680 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1681 &rr
->dnskey
.key
, &rr
->dnskey
.key_size
,
1684 if (rr
->dnskey
.key_size
<= 0) {
1685 /* the accepted size depends on the algorithm, but for now
1686 just ensure that the value is greater than zero */
1694 case DNS_TYPE_RRSIG
:
1695 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.type_covered
, NULL
);
1699 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.algorithm
, NULL
);
1703 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.labels
, NULL
);
1707 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.original_ttl
, NULL
);
1711 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.expiration
, NULL
);
1715 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.inception
, NULL
);
1719 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.key_tag
, NULL
);
1723 r
= dns_packet_read_name(p
, &rr
->rrsig
.signer
, false, NULL
);
1727 r
= dns_packet_read_memdup(p
, offset
+ rdlength
- p
->rindex
,
1728 &rr
->rrsig
.signature
, &rr
->rrsig
.signature_size
,
1731 if (rr
->rrsig
.signature_size
<= 0) {
1732 /* the accepted size depends on the algorithm, but for now
1733 just ensure that the value is greater than zero */
1741 r
= dns_packet_read_name(p
, &rr
->nsec
.next_domain_name
, false, NULL
);
1745 r
= dns_packet_read_type_windows(p
, &rr
->nsec
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1749 /* The types bitmap must contain at least the NSEC record itself, so an empty bitmap means
1750 something went wrong */
1751 if (bitmap_isclear(rr
->nsec
.types
)) {
1758 case DNS_TYPE_NSEC3
: {
1761 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.algorithm
, NULL
);
1765 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.flags
, NULL
);
1769 r
= dns_packet_read_uint16(p
, &rr
->nsec3
.iterations
, NULL
);
1773 /* this may be zero */
1774 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1778 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.salt
, &rr
->nsec3
.salt_size
, NULL
);
1782 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1791 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.next_hashed_name
, &rr
->nsec3
.next_hashed_name_size
, NULL
);
1795 r
= dns_packet_read_type_windows(p
, &rr
->nsec3
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1799 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
1805 r
= dns_packet_read_memdup(p
, rdlength
, &rr
->generic
.data
, &rr
->generic
.size
, NULL
);
1812 if (p
->rindex
!= offset
+ rdlength
) {
1821 *start
= saved_rindex
;
1825 dns_packet_rewind(p
, saved_rindex
);
1829 int dns_packet_extract(DnsPacket
*p
) {
1830 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1831 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1832 size_t saved_rindex
;
1839 saved_rindex
= p
->rindex
;
1840 dns_packet_rewind(p
, DNS_PACKET_HEADER_SIZE
);
1842 n
= DNS_PACKET_QDCOUNT(p
);
1844 question
= dns_question_new(n
);
1850 for (i
= 0; i
< n
; i
++) {
1851 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1853 r
= dns_packet_read_key(p
, &key
, NULL
);
1857 r
= dns_question_add(question
, key
);
1863 n
= DNS_PACKET_RRCOUNT(p
);
1865 answer
= dns_answer_new(n
);
1871 for (i
= 0; i
< n
; i
++) {
1872 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1874 r
= dns_packet_read_rr(p
, &rr
, NULL
);
1878 r
= dns_answer_add(answer
, rr
, p
->ifindex
);
1884 p
->question
= question
;
1890 p
->extracted
= true;
1895 p
->rindex
= saved_rindex
;
1899 static const char* const dns_rcode_table
[_DNS_RCODE_MAX_DEFINED
] = {
1900 [DNS_RCODE_SUCCESS
] = "SUCCESS",
1901 [DNS_RCODE_FORMERR
] = "FORMERR",
1902 [DNS_RCODE_SERVFAIL
] = "SERVFAIL",
1903 [DNS_RCODE_NXDOMAIN
] = "NXDOMAIN",
1904 [DNS_RCODE_NOTIMP
] = "NOTIMP",
1905 [DNS_RCODE_REFUSED
] = "REFUSED",
1906 [DNS_RCODE_YXDOMAIN
] = "YXDOMAIN",
1907 [DNS_RCODE_YXRRSET
] = "YRRSET",
1908 [DNS_RCODE_NXRRSET
] = "NXRRSET",
1909 [DNS_RCODE_NOTAUTH
] = "NOTAUTH",
1910 [DNS_RCODE_NOTZONE
] = "NOTZONE",
1911 [DNS_RCODE_BADVERS
] = "BADVERS",
1912 [DNS_RCODE_BADKEY
] = "BADKEY",
1913 [DNS_RCODE_BADTIME
] = "BADTIME",
1914 [DNS_RCODE_BADMODE
] = "BADMODE",
1915 [DNS_RCODE_BADNAME
] = "BADNAME",
1916 [DNS_RCODE_BADALG
] = "BADALG",
1917 [DNS_RCODE_BADTRUNC
] = "BADTRUNC",
1919 DEFINE_STRING_TABLE_LOOKUP(dns_rcode
, int);
1921 static const char* const dns_protocol_table
[_DNS_PROTOCOL_MAX
] = {
1922 [DNS_PROTOCOL_DNS
] = "dns",
1923 [DNS_PROTOCOL_MDNS
] = "mdns",
1924 [DNS_PROTOCOL_LLMNR
] = "llmnr",
1926 DEFINE_STRING_TABLE_LOOKUP(dns_protocol
, DnsProtocol
);
1928 static const char* const dnssec_algorithm_table
[_DNSSEC_ALGORITHM_MAX_DEFINED
] = {
1929 [DNSSEC_ALGORITHM_RSAMD5
] = "RSAMD5",
1930 [DNSSEC_ALGORITHM_DH
] = "DH",
1931 [DNSSEC_ALGORITHM_DSA
] = "DSA",
1932 [DNSSEC_ALGORITHM_ECC
] = "ECC",
1933 [DNSSEC_ALGORITHM_RSASHA1
] = "RSASHA1",
1934 [DNSSEC_ALGORITHM_DSA_NSEC3_SHA1
] = "DSA-NSEC3-SHA1",
1935 [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1
] = "RSASHA1-NSEC3-SHA1",
1936 [DNSSEC_ALGORITHM_INDIRECT
] = "INDIRECT",
1937 [DNSSEC_ALGORITHM_PRIVATEDNS
] = "PRIVATEDNS",
1938 [DNSSEC_ALGORITHM_PRIVATEOID
] = "PRIVATEOID",
1940 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm
, int);