1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include "unaligned.h"
26 #include "dns-domain.h"
27 #include "resolved-dns-packet.h"
29 int dns_packet_new(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
35 if (mtu
<= UDP_PACKET_HEADER_SIZE
)
36 a
= DNS_PACKET_SIZE_START
;
38 a
= mtu
- UDP_PACKET_HEADER_SIZE
;
40 if (a
< DNS_PACKET_HEADER_SIZE
)
41 a
= DNS_PACKET_HEADER_SIZE
;
43 /* round up to next page size */
44 a
= PAGE_ALIGN(ALIGN(sizeof(DnsPacket
)) + a
) - ALIGN(sizeof(DnsPacket
));
46 /* make sure we never allocate more than useful */
47 if (a
> DNS_PACKET_SIZE_MAX
)
48 a
= DNS_PACKET_SIZE_MAX
;
50 p
= malloc0(ALIGN(sizeof(DnsPacket
)) + a
);
54 p
->size
= p
->rindex
= DNS_PACKET_HEADER_SIZE
;
56 p
->protocol
= protocol
;
64 int dns_packet_new_query(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
71 r
= dns_packet_new(&p
, protocol
, mtu
);
75 h
= DNS_PACKET_HEADER(p
);
77 if (protocol
== DNS_PROTOCOL_LLMNR
)
78 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
88 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
92 1 /* rd (ask for recursion) */,
102 DnsPacket
*dns_packet_ref(DnsPacket
*p
) {
107 assert(p
->n_ref
> 0);
112 static void dns_packet_free(DnsPacket
*p
) {
117 dns_question_unref(p
->question
);
118 dns_answer_unref(p
->answer
);
120 while ((s
= hashmap_steal_first_key(p
->names
)))
122 hashmap_free(p
->names
);
128 DnsPacket
*dns_packet_unref(DnsPacket
*p
) {
132 assert(p
->n_ref
> 0);
142 int dns_packet_validate(DnsPacket
*p
) {
145 if (p
->size
< DNS_PACKET_HEADER_SIZE
)
148 if (p
->size
> DNS_PACKET_SIZE_MAX
)
154 int dns_packet_validate_reply(DnsPacket
*p
) {
159 r
= dns_packet_validate(p
);
163 if (DNS_PACKET_QR(p
) != 1)
166 if (DNS_PACKET_OPCODE(p
) != 0)
169 switch (p
->protocol
) {
170 case DNS_PROTOCOL_LLMNR
:
171 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
172 if (DNS_PACKET_QDCOUNT(p
) != 1)
184 int dns_packet_validate_query(DnsPacket
*p
) {
189 r
= dns_packet_validate(p
);
193 if (DNS_PACKET_QR(p
) != 0)
196 if (DNS_PACKET_OPCODE(p
) != 0)
199 if (DNS_PACKET_TC(p
))
202 switch (p
->protocol
) {
203 case DNS_PROTOCOL_LLMNR
:
204 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
205 if (DNS_PACKET_QDCOUNT(p
) != 1)
208 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
209 if (DNS_PACKET_ANCOUNT(p
) > 0)
212 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
213 if (DNS_PACKET_NSCOUNT(p
) > 0)
225 static int dns_packet_extend(DnsPacket
*p
, size_t add
, void **ret
, size_t *start
) {
228 if (p
->size
+ add
> p
->allocated
) {
231 a
= PAGE_ALIGN((p
->size
+ add
) * 2);
232 if (a
> DNS_PACKET_SIZE_MAX
)
233 a
= DNS_PACKET_SIZE_MAX
;
235 if (p
->size
+ add
> a
)
241 d
= realloc(p
->_data
, a
);
247 p
->_data
= malloc(a
);
251 memcpy(p
->_data
, (uint8_t*) p
+ ALIGN(sizeof(DnsPacket
)), p
->size
);
252 memzero((uint8_t*) p
->_data
+ p
->size
, a
- p
->size
);
262 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->size
;
268 static void dns_packet_truncate(DnsPacket
*p
, size_t sz
) {
278 HASHMAP_FOREACH_KEY(n
, s
, p
->names
, i
) {
280 if (PTR_TO_SIZE(n
) < sz
)
283 hashmap_remove(p
->names
, s
);
290 int dns_packet_append_blob(DnsPacket
*p
, const void *d
, size_t l
, size_t *start
) {
296 r
= dns_packet_extend(p
, l
, &q
, start
);
304 int dns_packet_append_uint8(DnsPacket
*p
, uint8_t v
, size_t *start
) {
310 r
= dns_packet_extend(p
, sizeof(uint8_t), &d
, start
);
314 ((uint8_t*) d
)[0] = v
;
319 int dns_packet_append_uint16(DnsPacket
*p
, uint16_t v
, size_t *start
) {
325 r
= dns_packet_extend(p
, sizeof(uint16_t), &d
, start
);
329 unaligned_write_be16(d
, v
);
334 int dns_packet_append_uint32(DnsPacket
*p
, uint32_t v
, size_t *start
) {
340 r
= dns_packet_extend(p
, sizeof(uint32_t), &d
, start
);
344 unaligned_write_be32(d
, v
);
349 int dns_packet_append_string(DnsPacket
*p
, const char *s
, size_t *start
) {
361 r
= dns_packet_extend(p
, 1 + l
, &d
, start
);
365 ((uint8_t*) d
)[0] = (uint8_t) l
;
366 memcpy(((uint8_t*) d
) + 1, s
, l
);
371 int dns_packet_append_label(DnsPacket
*p
, const char *d
, size_t l
, size_t *start
) {
378 if (l
> DNS_LABEL_MAX
)
381 r
= dns_packet_extend(p
, 1 + l
, &w
, start
);
385 ((uint8_t*) w
)[0] = (uint8_t) l
;
386 memcpy(((uint8_t*) w
) + 1, d
, l
);
391 int dns_packet_append_name(
394 bool allow_compression
,
403 if (p
->refuse_compression
)
404 allow_compression
= false;
406 saved_size
= p
->size
;
409 _cleanup_free_
char *s
= NULL
;
410 char label
[DNS_LABEL_MAX
];
414 if (allow_compression
)
415 n
= PTR_TO_SIZE(hashmap_get(p
->names
, name
));
420 r
= dns_packet_append_uint16(p
, 0xC000 | n
, NULL
);
434 r
= dns_label_unescape(&name
, label
, sizeof(label
));
438 if (p
->protocol
== DNS_PROTOCOL_DNS
)
439 k
= dns_label_apply_idna(label
, r
, label
, sizeof(label
));
441 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
449 r
= dns_packet_append_label(p
, label
, r
, &n
);
453 if (allow_compression
) {
454 r
= hashmap_ensure_allocated(&p
->names
, &dns_name_hash_ops
);
458 r
= hashmap_put(p
->names
, s
, SIZE_TO_PTR(n
));
466 r
= dns_packet_append_uint8(p
, 0, NULL
);
477 dns_packet_truncate(p
, saved_size
);
481 int dns_packet_append_key(DnsPacket
*p
, const DnsResourceKey
*k
, size_t *start
) {
488 saved_size
= p
->size
;
490 r
= dns_packet_append_name(p
, DNS_RESOURCE_KEY_NAME(k
), true, NULL
);
494 r
= dns_packet_append_uint16(p
, k
->type
, NULL
);
498 r
= dns_packet_append_uint16(p
, k
->class, NULL
);
508 dns_packet_truncate(p
, saved_size
);
512 static int dns_packet_append_type_window(DnsPacket
*p
, uint8_t window
, uint8_t length
, uint8_t *types
, size_t *start
) {
520 saved_size
= p
->size
;
522 r
= dns_packet_append_uint8(p
, window
, NULL
);
526 r
= dns_packet_append_uint8(p
, length
, NULL
);
530 r
= dns_packet_append_blob(p
, types
, length
, NULL
);
539 dns_packet_truncate(p
, saved_size
);
543 static int dns_packet_append_types(DnsPacket
*p
, Bitmap
*types
, size_t *start
) {
547 uint8_t bitmaps
[32] = {};
555 saved_size
= p
->size
;
557 BITMAP_FOREACH(n
, types
, i
) {
560 if ((n
>> 8) != window
&& bitmaps
[entry
/ 8] != 0) {
561 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
572 bitmaps
[entry
/ 8] |= 1 << (7 - (entry
% 8));
575 r
= dns_packet_append_type_window(p
, window
, entry
/ 8 + 1, bitmaps
, NULL
);
584 dns_packet_truncate(p
, saved_size
);
588 int dns_packet_append_rr(DnsPacket
*p
, const DnsResourceRecord
*rr
, size_t *start
) {
589 size_t saved_size
, rdlength_offset
, end
, rdlength
;
595 saved_size
= p
->size
;
597 r
= dns_packet_append_key(p
, rr
->key
, NULL
);
601 r
= dns_packet_append_uint32(p
, rr
->ttl
, NULL
);
605 /* Initially we write 0 here */
606 r
= dns_packet_append_uint16(p
, 0, &rdlength_offset
);
610 switch (rr
->unparseable
? _DNS_TYPE_INVALID
: rr
->key
->type
) {
613 r
= dns_packet_append_uint16(p
, rr
->srv
.priority
, NULL
);
617 r
= dns_packet_append_uint16(p
, rr
->srv
.weight
, NULL
);
621 r
= dns_packet_append_uint16(p
, rr
->srv
.port
, NULL
);
625 r
= dns_packet_append_name(p
, rr
->srv
.name
, true, NULL
);
632 r
= dns_packet_append_name(p
, rr
->ptr
.name
, true, NULL
);
636 r
= dns_packet_append_string(p
, rr
->hinfo
.cpu
, NULL
);
640 r
= dns_packet_append_string(p
, rr
->hinfo
.os
, NULL
);
643 case DNS_TYPE_SPF
: /* exactly the same as TXT */
647 if (strv_isempty(rr
->txt
.strings
)) {
648 /* RFC 6763, section 6.1 suggests to generate
649 * single empty string for an empty array. */
651 r
= dns_packet_append_string(p
, "", NULL
);
655 STRV_FOREACH(s
, rr
->txt
.strings
) {
656 r
= dns_packet_append_string(p
, *s
, NULL
);
667 r
= dns_packet_append_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
671 r
= dns_packet_append_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
675 r
= dns_packet_append_name(p
, rr
->soa
.mname
, true, NULL
);
679 r
= dns_packet_append_name(p
, rr
->soa
.rname
, true, NULL
);
683 r
= dns_packet_append_uint32(p
, rr
->soa
.serial
, NULL
);
687 r
= dns_packet_append_uint32(p
, rr
->soa
.refresh
, NULL
);
691 r
= dns_packet_append_uint32(p
, rr
->soa
.retry
, NULL
);
695 r
= dns_packet_append_uint32(p
, rr
->soa
.expire
, NULL
);
699 r
= dns_packet_append_uint32(p
, rr
->soa
.minimum
, NULL
);
703 r
= dns_packet_append_uint16(p
, rr
->mx
.priority
, NULL
);
707 r
= dns_packet_append_name(p
, rr
->mx
.exchange
, true, NULL
);
711 r
= dns_packet_append_uint8(p
, rr
->loc
.version
, NULL
);
715 r
= dns_packet_append_uint8(p
, rr
->loc
.size
, NULL
);
719 r
= dns_packet_append_uint8(p
, rr
->loc
.horiz_pre
, NULL
);
723 r
= dns_packet_append_uint8(p
, rr
->loc
.vert_pre
, NULL
);
727 r
= dns_packet_append_uint32(p
, rr
->loc
.latitude
, NULL
);
731 r
= dns_packet_append_uint32(p
, rr
->loc
.longitude
, NULL
);
735 r
= dns_packet_append_uint32(p
, rr
->loc
.altitude
, NULL
);
739 r
= dns_packet_append_uint16(p
, rr
->ds
.key_tag
, NULL
);
743 r
= dns_packet_append_uint8(p
, rr
->ds
.algorithm
, NULL
);
747 r
= dns_packet_append_uint8(p
, rr
->ds
.digest_type
, NULL
);
751 r
= dns_packet_append_blob(p
, rr
->ds
.digest
, rr
->ds
.digest_size
, NULL
);
755 r
= dns_packet_append_uint8(p
, rr
->sshfp
.algorithm
, NULL
);
759 r
= dns_packet_append_uint8(p
, rr
->sshfp
.fptype
, NULL
);
763 r
= dns_packet_append_blob(p
, rr
->sshfp
.fingerprint
, rr
->sshfp
.fingerprint_size
, NULL
);
766 case DNS_TYPE_DNSKEY
:
767 r
= dns_packet_append_uint16(p
, dnskey_to_flags(rr
), NULL
);
771 r
= dns_packet_append_uint8(p
, 3u, NULL
);
775 r
= dns_packet_append_uint8(p
, rr
->dnskey
.algorithm
, NULL
);
779 r
= dns_packet_append_blob(p
, rr
->dnskey
.key
, rr
->dnskey
.key_size
, NULL
);
783 r
= dns_packet_append_uint16(p
, rr
->rrsig
.type_covered
, NULL
);
787 r
= dns_packet_append_uint8(p
, rr
->rrsig
.algorithm
, NULL
);
791 r
= dns_packet_append_uint8(p
, rr
->rrsig
.labels
, NULL
);
795 r
= dns_packet_append_uint32(p
, rr
->rrsig
.original_ttl
, NULL
);
799 r
= dns_packet_append_uint32(p
, rr
->rrsig
.expiration
, NULL
);
803 r
= dns_packet_append_uint32(p
, rr
->rrsig
.inception
, NULL
);
807 r
= dns_packet_append_uint16(p
, rr
->rrsig
.key_tag
, NULL
);
811 r
= dns_packet_append_name(p
, rr
->rrsig
.signer
, false, NULL
);
815 r
= dns_packet_append_blob(p
, rr
->rrsig
.signature
, rr
->rrsig
.signature_size
, NULL
);
819 r
= dns_packet_append_name(p
, rr
->nsec
.next_domain_name
, false, NULL
);
823 r
= dns_packet_append_types(p
, rr
->nsec
.types
, NULL
);
829 r
= dns_packet_append_uint8(p
, rr
->nsec3
.algorithm
, NULL
);
833 r
= dns_packet_append_uint8(p
, rr
->nsec3
.flags
, NULL
);
837 r
= dns_packet_append_uint16(p
, rr
->nsec3
.iterations
, NULL
);
841 r
= dns_packet_append_uint8(p
, rr
->nsec3
.salt_size
, NULL
);
845 r
= dns_packet_append_blob(p
, rr
->nsec3
.salt
, rr
->nsec3
.salt_size
, NULL
);
849 r
= dns_packet_append_uint8(p
, rr
->nsec3
.next_hashed_name_size
, NULL
);
853 r
= dns_packet_append_blob(p
, rr
->nsec3
.next_hashed_name
, rr
->nsec3
.next_hashed_name_size
, NULL
);
857 r
= dns_packet_append_types(p
, rr
->nsec3
.types
, NULL
);
862 case _DNS_TYPE_INVALID
: /* unparseable */
865 r
= dns_packet_append_blob(p
, rr
->generic
.data
, rr
->generic
.size
, NULL
);
871 /* Let's calculate the actual data size and update the field */
872 rdlength
= p
->size
- rdlength_offset
- sizeof(uint16_t);
873 if (rdlength
> 0xFFFF) {
879 p
->size
= rdlength_offset
;
880 r
= dns_packet_append_uint16(p
, rdlength
, NULL
);
891 dns_packet_truncate(p
, saved_size
);
896 int dns_packet_read(DnsPacket
*p
, size_t sz
, const void **ret
, size_t *start
) {
899 if (p
->rindex
+ sz
> p
->size
)
903 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->rindex
;
912 void dns_packet_rewind(DnsPacket
*p
, size_t idx
) {
914 assert(idx
<= p
->size
);
915 assert(idx
>= DNS_PACKET_HEADER_SIZE
);
920 int dns_packet_read_blob(DnsPacket
*p
, void *d
, size_t sz
, size_t *start
) {
927 r
= dns_packet_read(p
, sz
, &q
, start
);
935 static int dns_packet_read_memdup(
936 DnsPacket
*p
, size_t size
,
937 void **ret
, size_t *ret_size
,
947 r
= dns_packet_read(p
, size
, &src
, &start
);
956 copy
= memdup(src
, size
);
971 int dns_packet_read_uint8(DnsPacket
*p
, uint8_t *ret
, size_t *start
) {
977 r
= dns_packet_read(p
, sizeof(uint8_t), &d
, start
);
981 *ret
= ((uint8_t*) d
)[0];
985 int dns_packet_read_uint16(DnsPacket
*p
, uint16_t *ret
, size_t *start
) {
991 r
= dns_packet_read(p
, sizeof(uint16_t), &d
, start
);
995 *ret
= unaligned_read_be16(d
);
1000 int dns_packet_read_uint32(DnsPacket
*p
, uint32_t *ret
, size_t *start
) {
1006 r
= dns_packet_read(p
, sizeof(uint32_t), &d
, start
);
1010 *ret
= unaligned_read_be32(d
);
1015 int dns_packet_read_string(DnsPacket
*p
, char **ret
, size_t *start
) {
1016 size_t saved_rindex
;
1024 saved_rindex
= p
->rindex
;
1026 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1030 r
= dns_packet_read(p
, c
, &d
, NULL
);
1034 if (memchr(d
, 0, c
)) {
1045 if (!utf8_is_valid(t
)) {
1054 *start
= saved_rindex
;
1059 dns_packet_rewind(p
, saved_rindex
);
1063 int dns_packet_read_name(
1066 bool allow_compression
,
1069 size_t saved_rindex
, after_rindex
= 0, jump_barrier
;
1070 _cleanup_free_
char *ret
= NULL
;
1071 size_t n
= 0, allocated
= 0;
1078 if (p
->refuse_compression
)
1079 allow_compression
= false;
1081 saved_rindex
= p
->rindex
;
1082 jump_barrier
= p
->rindex
;
1087 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1095 _cleanup_free_
char *t
= NULL
;
1099 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
1103 r
= dns_label_escape(label
, c
, &t
);
1107 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ strlen(t
) + 1)) {
1117 memcpy(ret
+ n
, t
, r
);
1120 } else if (allow_compression
&& (c
& 0xc0) == 0xc0) {
1124 r
= dns_packet_read_uint8(p
, &d
, NULL
);
1128 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
1129 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= jump_barrier
) {
1134 if (after_rindex
== 0)
1135 after_rindex
= p
->rindex
;
1137 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1146 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1)) {
1153 if (after_rindex
!= 0)
1154 p
->rindex
= after_rindex
;
1160 *start
= saved_rindex
;
1165 dns_packet_rewind(p
, saved_rindex
);
1169 static int dns_packet_read_type_window(DnsPacket
*p
, Bitmap
**types
, size_t *start
) {
1172 const uint8_t *bitmap
;
1176 size_t saved_rindex
;
1182 saved_rindex
= p
->rindex
;
1184 r
= bitmap_ensure_allocated(types
);
1188 r
= dns_packet_read_uint8(p
, &window
, NULL
);
1192 r
= dns_packet_read_uint8(p
, &length
, NULL
);
1196 if (length
== 0 || length
> 32)
1199 r
= dns_packet_read(p
, length
, (const void **)&bitmap
, NULL
);
1203 for (i
= 0; i
< length
; i
++) {
1204 uint8_t bitmask
= 1 << 7;
1215 if (bitmap
[i
] & bitmask
) {
1218 n
= (uint16_t) window
<< 8 | (uint16_t) bit
;
1220 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1221 if (dns_type_is_pseudo(n
))
1224 r
= bitmap_set(*types
, n
);
1238 *start
= saved_rindex
;
1242 dns_packet_rewind(p
, saved_rindex
);
1246 static int dns_packet_read_type_windows(DnsPacket
*p
, Bitmap
**types
, size_t size
, size_t *start
) {
1247 size_t saved_rindex
;
1250 saved_rindex
= p
->rindex
;
1252 while (p
->rindex
< saved_rindex
+ size
) {
1253 r
= dns_packet_read_type_window(p
, types
, NULL
);
1257 /* don't read past end of current RR */
1258 if (p
->rindex
> saved_rindex
+ size
) {
1264 if (p
->rindex
!= saved_rindex
+ size
) {
1270 *start
= saved_rindex
;
1274 dns_packet_rewind(p
, saved_rindex
);
1278 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, size_t *start
) {
1279 _cleanup_free_
char *name
= NULL
;
1280 uint16_t class, type
;
1281 DnsResourceKey
*key
;
1282 size_t saved_rindex
;
1288 saved_rindex
= p
->rindex
;
1290 r
= dns_packet_read_name(p
, &name
, true, NULL
);
1294 r
= dns_packet_read_uint16(p
, &type
, NULL
);
1298 r
= dns_packet_read_uint16(p
, &class, NULL
);
1302 key
= dns_resource_key_new_consume(class, type
, name
);
1312 *start
= saved_rindex
;
1316 dns_packet_rewind(p
, saved_rindex
);
1320 static bool loc_size_ok(uint8_t size
) {
1321 uint8_t m
= size
>> 4, e
= size
& 0xF;
1323 return m
<= 9 && e
<= 9 && (m
> 0 || e
== 0);
1326 static int dnskey_parse_flags(DnsResourceRecord
*rr
, uint16_t flags
) {
1329 if (flags
& ~(DNSKEY_FLAG_SEP
| DNSKEY_FLAG_ZONE_KEY
))
1332 rr
->dnskey
.zone_key_flag
= flags
& DNSKEY_FLAG_ZONE_KEY
;
1333 rr
->dnskey
.sep_flag
= flags
& DNSKEY_FLAG_SEP
;
1337 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, size_t *start
) {
1338 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1339 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1340 size_t saved_rindex
, offset
;
1347 saved_rindex
= p
->rindex
;
1349 r
= dns_packet_read_key(p
, &key
, NULL
);
1353 if (key
->class == DNS_CLASS_ANY
||
1354 key
->type
== DNS_TYPE_ANY
) {
1359 rr
= dns_resource_record_new(key
);
1365 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
1369 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
1373 if (p
->rindex
+ rdlength
> p
->size
) {
1380 switch (rr
->key
->type
) {
1383 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
1386 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
1389 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
1392 r
= dns_packet_read_name(p
, &rr
->srv
.name
, true, NULL
);
1397 case DNS_TYPE_CNAME
:
1398 case DNS_TYPE_DNAME
:
1399 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, true, NULL
);
1402 case DNS_TYPE_HINFO
:
1403 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1407 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1410 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1412 if (rdlength
<= 0) {
1413 /* RFC 6763, section 6.1 suggests to treat
1414 * empty TXT RRs as equivalent to a TXT record
1415 * with a single empty string. */
1417 r
= strv_extend(&rr
->txt
.strings
, "");
1421 while (p
->rindex
< offset
+ rdlength
) {
1424 r
= dns_packet_read_string(p
, &s
, NULL
);
1428 r
= strv_consume(&rr
->txt
.strings
, s
);
1438 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1442 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1446 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, true, NULL
);
1450 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, true, NULL
);
1454 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1458 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1462 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1466 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1470 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1474 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1478 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, true, NULL
);
1481 case DNS_TYPE_LOC
: {
1485 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1490 rr
->loc
.version
= t
;
1492 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1496 if (!loc_size_ok(rr
->loc
.size
)) {
1501 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1505 if (!loc_size_ok(rr
->loc
.horiz_pre
)) {
1510 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1514 if (!loc_size_ok(rr
->loc
.vert_pre
)) {
1519 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1523 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1527 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1533 dns_packet_rewind(p
, pos
);
1534 rr
->unparseable
= true;
1540 r
= dns_packet_read_uint16(p
, &rr
->ds
.key_tag
, NULL
);
1544 r
= dns_packet_read_uint8(p
, &rr
->ds
.algorithm
, NULL
);
1548 r
= dns_packet_read_uint8(p
, &rr
->ds
.digest_type
, NULL
);
1552 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1553 &rr
->ds
.digest
, &rr
->ds
.digest_size
,
1558 if (rr
->ds
.digest_size
<= 0) {
1559 /* the accepted size depends on the algorithm, but for now
1560 just ensure that the value is greater than zero */
1566 case DNS_TYPE_SSHFP
:
1567 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1571 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1575 r
= dns_packet_read_memdup(p
, rdlength
- 2,
1576 &rr
->sshfp
.fingerprint
, &rr
->sshfp
.fingerprint_size
,
1579 if (rr
->sshfp
.fingerprint_size
<= 0) {
1580 /* the accepted size depends on the algorithm, but for now
1581 just ensure that the value is greater than zero */
1588 case DNS_TYPE_DNSKEY
: {
1592 r
= dns_packet_read_uint16(p
, &flags
, NULL
);
1596 r
= dnskey_parse_flags(rr
, flags
);
1600 r
= dns_packet_read_uint8(p
, &proto
, NULL
);
1604 /* protocol is required to be always 3 */
1610 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.algorithm
, NULL
);
1614 r
= dns_packet_read_memdup(p
, rdlength
- 4,
1615 &rr
->dnskey
.key
, &rr
->dnskey
.key_size
,
1618 if (rr
->dnskey
.key_size
<= 0) {
1619 /* the accepted size depends on the algorithm, but for now
1620 just ensure that the value is greater than zero */
1628 case DNS_TYPE_RRSIG
:
1629 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.type_covered
, NULL
);
1633 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.algorithm
, NULL
);
1637 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.labels
, NULL
);
1641 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.original_ttl
, NULL
);
1645 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.expiration
, NULL
);
1649 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.inception
, NULL
);
1653 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.key_tag
, NULL
);
1657 r
= dns_packet_read_name(p
, &rr
->rrsig
.signer
, false, NULL
);
1661 r
= dns_packet_read_memdup(p
, offset
+ rdlength
- p
->rindex
,
1662 &rr
->rrsig
.signature
, &rr
->rrsig
.signature_size
,
1665 if (rr
->rrsig
.signature_size
<= 0) {
1666 /* the accepted size depends on the algorithm, but for now
1667 just ensure that the value is greater than zero */
1675 r
= dns_packet_read_name(p
, &rr
->nsec
.next_domain_name
, false, NULL
);
1679 r
= dns_packet_read_type_windows(p
, &rr
->nsec
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1683 /* The types bitmap must contain at least the NSEC record itself, so an empty bitmap means
1684 something went wrong */
1685 if (bitmap_isclear(rr
->nsec
.types
)) {
1692 case DNS_TYPE_NSEC3
: {
1695 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.algorithm
, NULL
);
1699 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.flags
, NULL
);
1703 r
= dns_packet_read_uint16(p
, &rr
->nsec3
.iterations
, NULL
);
1707 /* this may be zero */
1708 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1712 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.salt
, &rr
->nsec3
.salt_size
, NULL
);
1716 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1725 r
= dns_packet_read_memdup(p
, size
, &rr
->nsec3
.next_hashed_name
, &rr
->nsec3
.next_hashed_name_size
, NULL
);
1729 r
= dns_packet_read_type_windows(p
, &rr
->nsec3
.types
, offset
+ rdlength
- p
->rindex
, NULL
);
1733 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
1739 r
= dns_packet_read_memdup(p
, rdlength
, &rr
->generic
.data
, &rr
->generic
.size
, NULL
);
1746 if (p
->rindex
!= offset
+ rdlength
) {
1755 *start
= saved_rindex
;
1759 dns_packet_rewind(p
, saved_rindex
);
1763 int dns_packet_extract(DnsPacket
*p
) {
1764 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1765 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1766 size_t saved_rindex
;
1773 saved_rindex
= p
->rindex
;
1774 dns_packet_rewind(p
, DNS_PACKET_HEADER_SIZE
);
1776 n
= DNS_PACKET_QDCOUNT(p
);
1778 question
= dns_question_new(n
);
1784 for (i
= 0; i
< n
; i
++) {
1785 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1787 r
= dns_packet_read_key(p
, &key
, NULL
);
1791 r
= dns_question_add(question
, key
);
1797 n
= DNS_PACKET_RRCOUNT(p
);
1799 answer
= dns_answer_new(n
);
1805 for (i
= 0; i
< n
; i
++) {
1806 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1808 r
= dns_packet_read_rr(p
, &rr
, NULL
);
1812 r
= dns_answer_add(answer
, rr
, p
->ifindex
);
1818 p
->question
= question
;
1824 p
->extracted
= true;
1829 p
->rindex
= saved_rindex
;
1833 static const char* const dns_rcode_table
[_DNS_RCODE_MAX_DEFINED
] = {
1834 [DNS_RCODE_SUCCESS
] = "SUCCESS",
1835 [DNS_RCODE_FORMERR
] = "FORMERR",
1836 [DNS_RCODE_SERVFAIL
] = "SERVFAIL",
1837 [DNS_RCODE_NXDOMAIN
] = "NXDOMAIN",
1838 [DNS_RCODE_NOTIMP
] = "NOTIMP",
1839 [DNS_RCODE_REFUSED
] = "REFUSED",
1840 [DNS_RCODE_YXDOMAIN
] = "YXDOMAIN",
1841 [DNS_RCODE_YXRRSET
] = "YRRSET",
1842 [DNS_RCODE_NXRRSET
] = "NXRRSET",
1843 [DNS_RCODE_NOTAUTH
] = "NOTAUTH",
1844 [DNS_RCODE_NOTZONE
] = "NOTZONE",
1845 [DNS_RCODE_BADVERS
] = "BADVERS",
1846 [DNS_RCODE_BADKEY
] = "BADKEY",
1847 [DNS_RCODE_BADTIME
] = "BADTIME",
1848 [DNS_RCODE_BADMODE
] = "BADMODE",
1849 [DNS_RCODE_BADNAME
] = "BADNAME",
1850 [DNS_RCODE_BADALG
] = "BADALG",
1851 [DNS_RCODE_BADTRUNC
] = "BADTRUNC",
1853 DEFINE_STRING_TABLE_LOOKUP(dns_rcode
, int);
1855 static const char* const dns_protocol_table
[_DNS_PROTOCOL_MAX
] = {
1856 [DNS_PROTOCOL_DNS
] = "dns",
1857 [DNS_PROTOCOL_MDNS
] = "mdns",
1858 [DNS_PROTOCOL_LLMNR
] = "llmnr",
1860 DEFINE_STRING_TABLE_LOOKUP(dns_protocol
, DnsProtocol
);
1862 static const char* const dnssec_algorithm_table
[_DNSSEC_ALGORITHM_MAX_DEFINED
] = {
1863 [DNSSEC_ALGORITHM_RSAMD5
] = "RSAMD5",
1864 [DNSSEC_ALGORITHM_DH
] = "DH",
1865 [DNSSEC_ALGORITHM_DSA
] = "DSA",
1866 [DNSSEC_ALGORITHM_ECC
] = "ECC",
1867 [DNSSEC_ALGORITHM_RSASHA1
] = "RSASHA1",
1868 [DNSSEC_ALGORITHM_DSA_NSEC3_SHA1
] = "DSA-NSEC3-SHA1",
1869 [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1
] = "RSASHA1-NSEC3-SHA1",
1870 [DNSSEC_ALGORITHM_INDIRECT
] = "INDIRECT",
1871 [DNSSEC_ALGORITHM_PRIVATEDNS
] = "PRIVATEDNS",
1872 [DNSSEC_ALGORITHM_PRIVATEOID
] = "PRIVATEOID",
1874 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm
, int);