1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include "unaligned.h"
26 #include "dns-domain.h"
27 #include "resolved-dns-packet.h"
29 int dns_packet_new(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
35 if (mtu
<= UDP_PACKET_HEADER_SIZE
)
36 a
= DNS_PACKET_SIZE_START
;
38 a
= mtu
- UDP_PACKET_HEADER_SIZE
;
40 if (a
< DNS_PACKET_HEADER_SIZE
)
41 a
= DNS_PACKET_HEADER_SIZE
;
43 /* round up to next page size */
44 a
= PAGE_ALIGN(ALIGN(sizeof(DnsPacket
)) + a
) - ALIGN(sizeof(DnsPacket
));
46 /* make sure we never allocate more than useful */
47 if (a
> DNS_PACKET_SIZE_MAX
)
48 a
= DNS_PACKET_SIZE_MAX
;
50 p
= malloc0(ALIGN(sizeof(DnsPacket
)) + a
);
54 p
->size
= p
->rindex
= DNS_PACKET_HEADER_SIZE
;
56 p
->protocol
= protocol
;
64 int dns_packet_new_query(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
71 r
= dns_packet_new(&p
, protocol
, mtu
);
75 h
= DNS_PACKET_HEADER(p
);
77 if (protocol
== DNS_PROTOCOL_LLMNR
)
78 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
88 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
92 1 /* rd (ask for recursion) */,
102 DnsPacket
*dns_packet_ref(DnsPacket
*p
) {
107 assert(p
->n_ref
> 0);
112 static void dns_packet_free(DnsPacket
*p
) {
117 dns_question_unref(p
->question
);
118 dns_answer_unref(p
->answer
);
120 while ((s
= hashmap_steal_first_key(p
->names
)))
122 hashmap_free(p
->names
);
128 DnsPacket
*dns_packet_unref(DnsPacket
*p
) {
132 assert(p
->n_ref
> 0);
142 int dns_packet_validate(DnsPacket
*p
) {
145 if (p
->size
< DNS_PACKET_HEADER_SIZE
)
148 if (p
->size
> DNS_PACKET_SIZE_MAX
)
154 int dns_packet_validate_reply(DnsPacket
*p
) {
159 r
= dns_packet_validate(p
);
163 if (DNS_PACKET_QR(p
) != 1)
166 if (DNS_PACKET_OPCODE(p
) != 0)
169 switch (p
->protocol
) {
170 case DNS_PROTOCOL_LLMNR
:
171 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
172 if (DNS_PACKET_QDCOUNT(p
) != 1)
184 int dns_packet_validate_query(DnsPacket
*p
) {
189 r
= dns_packet_validate(p
);
193 if (DNS_PACKET_QR(p
) != 0)
196 if (DNS_PACKET_OPCODE(p
) != 0)
199 if (DNS_PACKET_TC(p
))
202 switch (p
->protocol
) {
203 case DNS_PROTOCOL_LLMNR
:
204 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
205 if (DNS_PACKET_QDCOUNT(p
) != 1)
208 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
209 if (DNS_PACKET_ANCOUNT(p
) > 0)
212 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
213 if (DNS_PACKET_NSCOUNT(p
) > 0)
225 static int dns_packet_extend(DnsPacket
*p
, size_t add
, void **ret
, size_t *start
) {
228 if (p
->size
+ add
> p
->allocated
) {
231 a
= PAGE_ALIGN((p
->size
+ add
) * 2);
232 if (a
> DNS_PACKET_SIZE_MAX
)
233 a
= DNS_PACKET_SIZE_MAX
;
235 if (p
->size
+ add
> a
)
241 d
= realloc(p
->_data
, a
);
247 p
->_data
= malloc(a
);
251 memcpy(p
->_data
, (uint8_t*) p
+ ALIGN(sizeof(DnsPacket
)), p
->size
);
252 memzero((uint8_t*) p
->_data
+ p
->size
, a
- p
->size
);
262 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->size
;
268 static void dns_packet_truncate(DnsPacket
*p
, size_t sz
) {
278 HASHMAP_FOREACH_KEY(s
, n
, p
->names
, i
) {
280 if (PTR_TO_SIZE(n
) < sz
)
283 hashmap_remove(p
->names
, s
);
290 int dns_packet_append_blob(DnsPacket
*p
, const void *d
, size_t l
, size_t *start
) {
296 r
= dns_packet_extend(p
, l
, &q
, start
);
304 int dns_packet_append_uint8(DnsPacket
*p
, uint8_t v
, size_t *start
) {
310 r
= dns_packet_extend(p
, sizeof(uint8_t), &d
, start
);
314 ((uint8_t*) d
)[0] = v
;
319 int dns_packet_append_uint16(DnsPacket
*p
, uint16_t v
, size_t *start
) {
325 r
= dns_packet_extend(p
, sizeof(uint16_t), &d
, start
);
329 unaligned_write_be16(d
, v
);
334 int dns_packet_append_uint32(DnsPacket
*p
, uint32_t v
, size_t *start
) {
340 r
= dns_packet_extend(p
, sizeof(uint32_t), &d
, start
);
344 unaligned_write_be32(d
, v
);
349 int dns_packet_append_string(DnsPacket
*p
, const char *s
, size_t *start
) {
361 r
= dns_packet_extend(p
, 1 + l
, &d
, start
);
365 ((uint8_t*) d
)[0] = (uint8_t) l
;
366 memcpy(((uint8_t*) d
) + 1, s
, l
);
371 int dns_packet_append_label(DnsPacket
*p
, const char *d
, size_t l
, size_t *start
) {
378 if (l
> DNS_LABEL_MAX
)
381 r
= dns_packet_extend(p
, 1 + l
, &w
, start
);
385 ((uint8_t*) w
)[0] = (uint8_t) l
;
386 memcpy(((uint8_t*) w
) + 1, d
, l
);
391 int dns_packet_append_name(DnsPacket
*p
, const char *name
,
392 bool allow_compression
, size_t *start
) {
399 saved_size
= p
->size
;
402 _cleanup_free_
char *s
= NULL
;
403 char label
[DNS_LABEL_MAX
];
407 if (allow_compression
)
408 n
= PTR_TO_SIZE(hashmap_get(p
->names
, name
));
413 r
= dns_packet_append_uint16(p
, 0xC000 | n
, NULL
);
427 r
= dns_label_unescape(&name
, label
, sizeof(label
));
431 if (p
->protocol
== DNS_PROTOCOL_DNS
)
432 k
= dns_label_apply_idna(label
, r
, label
, sizeof(label
));
434 k
= dns_label_undo_idna(label
, r
, label
, sizeof(label
));
442 r
= dns_packet_append_label(p
, label
, r
, &n
);
446 if (allow_compression
) {
447 r
= hashmap_ensure_allocated(&p
->names
, &dns_name_hash_ops
);
451 r
= hashmap_put(p
->names
, s
, SIZE_TO_PTR(n
));
459 r
= dns_packet_append_uint8(p
, 0, NULL
);
470 dns_packet_truncate(p
, saved_size
);
474 int dns_packet_append_key(DnsPacket
*p
, const DnsResourceKey
*k
, size_t *start
) {
481 saved_size
= p
->size
;
483 r
= dns_packet_append_name(p
, DNS_RESOURCE_KEY_NAME(k
), true, NULL
);
487 r
= dns_packet_append_uint16(p
, k
->type
, NULL
);
491 r
= dns_packet_append_uint16(p
, k
->class, NULL
);
501 dns_packet_truncate(p
, saved_size
);
505 static int dns_packet_append_type_window(DnsPacket
*p
, uint8_t window
, uint8_t length
, uint8_t *types
, size_t *start
) {
515 saved_size
= p
->size
;
517 r
= dns_packet_append_uint8(p
, window
, NULL
);
521 r
= dns_packet_append_uint8(p
, length
, NULL
);
525 r
= dns_packet_append_blob(p
, types
, length
, NULL
);
534 dns_packet_truncate(p
, saved_size
);
538 static int dns_packet_append_types(DnsPacket
*p
, Bitmap
*types
, size_t *start
) {
541 uint8_t bitmaps
[32] = {};
549 saved_size
= p
->size
;
551 BITMAP_FOREACH(n
, types
) {
556 if ((n
<< 8) != window
) {
557 r
= dns_packet_append_type_window(p
, window
, len
, bitmaps
, NULL
);
572 bitmaps
[entry
/ 8] |= 1 << (7 - (entry
% 8));
575 r
= dns_packet_append_type_window(p
, window
, len
, 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
.key
, rr
->sshfp
.key_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 int dns_packet_read_uint8(DnsPacket
*p
, uint8_t *ret
, size_t *start
) {
941 r
= dns_packet_read(p
, sizeof(uint8_t), &d
, start
);
945 *ret
= ((uint8_t*) d
)[0];
949 int dns_packet_read_uint16(DnsPacket
*p
, uint16_t *ret
, size_t *start
) {
955 r
= dns_packet_read(p
, sizeof(uint16_t), &d
, start
);
959 *ret
= unaligned_read_be16(d
);
964 int dns_packet_read_uint32(DnsPacket
*p
, uint32_t *ret
, size_t *start
) {
970 r
= dns_packet_read(p
, sizeof(uint32_t), &d
, start
);
974 *ret
= unaligned_read_be32(d
);
979 int dns_packet_read_string(DnsPacket
*p
, char **ret
, size_t *start
) {
988 saved_rindex
= p
->rindex
;
990 r
= dns_packet_read_uint8(p
, &c
, NULL
);
994 r
= dns_packet_read(p
, c
, &d
, NULL
);
998 if (memchr(d
, 0, c
)) {
1009 if (!utf8_is_valid(t
)) {
1018 *start
= saved_rindex
;
1023 dns_packet_rewind(p
, saved_rindex
);
1027 int dns_packet_read_name(DnsPacket
*p
, char **_ret
,
1028 bool allow_compression
, size_t *start
) {
1029 size_t saved_rindex
, after_rindex
= 0, jump_barrier
;
1030 _cleanup_free_
char *ret
= NULL
;
1031 size_t n
= 0, allocated
= 0;
1038 saved_rindex
= p
->rindex
;
1039 jump_barrier
= p
->rindex
;
1044 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1052 _cleanup_free_
char *t
= NULL
;
1056 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
1060 r
= dns_label_escape(label
, c
, &t
);
1064 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ strlen(t
) + 1)) {
1074 memcpy(ret
+ n
, t
, r
);
1077 } else if (allow_compression
&& (c
& 0xc0) == 0xc0) {
1081 r
= dns_packet_read_uint8(p
, &d
, NULL
);
1085 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
1086 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= jump_barrier
) {
1091 if (after_rindex
== 0)
1092 after_rindex
= p
->rindex
;
1094 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1103 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1)) {
1110 if (after_rindex
!= 0)
1111 p
->rindex
= after_rindex
;
1117 *start
= saved_rindex
;
1122 dns_packet_rewind(p
, saved_rindex
);
1126 static int dns_packet_read_type_window(DnsPacket
*p
, Bitmap
**types
, size_t *start
) {
1129 const uint8_t *bitmap
;
1132 size_t saved_rindex
;
1138 saved_rindex
= p
->rindex
;
1140 r
= bitmap_ensure_allocated(types
);
1144 r
= dns_packet_read_uint8(p
, &window
, NULL
);
1148 r
= dns_packet_read_uint8(p
, &length
, NULL
);
1152 if (length
== 0 || length
> 32)
1155 r
= dns_packet_read(p
, length
, (const void **)&bitmap
, NULL
);
1159 for (i
= 0; i
< length
; i
++) {
1160 uint8_t bitmask
= 1 << 7;
1171 if (bitmap
[i
] & bitmask
) {
1174 /* XXX: ignore pseudo-types? see RFC4034 section 4.1.2 */
1175 n
= (uint16_t) window
<< 8 | (uint16_t) bit
;
1177 r
= bitmap_set(*types
, n
);
1191 *start
= saved_rindex
;
1195 dns_packet_rewind(p
, saved_rindex
);
1199 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, size_t *start
) {
1200 _cleanup_free_
char *name
= NULL
;
1201 uint16_t class, type
;
1202 DnsResourceKey
*key
;
1203 size_t saved_rindex
;
1209 saved_rindex
= p
->rindex
;
1211 r
= dns_packet_read_name(p
, &name
, true, NULL
);
1215 r
= dns_packet_read_uint16(p
, &type
, NULL
);
1219 r
= dns_packet_read_uint16(p
, &class, NULL
);
1223 key
= dns_resource_key_new_consume(class, type
, name
);
1233 *start
= saved_rindex
;
1237 dns_packet_rewind(p
, saved_rindex
);
1241 static int dns_packet_read_public_key(DnsPacket
*p
, size_t length
,
1242 void **dp
, size_t *lengthp
,
1248 r
= dns_packet_read(p
, length
, &d
, NULL
);
1252 d2
= memdup(d
, length
);
1261 static bool loc_size_ok(uint8_t size
) {
1262 uint8_t m
= size
>> 4, e
= size
& 0xF;
1264 return m
<= 9 && e
<= 9 && (m
> 0 || e
== 0);
1267 static int dnskey_parse_flags(DnsResourceRecord
*rr
, uint16_t flags
) {
1270 if (flags
& ~(DNSKEY_FLAG_SEP
| DNSKEY_FLAG_ZONE_KEY
))
1273 rr
->dnskey
.zone_key_flag
= flags
& DNSKEY_FLAG_ZONE_KEY
;
1274 rr
->dnskey
.sep_flag
= flags
& DNSKEY_FLAG_SEP
;
1278 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, size_t *start
) {
1279 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1280 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1281 size_t saved_rindex
, offset
;
1289 saved_rindex
= p
->rindex
;
1291 r
= dns_packet_read_key(p
, &key
, NULL
);
1295 if (key
->class == DNS_CLASS_ANY
||
1296 key
->type
== DNS_TYPE_ANY
) {
1301 rr
= dns_resource_record_new(key
);
1307 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
1311 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
1315 if (p
->rindex
+ rdlength
> p
->size
) {
1322 switch (rr
->key
->type
) {
1325 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
1328 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
1331 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
1334 r
= dns_packet_read_name(p
, &rr
->srv
.name
, true, NULL
);
1339 case DNS_TYPE_CNAME
:
1340 case DNS_TYPE_DNAME
:
1341 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, true, NULL
);
1344 case DNS_TYPE_HINFO
:
1345 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1349 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1352 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1354 if (rdlength
<= 0) {
1355 /* RFC 6763, section 6.1 suggests to treat
1356 * empty TXT RRs as equivalent to a TXT record
1357 * with a single empty string. */
1359 r
= strv_extend(&rr
->txt
.strings
, "");
1363 while (p
->rindex
< offset
+ rdlength
) {
1366 r
= dns_packet_read_string(p
, &s
, NULL
);
1370 r
= strv_consume(&rr
->txt
.strings
, s
);
1380 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1384 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1388 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, true, NULL
);
1392 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, true, NULL
);
1396 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1400 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1404 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1408 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1412 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1416 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1420 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, true, NULL
);
1423 case DNS_TYPE_LOC
: {
1427 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1432 rr
->loc
.version
= t
;
1434 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1438 if (!loc_size_ok(rr
->loc
.size
)) {
1443 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1447 if (!loc_size_ok(rr
->loc
.horiz_pre
)) {
1452 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1456 if (!loc_size_ok(rr
->loc
.vert_pre
)) {
1461 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1465 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1469 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1475 dns_packet_rewind(p
, pos
);
1476 rr
->unparseable
= true;
1482 r
= dns_packet_read_uint16(p
, &rr
->ds
.key_tag
, NULL
);
1486 r
= dns_packet_read_uint8(p
, &rr
->ds
.algorithm
, NULL
);
1490 r
= dns_packet_read_uint8(p
, &rr
->ds
.digest_type
, NULL
);
1494 r
= dns_packet_read_public_key(p
, rdlength
- 4,
1495 &rr
->ds
.digest
, &rr
->ds
.digest_size
,
1501 case DNS_TYPE_SSHFP
:
1502 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1506 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1510 r
= dns_packet_read_public_key(p
, rdlength
- 2,
1511 &rr
->sshfp
.key
, &rr
->sshfp
.key_size
,
1515 case DNS_TYPE_DNSKEY
: {
1519 r
= dns_packet_read_uint16(p
, &flags
, NULL
);
1523 r
= dnskey_parse_flags(rr
, flags
);
1527 r
= dns_packet_read_uint8(p
, &proto
, NULL
);
1531 /* protocol is required to be always 3 */
1537 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.algorithm
, NULL
);
1541 r
= dns_packet_read_public_key(p
, rdlength
- 4,
1542 &rr
->dnskey
.key
, &rr
->dnskey
.key_size
,
1547 case DNS_TYPE_RRSIG
:
1548 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.type_covered
, NULL
);
1552 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.algorithm
, NULL
);
1556 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.labels
, NULL
);
1560 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.original_ttl
, NULL
);
1564 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.expiration
, NULL
);
1568 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.inception
, NULL
);
1572 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.key_tag
, NULL
);
1576 r
= dns_packet_read_name(p
, &rr
->rrsig
.signer
, false, NULL
);
1580 r
= dns_packet_read_public_key(p
, offset
+ rdlength
- p
->rindex
,
1581 &rr
->rrsig
.signature
, &rr
->rrsig
.signature_size
,
1586 r
= dns_packet_read_name(p
, &rr
->nsec
.next_domain_name
, false, NULL
);
1590 while (p
->rindex
!= offset
+ rdlength
) {
1591 r
= dns_packet_read_type_window(p
, &rr
->nsec
.types
, NULL
);
1598 case DNS_TYPE_NSEC3
: {
1601 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.algorithm
, NULL
);
1605 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.flags
, NULL
);
1609 r
= dns_packet_read_uint16(p
, &rr
->nsec3
.iterations
, NULL
);
1613 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1617 rr
->nsec3
.salt_size
= size
;
1619 r
= dns_packet_read_blob(p
, &d
, rr
->nsec3
.salt_size
, NULL
);
1623 rr
->nsec3
.salt
= memdup(d
, rr
->nsec3
.salt_size
);
1624 if (!rr
->nsec3
.salt
) {
1629 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1633 rr
->nsec3
.next_hashed_name_size
= size
;
1635 r
= dns_packet_read(p
, rr
->nsec3
.next_hashed_name_size
, &d
, NULL
);
1639 rr
->nsec3
.next_hashed_name
= memdup(d
, rr
->nsec3
.next_hashed_name_size
);
1640 if (!rr
->nsec3
.next_hashed_name
) {
1645 r
= dns_packet_append_types(p
, rr
->nsec3
.types
, NULL
);
1653 r
= dns_packet_read(p
, rdlength
, &d
, NULL
);
1657 rr
->generic
.data
= memdup(d
, rdlength
);
1658 if (!rr
->generic
.data
) {
1663 rr
->generic
.size
= rdlength
;
1668 if (p
->rindex
!= offset
+ rdlength
) {
1677 *start
= saved_rindex
;
1681 dns_packet_rewind(p
, saved_rindex
);
1685 int dns_packet_extract(DnsPacket
*p
) {
1686 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1687 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1688 size_t saved_rindex
;
1695 saved_rindex
= p
->rindex
;
1696 dns_packet_rewind(p
, DNS_PACKET_HEADER_SIZE
);
1698 n
= DNS_PACKET_QDCOUNT(p
);
1700 question
= dns_question_new(n
);
1706 for (i
= 0; i
< n
; i
++) {
1707 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1709 r
= dns_packet_read_key(p
, &key
, NULL
);
1713 r
= dns_question_add(question
, key
);
1719 n
= DNS_PACKET_RRCOUNT(p
);
1721 answer
= dns_answer_new(n
);
1727 for (i
= 0; i
< n
; i
++) {
1728 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1730 r
= dns_packet_read_rr(p
, &rr
, NULL
);
1734 r
= dns_answer_add(answer
, rr
);
1740 p
->question
= question
;
1746 p
->extracted
= true;
1751 p
->rindex
= saved_rindex
;
1755 static const char* const dns_rcode_table
[_DNS_RCODE_MAX_DEFINED
] = {
1756 [DNS_RCODE_SUCCESS
] = "SUCCESS",
1757 [DNS_RCODE_FORMERR
] = "FORMERR",
1758 [DNS_RCODE_SERVFAIL
] = "SERVFAIL",
1759 [DNS_RCODE_NXDOMAIN
] = "NXDOMAIN",
1760 [DNS_RCODE_NOTIMP
] = "NOTIMP",
1761 [DNS_RCODE_REFUSED
] = "REFUSED",
1762 [DNS_RCODE_YXDOMAIN
] = "YXDOMAIN",
1763 [DNS_RCODE_YXRRSET
] = "YRRSET",
1764 [DNS_RCODE_NXRRSET
] = "NXRRSET",
1765 [DNS_RCODE_NOTAUTH
] = "NOTAUTH",
1766 [DNS_RCODE_NOTZONE
] = "NOTZONE",
1767 [DNS_RCODE_BADVERS
] = "BADVERS",
1768 [DNS_RCODE_BADKEY
] = "BADKEY",
1769 [DNS_RCODE_BADTIME
] = "BADTIME",
1770 [DNS_RCODE_BADMODE
] = "BADMODE",
1771 [DNS_RCODE_BADNAME
] = "BADNAME",
1772 [DNS_RCODE_BADALG
] = "BADALG",
1773 [DNS_RCODE_BADTRUNC
] = "BADTRUNC",
1775 DEFINE_STRING_TABLE_LOOKUP(dns_rcode
, int);
1777 static const char* const dns_protocol_table
[_DNS_PROTOCOL_MAX
] = {
1778 [DNS_PROTOCOL_DNS
] = "dns",
1779 [DNS_PROTOCOL_MDNS
] = "mdns",
1780 [DNS_PROTOCOL_LLMNR
] = "llmnr",
1782 DEFINE_STRING_TABLE_LOOKUP(dns_protocol
, DnsProtocol
);
1784 static const char* const dnssec_algorithm_table
[_DNSSEC_ALGORITHM_MAX_DEFINED
] = {
1785 [DNSSEC_ALGORITHM_RSAMD5
] = "RSAMD5",
1786 [DNSSEC_ALGORITHM_DH
] = "DH",
1787 [DNSSEC_ALGORITHM_DSA
] = "DSA",
1788 [DNSSEC_ALGORITHM_ECC
] = "ECC",
1789 [DNSSEC_ALGORITHM_RSASHA1
] = "RSASHA1",
1790 [DNSSEC_ALGORITHM_DSA_NSEC3_SHA1
] = "DSA-NSEC3-SHA1",
1791 [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1
] = "RSASHA1-NSEC3-SHA1",
1792 [DNSSEC_ALGORITHM_INDIRECT
] = "INDIRECT",
1793 [DNSSEC_ALGORITHM_PRIVATEDNS
] = "PRIVATEDNS",
1794 [DNSSEC_ALGORITHM_PRIVATEOID
] = "PRIVATEOID",
1796 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm
, int);