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 #define EDNS0_OPT_DO (1<<15)
33 int dns_packet_new(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
39 if (mtu
<= UDP_PACKET_HEADER_SIZE
)
40 a
= DNS_PACKET_SIZE_START
;
42 a
= mtu
- UDP_PACKET_HEADER_SIZE
;
44 if (a
< DNS_PACKET_HEADER_SIZE
)
45 a
= DNS_PACKET_HEADER_SIZE
;
47 /* round up to next page size */
48 a
= PAGE_ALIGN(ALIGN(sizeof(DnsPacket
)) + a
) - ALIGN(sizeof(DnsPacket
));
50 /* make sure we never allocate more than useful */
51 if (a
> DNS_PACKET_SIZE_MAX
)
52 a
= DNS_PACKET_SIZE_MAX
;
54 p
= malloc0(ALIGN(sizeof(DnsPacket
)) + a
);
58 p
->size
= p
->rindex
= DNS_PACKET_HEADER_SIZE
;
60 p
->protocol
= protocol
;
68 int dns_packet_new_query(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
75 r
= dns_packet_new(&p
, protocol
, mtu
);
79 h
= DNS_PACKET_HEADER(p
);
81 if (protocol
== DNS_PROTOCOL_LLMNR
)
82 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
92 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
96 1 /* rd (ask for recursion) */,
106 DnsPacket
*dns_packet_ref(DnsPacket
*p
) {
111 assert(p
->n_ref
> 0);
116 static void dns_packet_free(DnsPacket
*p
) {
121 dns_question_unref(p
->question
);
122 dns_answer_unref(p
->answer
);
124 while ((s
= hashmap_steal_first_key(p
->names
)))
126 hashmap_free(p
->names
);
132 DnsPacket
*dns_packet_unref(DnsPacket
*p
) {
136 assert(p
->n_ref
> 0);
146 int dns_packet_validate(DnsPacket
*p
) {
149 if (p
->size
< DNS_PACKET_HEADER_SIZE
)
152 if (p
->size
> DNS_PACKET_SIZE_MAX
)
158 int dns_packet_validate_reply(DnsPacket
*p
) {
163 r
= dns_packet_validate(p
);
167 if (DNS_PACKET_QR(p
) != 1)
170 if (DNS_PACKET_OPCODE(p
) != 0)
173 switch (p
->protocol
) {
174 case DNS_PROTOCOL_LLMNR
:
175 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
176 if (DNS_PACKET_QDCOUNT(p
) != 1)
188 int dns_packet_validate_query(DnsPacket
*p
) {
193 r
= dns_packet_validate(p
);
197 if (DNS_PACKET_QR(p
) != 0)
200 if (DNS_PACKET_OPCODE(p
) != 0)
203 if (DNS_PACKET_TC(p
))
206 switch (p
->protocol
) {
207 case DNS_PROTOCOL_LLMNR
:
208 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
209 if (DNS_PACKET_QDCOUNT(p
) != 1)
212 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
213 if (DNS_PACKET_ANCOUNT(p
) > 0)
216 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
217 if (DNS_PACKET_NSCOUNT(p
) > 0)
229 static int dns_packet_extend(DnsPacket
*p
, size_t add
, void **ret
, size_t *start
) {
232 if (p
->size
+ add
> p
->allocated
) {
235 a
= PAGE_ALIGN((p
->size
+ add
) * 2);
236 if (a
> DNS_PACKET_SIZE_MAX
)
237 a
= DNS_PACKET_SIZE_MAX
;
239 if (p
->size
+ add
> a
)
245 d
= realloc(p
->_data
, a
);
251 p
->_data
= malloc(a
);
255 memcpy(p
->_data
, (uint8_t*) p
+ ALIGN(sizeof(DnsPacket
)), p
->size
);
256 memzero((uint8_t*) p
->_data
+ p
->size
, a
- p
->size
);
266 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->size
;
272 void dns_packet_truncate(DnsPacket
*p
, size_t sz
) {
282 HASHMAP_FOREACH_KEY(n
, s
, p
->names
, i
) {
284 if (PTR_TO_SIZE(n
) < sz
)
287 hashmap_remove(p
->names
, s
);
294 int dns_packet_append_blob(DnsPacket
*p
, const void *d
, size_t l
, size_t *start
) {
300 r
= dns_packet_extend(p
, l
, &q
, start
);
308 int dns_packet_append_uint8(DnsPacket
*p
, uint8_t v
, size_t *start
) {
314 r
= dns_packet_extend(p
, sizeof(uint8_t), &d
, start
);
318 ((uint8_t*) d
)[0] = v
;
323 int dns_packet_append_uint16(DnsPacket
*p
, uint16_t v
, size_t *start
) {
329 r
= dns_packet_extend(p
, sizeof(uint16_t), &d
, start
);
333 unaligned_write_be16(d
, v
);
338 int dns_packet_append_uint32(DnsPacket
*p
, uint32_t v
, size_t *start
) {
344 r
= dns_packet_extend(p
, sizeof(uint32_t), &d
, start
);
348 unaligned_write_be32(d
, v
);
353 int dns_packet_append_string(DnsPacket
*p
, const char *s
, size_t *start
) {
357 return dns_packet_append_raw_string(p
, s
, strlen(s
), start
);
360 int dns_packet_append_raw_string(DnsPacket
*p
, const void *s
, size_t size
, size_t *start
) {
365 assert(s
|| size
== 0);
370 r
= dns_packet_extend(p
, 1 + size
, &d
, start
);
374 ((uint8_t*) d
)[0] = (uint8_t) size
;
377 memcpy(((uint8_t*) d
) + 1, s
, size
);
382 int dns_packet_append_label(DnsPacket
*p
, const char *d
, size_t l
, size_t *start
) {
389 if (l
> DNS_LABEL_MAX
)
392 r
= dns_packet_extend(p
, 1 + l
, &w
, start
);
396 ((uint8_t*) w
)[0] = (uint8_t) l
;
397 memcpy(((uint8_t*) w
) + 1, d
, l
);
402 int dns_packet_append_name(
405 bool allow_compression
,
414 if (p
->refuse_compression
)
415 allow_compression
= false;
417 saved_size
= p
->size
;
420 _cleanup_free_
char *s
= NULL
;
421 char label
[DNS_LABEL_MAX
];
425 if (allow_compression
)
426 n
= PTR_TO_SIZE(hashmap_get(p
->names
, name
));
431 r
= dns_packet_append_uint16(p
, 0xC000 | n
, NULL
);
445 r
= dns_label_unescape(&name
, label
, sizeof(label
));
449 if (p
->protocol
== DNS_PROTOCOL_DNS
)
450 k
= dns_label_apply_idna(label
, r
, label
, sizeof(label
));
452 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
460 r
= dns_packet_append_label(p
, label
, r
, &n
);
464 if (allow_compression
) {
465 r
= hashmap_ensure_allocated(&p
->names
, &dns_name_hash_ops
);
469 r
= hashmap_put(p
->names
, s
, SIZE_TO_PTR(n
));
477 r
= dns_packet_append_uint8(p
, 0, NULL
);
488 dns_packet_truncate(p
, saved_size
);
492 int dns_packet_append_key(DnsPacket
*p
, const DnsResourceKey
*k
, size_t *start
) {
499 saved_size
= p
->size
;
501 r
= dns_packet_append_name(p
, DNS_RESOURCE_KEY_NAME(k
), true, NULL
);
505 r
= dns_packet_append_uint16(p
, k
->type
, NULL
);
509 r
= dns_packet_append_uint16(p
, k
->class, NULL
);
519 dns_packet_truncate(p
, saved_size
);
523 static int dns_packet_append_type_window(DnsPacket
*p
, uint8_t window
, uint8_t length
, uint8_t *types
, size_t *start
) {
531 saved_size
= p
->size
;
533 r
= dns_packet_append_uint8(p
, window
, NULL
);
537 r
= dns_packet_append_uint8(p
, length
, NULL
);
541 r
= dns_packet_append_blob(p
, types
, length
, NULL
);
550 dns_packet_truncate(p
, saved_size
);
554 static int dns_packet_append_types(DnsPacket
*p
, Bitmap
*types
, size_t *start
) {
558 uint8_t bitmaps
[32] = {};
566 saved_size
= p
->size
;
568 BITMAP_FOREACH(n
, types
, i
) {
571 if ((n
>> 8) != window
&& bitmaps
[entry
/ 8] != 0) {
572 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
583 bitmaps
[entry
/ 8] |= 1 << (7 - (entry
% 8));
586 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
595 dns_packet_truncate(p
, saved_size
);
599 /* Append the OPT pseudo-RR described in RFC6891 */
600 int dns_packet_append_opt_rr(DnsPacket
*p
, uint16_t max_udp_size
, bool edns0_do
, size_t *start
) {
605 /* we must never advertise supported packet size smaller than the legacy max */
606 assert(max_udp_size
>= DNS_PACKET_UNICAST_SIZE_MAX
);
608 saved_size
= p
->size
;
611 r
= dns_packet_append_uint8(p
, 0, NULL
);
616 r
= dns_packet_append_uint16(p
, DNS_TYPE_OPT
, NULL
);
620 /* maximum udp packet that can be received */
621 r
= dns_packet_append_uint16(p
, max_udp_size
, NULL
);
625 /* extended RCODE and VERSION */
626 r
= dns_packet_append_uint16(p
, 0, NULL
);
630 /* flags: DNSSEC OK (DO), see RFC3225 */
631 r
= dns_packet_append_uint16(p
, edns0_do
? EDNS0_OPT_DO
: 0, NULL
);
636 r
= dns_packet_append_uint16(p
, 0, NULL
);
646 dns_packet_truncate(p
, saved_size
);
650 int dns_packet_append_rr(DnsPacket
*p
, const DnsResourceRecord
*rr
, size_t *start
) {
651 size_t saved_size
, rdlength_offset
, end
, rdlength
;
657 saved_size
= p
->size
;
659 r
= dns_packet_append_key(p
, rr
->key
, NULL
);
663 r
= dns_packet_append_uint32(p
, rr
->ttl
, NULL
);
667 /* Initially we write 0 here */
668 r
= dns_packet_append_uint16(p
, 0, &rdlength_offset
);
672 switch (rr
->unparseable
? _DNS_TYPE_INVALID
: rr
->key
->type
) {
675 r
= dns_packet_append_uint16(p
, rr
->srv
.priority
, NULL
);
679 r
= dns_packet_append_uint16(p
, rr
->srv
.weight
, NULL
);
683 r
= dns_packet_append_uint16(p
, rr
->srv
.port
, NULL
);
687 r
= dns_packet_append_name(p
, rr
->srv
.name
, true, NULL
);
694 r
= dns_packet_append_name(p
, rr
->ptr
.name
, true, NULL
);
698 r
= dns_packet_append_string(p
, rr
->hinfo
.cpu
, NULL
);
702 r
= dns_packet_append_string(p
, rr
->hinfo
.os
, NULL
);
705 case DNS_TYPE_SPF
: /* exactly the same as TXT */
708 if (!rr
->txt
.items
) {
709 /* RFC 6763, section 6.1 suggests to generate
710 * single empty string for an empty array. */
712 r
= dns_packet_append_raw_string(p
, NULL
, 0, NULL
);
718 LIST_FOREACH(items
, i
, rr
->txt
.items
) {
719 r
= dns_packet_append_raw_string(p
, i
->data
, i
->length
, NULL
);
729 r
= dns_packet_append_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
733 r
= dns_packet_append_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
737 r
= dns_packet_append_name(p
, rr
->soa
.mname
, true, NULL
);
741 r
= dns_packet_append_name(p
, rr
->soa
.rname
, true, NULL
);
745 r
= dns_packet_append_uint32(p
, rr
->soa
.serial
, NULL
);
749 r
= dns_packet_append_uint32(p
, rr
->soa
.refresh
, NULL
);
753 r
= dns_packet_append_uint32(p
, rr
->soa
.retry
, NULL
);
757 r
= dns_packet_append_uint32(p
, rr
->soa
.expire
, NULL
);
761 r
= dns_packet_append_uint32(p
, rr
->soa
.minimum
, NULL
);
765 r
= dns_packet_append_uint16(p
, rr
->mx
.priority
, NULL
);
769 r
= dns_packet_append_name(p
, rr
->mx
.exchange
, true, NULL
);
773 r
= dns_packet_append_uint8(p
, rr
->loc
.version
, NULL
);
777 r
= dns_packet_append_uint8(p
, rr
->loc
.size
, NULL
);
781 r
= dns_packet_append_uint8(p
, rr
->loc
.horiz_pre
, NULL
);
785 r
= dns_packet_append_uint8(p
, rr
->loc
.vert_pre
, NULL
);
789 r
= dns_packet_append_uint32(p
, rr
->loc
.latitude
, NULL
);
793 r
= dns_packet_append_uint32(p
, rr
->loc
.longitude
, NULL
);
797 r
= dns_packet_append_uint32(p
, rr
->loc
.altitude
, NULL
);
801 r
= dns_packet_append_uint16(p
, rr
->ds
.key_tag
, NULL
);
805 r
= dns_packet_append_uint8(p
, rr
->ds
.algorithm
, NULL
);
809 r
= dns_packet_append_uint8(p
, rr
->ds
.digest_type
, NULL
);
813 r
= dns_packet_append_blob(p
, rr
->ds
.digest
, rr
->ds
.digest_size
, NULL
);
817 r
= dns_packet_append_uint8(p
, rr
->sshfp
.algorithm
, NULL
);
821 r
= dns_packet_append_uint8(p
, rr
->sshfp
.fptype
, NULL
);
825 r
= dns_packet_append_blob(p
, rr
->sshfp
.fingerprint
, rr
->sshfp
.fingerprint_size
, NULL
);
828 case DNS_TYPE_DNSKEY
:
829 r
= dns_packet_append_uint16(p
, rr
->dnskey
.flags
, NULL
);
833 r
= dns_packet_append_uint8(p
, rr
->dnskey
.protocol
, NULL
);
837 r
= dns_packet_append_uint8(p
, rr
->dnskey
.algorithm
, NULL
);
841 r
= dns_packet_append_blob(p
, rr
->dnskey
.key
, rr
->dnskey
.key_size
, NULL
);
845 r
= dns_packet_append_uint16(p
, rr
->rrsig
.type_covered
, NULL
);
849 r
= dns_packet_append_uint8(p
, rr
->rrsig
.algorithm
, NULL
);
853 r
= dns_packet_append_uint8(p
, rr
->rrsig
.labels
, NULL
);
857 r
= dns_packet_append_uint32(p
, rr
->rrsig
.original_ttl
, NULL
);
861 r
= dns_packet_append_uint32(p
, rr
->rrsig
.expiration
, NULL
);
865 r
= dns_packet_append_uint32(p
, rr
->rrsig
.inception
, NULL
);
869 r
= dns_packet_append_uint16(p
, rr
->rrsig
.key_tag
, NULL
);
873 r
= dns_packet_append_name(p
, rr
->rrsig
.signer
, false, NULL
);
877 r
= dns_packet_append_blob(p
, rr
->rrsig
.signature
, rr
->rrsig
.signature_size
, NULL
);
881 r
= dns_packet_append_name(p
, rr
->nsec
.next_domain_name
, false, NULL
);
885 r
= dns_packet_append_types(p
, rr
->nsec
.types
, NULL
);
891 r
= dns_packet_append_uint8(p
, rr
->nsec3
.algorithm
, NULL
);
895 r
= dns_packet_append_uint8(p
, rr
->nsec3
.flags
, NULL
);
899 r
= dns_packet_append_uint16(p
, rr
->nsec3
.iterations
, NULL
);
903 r
= dns_packet_append_uint8(p
, rr
->nsec3
.salt_size
, NULL
);
907 r
= dns_packet_append_blob(p
, rr
->nsec3
.salt
, rr
->nsec3
.salt_size
, NULL
);
911 r
= dns_packet_append_uint8(p
, rr
->nsec3
.next_hashed_name_size
, NULL
);
915 r
= dns_packet_append_blob(p
, rr
->nsec3
.next_hashed_name
, rr
->nsec3
.next_hashed_name_size
, NULL
);
919 r
= dns_packet_append_types(p
, rr
->nsec3
.types
, NULL
);
924 case _DNS_TYPE_INVALID
: /* unparseable */
927 r
= dns_packet_append_blob(p
, rr
->generic
.data
, rr
->generic
.size
, NULL
);
933 /* Let's calculate the actual data size and update the field */
934 rdlength
= p
->size
- rdlength_offset
- sizeof(uint16_t);
935 if (rdlength
> 0xFFFF) {
941 p
->size
= rdlength_offset
;
942 r
= dns_packet_append_uint16(p
, rdlength
, NULL
);
953 dns_packet_truncate(p
, saved_size
);
958 int dns_packet_read(DnsPacket
*p
, size_t sz
, const void **ret
, size_t *start
) {
961 if (p
->rindex
+ sz
> p
->size
)
965 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->rindex
;
974 void dns_packet_rewind(DnsPacket
*p
, size_t idx
) {
976 assert(idx
<= p
->size
);
977 assert(idx
>= DNS_PACKET_HEADER_SIZE
);
982 int dns_packet_read_blob(DnsPacket
*p
, void *d
, size_t sz
, size_t *start
) {
989 r
= dns_packet_read(p
, sz
, &q
, start
);
997 static int dns_packet_read_memdup(
998 DnsPacket
*p
, size_t size
,
999 void **ret
, size_t *ret_size
,
1000 size_t *ret_start
) {
1009 r
= dns_packet_read(p
, size
, &src
, &start
);
1018 copy
= memdup(src
, size
);
1033 int dns_packet_read_uint8(DnsPacket
*p
, uint8_t *ret
, size_t *start
) {
1039 r
= dns_packet_read(p
, sizeof(uint8_t), &d
, start
);
1043 *ret
= ((uint8_t*) d
)[0];
1047 int dns_packet_read_uint16(DnsPacket
*p
, uint16_t *ret
, size_t *start
) {
1053 r
= dns_packet_read(p
, sizeof(uint16_t), &d
, start
);
1057 *ret
= unaligned_read_be16(d
);
1062 int dns_packet_read_uint32(DnsPacket
*p
, uint32_t *ret
, size_t *start
) {
1068 r
= dns_packet_read(p
, sizeof(uint32_t), &d
, start
);
1072 *ret
= unaligned_read_be32(d
);
1077 int dns_packet_read_string(DnsPacket
*p
, char **ret
, size_t *start
) {
1078 size_t saved_rindex
;
1086 saved_rindex
= p
->rindex
;
1088 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1092 r
= dns_packet_read(p
, c
, &d
, NULL
);
1096 if (memchr(d
, 0, c
)) {
1107 if (!utf8_is_valid(t
)) {
1116 *start
= saved_rindex
;
1121 dns_packet_rewind(p
, saved_rindex
);
1125 int dns_packet_read_raw_string(DnsPacket
*p
, const void **ret
, size_t *size
, size_t *start
) {
1126 size_t saved_rindex
;
1132 saved_rindex
= p
->rindex
;
1134 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1138 r
= dns_packet_read(p
, c
, ret
, NULL
);
1145 *start
= saved_rindex
;
1150 dns_packet_rewind(p
, saved_rindex
);
1154 int dns_packet_read_name(
1157 bool allow_compression
,
1160 size_t saved_rindex
, after_rindex
= 0, jump_barrier
;
1161 _cleanup_free_
char *ret
= NULL
;
1162 size_t n
= 0, allocated
= 0;
1169 if (p
->refuse_compression
)
1170 allow_compression
= false;
1172 saved_rindex
= p
->rindex
;
1173 jump_barrier
= p
->rindex
;
1178 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1189 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
1193 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ DNS_LABEL_ESCAPED_MAX
)) {
1203 r
= dns_label_escape(label
, c
, ret
+ n
, DNS_LABEL_ESCAPED_MAX
);
1209 } else if (allow_compression
&& (c
& 0xc0) == 0xc0) {
1213 r
= dns_packet_read_uint8(p
, &d
, NULL
);
1217 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
1218 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= jump_barrier
) {
1223 if (after_rindex
== 0)
1224 after_rindex
= p
->rindex
;
1226 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1235 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1)) {
1242 if (after_rindex
!= 0)
1243 p
->rindex
= after_rindex
;
1249 *start
= saved_rindex
;
1254 dns_packet_rewind(p
, saved_rindex
);
1258 static int dns_packet_read_type_window(DnsPacket
*p
, Bitmap
**types
, size_t *start
) {
1261 const uint8_t *bitmap
;
1265 size_t saved_rindex
;
1271 saved_rindex
= p
->rindex
;
1273 r
= bitmap_ensure_allocated(types
);
1277 r
= dns_packet_read_uint8(p
, &window
, NULL
);
1281 r
= dns_packet_read_uint8(p
, &length
, NULL
);
1285 if (length
== 0 || length
> 32)
1288 r
= dns_packet_read(p
, length
, (const void **)&bitmap
, NULL
);
1292 for (i
= 0; i
< length
; i
++) {
1293 uint8_t bitmask
= 1 << 7;
1304 if (bitmap
[i
] & bitmask
) {
1307 n
= (uint16_t) window
<< 8 | (uint16_t) bit
;
1309 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1310 if (dns_type_is_pseudo(n
))
1313 r
= bitmap_set(*types
, n
);
1327 *start
= saved_rindex
;
1331 dns_packet_rewind(p
, saved_rindex
);
1335 static int dns_packet_read_type_windows(DnsPacket
*p
, Bitmap
**types
, size_t size
, size_t *start
) {
1336 size_t saved_rindex
;
1339 saved_rindex
= p
->rindex
;
1341 while (p
->rindex
< saved_rindex
+ size
) {
1342 r
= dns_packet_read_type_window(p
, types
, NULL
);
1346 /* don't read past end of current RR */
1347 if (p
->rindex
> saved_rindex
+ size
) {
1353 if (p
->rindex
!= saved_rindex
+ size
) {
1359 *start
= saved_rindex
;
1363 dns_packet_rewind(p
, saved_rindex
);
1367 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, size_t *start
) {
1368 _cleanup_free_
char *name
= NULL
;
1369 uint16_t class, type
;
1370 DnsResourceKey
*key
;
1371 size_t saved_rindex
;
1377 saved_rindex
= p
->rindex
;
1379 r
= dns_packet_read_name(p
, &name
, true, NULL
);
1383 r
= dns_packet_read_uint16(p
, &type
, NULL
);
1387 r
= dns_packet_read_uint16(p
, &class, NULL
);
1391 key
= dns_resource_key_new_consume(class, type
, name
);
1401 *start
= saved_rindex
;
1405 dns_packet_rewind(p
, saved_rindex
);
1409 static bool loc_size_ok(uint8_t size
) {
1410 uint8_t m
= size
>> 4, e
= size
& 0xF;
1412 return m
<= 9 && e
<= 9 && (m
> 0 || e
== 0);
1415 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, size_t *start
) {
1416 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1417 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1418 size_t saved_rindex
, offset
;
1425 saved_rindex
= p
->rindex
;
1427 r
= dns_packet_read_key(p
, &key
, NULL
);
1431 if (key
->class == DNS_CLASS_ANY
||
1432 key
->type
== DNS_TYPE_ANY
) {
1437 rr
= dns_resource_record_new(key
);
1443 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
1447 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
1451 if (p
->rindex
+ rdlength
> p
->size
) {
1458 switch (rr
->key
->type
) {
1461 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
1464 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
1467 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
1470 r
= dns_packet_read_name(p
, &rr
->srv
.name
, true, NULL
);
1475 case DNS_TYPE_CNAME
:
1476 case DNS_TYPE_DNAME
:
1477 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, true, NULL
);
1480 case DNS_TYPE_OPT
: /* we only care about the header */
1484 case DNS_TYPE_HINFO
:
1485 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1489 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1492 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1494 if (rdlength
<= 0) {
1496 /* RFC 6763, section 6.1 suggests to treat
1497 * empty TXT RRs as equivalent to a TXT record
1498 * with a single empty string. */
1500 i
= malloc0(offsetof(DnsTxtItem
, data
) + 1); /* for safety reasons we add an extra NUL byte */
1506 DnsTxtItem
*last
= NULL
;
1508 while (p
->rindex
< offset
+ rdlength
) {
1513 r
= dns_packet_read_raw_string(p
, &data
, &sz
, NULL
);
1517 i
= malloc0(offsetof(DnsTxtItem
, data
) + sz
+ 1); /* extra NUL byte at the end */
1521 memcpy(i
->data
, data
, sz
);
1524 LIST_INSERT_AFTER(items
, rr
->txt
.items
, last
, i
);
1533 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1537 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1541 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, true, NULL
);
1545 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, true, NULL
);
1549 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1553 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1557 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1561 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1565 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1569 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1573 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, true, NULL
);
1576 case DNS_TYPE_LOC
: {
1580 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1585 rr
->loc
.version
= t
;
1587 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1591 if (!loc_size_ok(rr
->loc
.size
)) {
1596 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1600 if (!loc_size_ok(rr
->loc
.horiz_pre
)) {
1605 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1609 if (!loc_size_ok(rr
->loc
.vert_pre
)) {
1614 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1618 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1622 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1628 dns_packet_rewind(p
, pos
);
1629 rr
->unparseable
= true;
1635 r
= dns_packet_read_uint16(p
, &rr
->ds
.key_tag
, NULL
);
1639 r
= dns_packet_read_uint8(p
, &rr
->ds
.algorithm
, NULL
);
1643 r
= dns_packet_read_uint8(p
, &rr
->ds
.digest_type
, NULL
);
1647 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1648 &rr
->ds
.digest
, &rr
->ds
.digest_size
,
1653 if (rr
->ds
.digest_size
<= 0) {
1654 /* the accepted size depends on the algorithm, but for now
1655 just ensure that the value is greater than zero */
1661 case DNS_TYPE_SSHFP
:
1662 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1666 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1670 r
= dns_packet_read_memdup(p
, rdlength
- 2,
1671 &rr
->sshfp
.fingerprint
, &rr
->sshfp
.fingerprint_size
,
1674 if (rr
->sshfp
.fingerprint_size
<= 0) {
1675 /* the accepted size depends on the algorithm, but for now
1676 just ensure that the value is greater than zero */
1683 case DNS_TYPE_DNSKEY
:
1684 r
= dns_packet_read_uint16(p
, &rr
->dnskey
.flags
, NULL
);
1688 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.protocol
, NULL
);
1692 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.algorithm
, NULL
);
1696 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1697 &rr
->dnskey
.key
, &rr
->dnskey
.key_size
,
1700 if (rr
->dnskey
.key_size
<= 0) {
1701 /* the accepted size depends on the algorithm, but for now
1702 just ensure that the value is greater than zero */
1709 case DNS_TYPE_RRSIG
:
1710 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.type_covered
, NULL
);
1714 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.algorithm
, NULL
);
1718 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.labels
, NULL
);
1722 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.original_ttl
, NULL
);
1726 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.expiration
, NULL
);
1730 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.inception
, NULL
);
1734 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.key_tag
, NULL
);
1738 r
= dns_packet_read_name(p
, &rr
->rrsig
.signer
, false, NULL
);
1742 r
= dns_packet_read_memdup(p
, offset
+ rdlength
- p
->rindex
,
1743 &rr
->rrsig
.signature
, &rr
->rrsig
.signature_size
,
1746 if (rr
->rrsig
.signature_size
<= 0) {
1747 /* the accepted size depends on the algorithm, but for now
1748 just ensure that the value is greater than zero */
1756 r
= dns_packet_read_name(p
, &rr
->nsec
.next_domain_name
, false, NULL
);
1760 r
= dns_packet_read_type_windows(p
, &rr
->nsec
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1764 /* We accept empty NSEC bitmaps. The bit indicating the presence of the NSEC record itself
1765 * is redundant and in e.g., RFC4956 this fact is used to define a use for NSEC records
1766 * without the NSEC bit set. */
1770 case DNS_TYPE_NSEC3
: {
1773 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.algorithm
, NULL
);
1777 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.flags
, NULL
);
1781 r
= dns_packet_read_uint16(p
, &rr
->nsec3
.iterations
, NULL
);
1785 /* this may be zero */
1786 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1790 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.salt
, &rr
->nsec3
.salt_size
, NULL
);
1794 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1803 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.next_hashed_name
, &rr
->nsec3
.next_hashed_name_size
, NULL
);
1807 r
= dns_packet_read_type_windows(p
, &rr
->nsec3
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1811 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
1817 r
= dns_packet_read_memdup(p
, rdlength
, &rr
->generic
.data
, &rr
->generic
.size
, NULL
);
1824 if (p
->rindex
!= offset
+ rdlength
) {
1833 *start
= saved_rindex
;
1837 dns_packet_rewind(p
, saved_rindex
);
1841 int dns_packet_extract(DnsPacket
*p
) {
1842 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1843 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1844 size_t saved_rindex
;
1851 saved_rindex
= p
->rindex
;
1852 dns_packet_rewind(p
, DNS_PACKET_HEADER_SIZE
);
1854 n
= DNS_PACKET_QDCOUNT(p
);
1856 question
= dns_question_new(n
);
1862 for (i
= 0; i
< n
; i
++) {
1863 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1865 r
= dns_packet_read_key(p
, &key
, NULL
);
1869 r
= dns_question_add(question
, key
);
1875 n
= DNS_PACKET_RRCOUNT(p
);
1877 answer
= dns_answer_new(n
);
1883 for (i
= 0; i
< n
; i
++) {
1884 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1886 r
= dns_packet_read_rr(p
, &rr
, NULL
);
1890 r
= dns_answer_add(answer
, rr
, p
->ifindex
);
1896 p
->question
= question
;
1902 p
->extracted
= true;
1907 p
->rindex
= saved_rindex
;
1911 static const char* const dns_rcode_table
[_DNS_RCODE_MAX_DEFINED
] = {
1912 [DNS_RCODE_SUCCESS
] = "SUCCESS",
1913 [DNS_RCODE_FORMERR
] = "FORMERR",
1914 [DNS_RCODE_SERVFAIL
] = "SERVFAIL",
1915 [DNS_RCODE_NXDOMAIN
] = "NXDOMAIN",
1916 [DNS_RCODE_NOTIMP
] = "NOTIMP",
1917 [DNS_RCODE_REFUSED
] = "REFUSED",
1918 [DNS_RCODE_YXDOMAIN
] = "YXDOMAIN",
1919 [DNS_RCODE_YXRRSET
] = "YRRSET",
1920 [DNS_RCODE_NXRRSET
] = "NXRRSET",
1921 [DNS_RCODE_NOTAUTH
] = "NOTAUTH",
1922 [DNS_RCODE_NOTZONE
] = "NOTZONE",
1923 [DNS_RCODE_BADVERS
] = "BADVERS",
1924 [DNS_RCODE_BADKEY
] = "BADKEY",
1925 [DNS_RCODE_BADTIME
] = "BADTIME",
1926 [DNS_RCODE_BADMODE
] = "BADMODE",
1927 [DNS_RCODE_BADNAME
] = "BADNAME",
1928 [DNS_RCODE_BADALG
] = "BADALG",
1929 [DNS_RCODE_BADTRUNC
] = "BADTRUNC",
1931 DEFINE_STRING_TABLE_LOOKUP(dns_rcode
, int);
1933 static const char* const dns_protocol_table
[_DNS_PROTOCOL_MAX
] = {
1934 [DNS_PROTOCOL_DNS
] = "dns",
1935 [DNS_PROTOCOL_MDNS
] = "mdns",
1936 [DNS_PROTOCOL_LLMNR
] = "llmnr",
1938 DEFINE_STRING_TABLE_LOOKUP(dns_protocol
, DnsProtocol
);
1940 static const char* const dnssec_algorithm_table
[_DNSSEC_ALGORITHM_MAX_DEFINED
] = {
1941 [DNSSEC_ALGORITHM_RSAMD5
] = "RSAMD5",
1942 [DNSSEC_ALGORITHM_DH
] = "DH",
1943 [DNSSEC_ALGORITHM_DSA
] = "DSA",
1944 [DNSSEC_ALGORITHM_ECC
] = "ECC",
1945 [DNSSEC_ALGORITHM_RSASHA1
] = "RSASHA1",
1946 [DNSSEC_ALGORITHM_DSA_NSEC3_SHA1
] = "DSA-NSEC3-SHA1",
1947 [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1
] = "RSASHA1-NSEC3-SHA1",
1948 [DNSSEC_ALGORITHM_RSASHA256
] = "RSASHA256",
1949 [DNSSEC_ALGORITHM_RSASHA512
] = "RSASHA512",
1950 [DNSSEC_ALGORITHM_INDIRECT
] = "INDIRECT",
1951 [DNSSEC_ALGORITHM_PRIVATEDNS
] = "PRIVATEDNS",
1952 [DNSSEC_ALGORITHM_PRIVATEOID
] = "PRIVATEOID",
1954 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm
, int);