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
) {
512 saved_size
= p
->size
;
516 r
= dns_packet_append_uint8(p
, window
, NULL
);
520 r
= dns_packet_append_uint8(p
, length
, NULL
);
524 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
) {
542 uint8_t bitmaps
[32] = {};
550 saved_size
= p
->size
;
552 BITMAP_FOREACH(n
, types
, i
) {
557 if ((n
<< 8) != window
) {
558 r
= dns_packet_append_type_window(p
, window
, len
, bitmaps
, NULL
);
573 bitmaps
[entry
/ 8] |= 1 << (7 - (entry
% 8));
576 r
= dns_packet_append_type_window(p
, window
, len
, bitmaps
, NULL
);
585 dns_packet_truncate(p
, saved_size
);
589 int dns_packet_append_rr(DnsPacket
*p
, const DnsResourceRecord
*rr
, size_t *start
) {
590 size_t saved_size
, rdlength_offset
, end
, rdlength
;
596 saved_size
= p
->size
;
598 r
= dns_packet_append_key(p
, rr
->key
, NULL
);
602 r
= dns_packet_append_uint32(p
, rr
->ttl
, NULL
);
606 /* Initially we write 0 here */
607 r
= dns_packet_append_uint16(p
, 0, &rdlength_offset
);
611 switch (rr
->unparseable
? _DNS_TYPE_INVALID
: rr
->key
->type
) {
614 r
= dns_packet_append_uint16(p
, rr
->srv
.priority
, NULL
);
618 r
= dns_packet_append_uint16(p
, rr
->srv
.weight
, NULL
);
622 r
= dns_packet_append_uint16(p
, rr
->srv
.port
, NULL
);
626 r
= dns_packet_append_name(p
, rr
->srv
.name
, true, NULL
);
633 r
= dns_packet_append_name(p
, rr
->ptr
.name
, true, NULL
);
637 r
= dns_packet_append_string(p
, rr
->hinfo
.cpu
, NULL
);
641 r
= dns_packet_append_string(p
, rr
->hinfo
.os
, NULL
);
644 case DNS_TYPE_SPF
: /* exactly the same as TXT */
648 if (strv_isempty(rr
->txt
.strings
)) {
649 /* RFC 6763, section 6.1 suggests to generate
650 * single empty string for an empty array. */
652 r
= dns_packet_append_string(p
, "", NULL
);
656 STRV_FOREACH(s
, rr
->txt
.strings
) {
657 r
= dns_packet_append_string(p
, *s
, NULL
);
668 r
= dns_packet_append_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
672 r
= dns_packet_append_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
676 r
= dns_packet_append_name(p
, rr
->soa
.mname
, true, NULL
);
680 r
= dns_packet_append_name(p
, rr
->soa
.rname
, true, NULL
);
684 r
= dns_packet_append_uint32(p
, rr
->soa
.serial
, NULL
);
688 r
= dns_packet_append_uint32(p
, rr
->soa
.refresh
, NULL
);
692 r
= dns_packet_append_uint32(p
, rr
->soa
.retry
, NULL
);
696 r
= dns_packet_append_uint32(p
, rr
->soa
.expire
, NULL
);
700 r
= dns_packet_append_uint32(p
, rr
->soa
.minimum
, NULL
);
704 r
= dns_packet_append_uint16(p
, rr
->mx
.priority
, NULL
);
708 r
= dns_packet_append_name(p
, rr
->mx
.exchange
, true, NULL
);
712 r
= dns_packet_append_uint8(p
, rr
->loc
.version
, NULL
);
716 r
= dns_packet_append_uint8(p
, rr
->loc
.size
, NULL
);
720 r
= dns_packet_append_uint8(p
, rr
->loc
.horiz_pre
, NULL
);
724 r
= dns_packet_append_uint8(p
, rr
->loc
.vert_pre
, NULL
);
728 r
= dns_packet_append_uint32(p
, rr
->loc
.latitude
, NULL
);
732 r
= dns_packet_append_uint32(p
, rr
->loc
.longitude
, NULL
);
736 r
= dns_packet_append_uint32(p
, rr
->loc
.altitude
, NULL
);
740 r
= dns_packet_append_uint16(p
, rr
->ds
.key_tag
, NULL
);
744 r
= dns_packet_append_uint8(p
, rr
->ds
.algorithm
, NULL
);
748 r
= dns_packet_append_uint8(p
, rr
->ds
.digest_type
, NULL
);
752 r
= dns_packet_append_blob(p
, rr
->ds
.digest
, rr
->ds
.digest_size
, NULL
);
756 r
= dns_packet_append_uint8(p
, rr
->sshfp
.algorithm
, NULL
);
760 r
= dns_packet_append_uint8(p
, rr
->sshfp
.fptype
, NULL
);
764 r
= dns_packet_append_blob(p
, rr
->sshfp
.key
, rr
->sshfp
.key_size
, NULL
);
767 case DNS_TYPE_DNSKEY
:
768 r
= dns_packet_append_uint16(p
, dnskey_to_flags(rr
), NULL
);
772 r
= dns_packet_append_uint8(p
, 3u, NULL
);
776 r
= dns_packet_append_uint8(p
, rr
->dnskey
.algorithm
, NULL
);
780 r
= dns_packet_append_blob(p
, rr
->dnskey
.key
, rr
->dnskey
.key_size
, NULL
);
784 r
= dns_packet_append_uint16(p
, rr
->rrsig
.type_covered
, NULL
);
788 r
= dns_packet_append_uint8(p
, rr
->rrsig
.algorithm
, NULL
);
792 r
= dns_packet_append_uint8(p
, rr
->rrsig
.labels
, NULL
);
796 r
= dns_packet_append_uint32(p
, rr
->rrsig
.original_ttl
, NULL
);
800 r
= dns_packet_append_uint32(p
, rr
->rrsig
.expiration
, NULL
);
804 r
= dns_packet_append_uint32(p
, rr
->rrsig
.inception
, NULL
);
808 r
= dns_packet_append_uint16(p
, rr
->rrsig
.key_tag
, NULL
);
812 r
= dns_packet_append_name(p
, rr
->rrsig
.signer
, false, NULL
);
816 r
= dns_packet_append_blob(p
, rr
->rrsig
.signature
, rr
->rrsig
.signature_size
, NULL
);
820 r
= dns_packet_append_name(p
, rr
->nsec
.next_domain_name
, false, NULL
);
824 r
= dns_packet_append_types(p
, rr
->nsec
.types
, NULL
);
830 r
= dns_packet_append_uint8(p
, rr
->nsec3
.algorithm
, NULL
);
834 r
= dns_packet_append_uint8(p
, rr
->nsec3
.flags
, NULL
);
838 r
= dns_packet_append_uint16(p
, rr
->nsec3
.iterations
, NULL
);
842 r
= dns_packet_append_uint8(p
, rr
->nsec3
.salt_size
, NULL
);
846 r
= dns_packet_append_blob(p
, rr
->nsec3
.salt
, rr
->nsec3
.salt_size
, NULL
);
850 r
= dns_packet_append_uint8(p
, rr
->nsec3
.next_hashed_name_size
, NULL
);
854 r
= dns_packet_append_blob(p
, rr
->nsec3
.next_hashed_name
, rr
->nsec3
.next_hashed_name_size
, NULL
);
858 r
= dns_packet_append_types(p
, rr
->nsec3
.types
, NULL
);
863 case _DNS_TYPE_INVALID
: /* unparseable */
866 r
= dns_packet_append_blob(p
, rr
->generic
.data
, rr
->generic
.size
, NULL
);
872 /* Let's calculate the actual data size and update the field */
873 rdlength
= p
->size
- rdlength_offset
- sizeof(uint16_t);
874 if (rdlength
> 0xFFFF) {
880 p
->size
= rdlength_offset
;
881 r
= dns_packet_append_uint16(p
, rdlength
, NULL
);
892 dns_packet_truncate(p
, saved_size
);
897 int dns_packet_read(DnsPacket
*p
, size_t sz
, const void **ret
, size_t *start
) {
900 if (p
->rindex
+ sz
> p
->size
)
904 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->rindex
;
913 void dns_packet_rewind(DnsPacket
*p
, size_t idx
) {
915 assert(idx
<= p
->size
);
916 assert(idx
>= DNS_PACKET_HEADER_SIZE
);
921 int dns_packet_read_blob(DnsPacket
*p
, void *d
, size_t sz
, size_t *start
) {
928 r
= dns_packet_read(p
, sz
, &q
, start
);
936 int dns_packet_read_uint8(DnsPacket
*p
, uint8_t *ret
, size_t *start
) {
942 r
= dns_packet_read(p
, sizeof(uint8_t), &d
, start
);
946 *ret
= ((uint8_t*) d
)[0];
950 int dns_packet_read_uint16(DnsPacket
*p
, uint16_t *ret
, size_t *start
) {
956 r
= dns_packet_read(p
, sizeof(uint16_t), &d
, start
);
960 *ret
= unaligned_read_be16(d
);
965 int dns_packet_read_uint32(DnsPacket
*p
, uint32_t *ret
, size_t *start
) {
971 r
= dns_packet_read(p
, sizeof(uint32_t), &d
, start
);
975 *ret
= unaligned_read_be32(d
);
980 int dns_packet_read_string(DnsPacket
*p
, char **ret
, size_t *start
) {
989 saved_rindex
= p
->rindex
;
991 r
= dns_packet_read_uint8(p
, &c
, NULL
);
995 r
= dns_packet_read(p
, c
, &d
, NULL
);
999 if (memchr(d
, 0, c
)) {
1010 if (!utf8_is_valid(t
)) {
1019 *start
= saved_rindex
;
1024 dns_packet_rewind(p
, saved_rindex
);
1028 int dns_packet_read_name(DnsPacket
*p
, char **_ret
,
1029 bool allow_compression
, size_t *start
) {
1030 size_t saved_rindex
, after_rindex
= 0, jump_barrier
;
1031 _cleanup_free_
char *ret
= NULL
;
1032 size_t n
= 0, allocated
= 0;
1039 saved_rindex
= p
->rindex
;
1040 jump_barrier
= p
->rindex
;
1045 r
= dns_packet_read_uint8(p
, &c
, NULL
);
1053 _cleanup_free_
char *t
= NULL
;
1057 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
1061 r
= dns_label_escape(label
, c
, &t
);
1065 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ strlen(t
) + 1)) {
1075 memcpy(ret
+ n
, t
, r
);
1078 } else if (allow_compression
&& (c
& 0xc0) == 0xc0) {
1082 r
= dns_packet_read_uint8(p
, &d
, NULL
);
1086 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
1087 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= jump_barrier
) {
1092 if (after_rindex
== 0)
1093 after_rindex
= p
->rindex
;
1095 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1104 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1)) {
1111 if (after_rindex
!= 0)
1112 p
->rindex
= after_rindex
;
1118 *start
= saved_rindex
;
1123 dns_packet_rewind(p
, saved_rindex
);
1127 static int dns_packet_read_type_window(DnsPacket
*p
, Bitmap
**types
, size_t *start
) {
1130 const uint8_t *bitmap
;
1133 size_t saved_rindex
;
1139 saved_rindex
= p
->rindex
;
1141 r
= bitmap_ensure_allocated(types
);
1145 r
= dns_packet_read_uint8(p
, &window
, NULL
);
1149 r
= dns_packet_read_uint8(p
, &length
, NULL
);
1153 if (length
== 0 || length
> 32)
1156 r
= dns_packet_read(p
, length
, (const void **)&bitmap
, NULL
);
1160 for (i
= 0; i
< length
; i
++) {
1161 uint8_t bitmask
= 1 << 7;
1172 if (bitmap
[i
] & bitmask
) {
1175 /* XXX: ignore pseudo-types? see RFC4034 section 4.1.2 */
1176 n
= (uint16_t) window
<< 8 | (uint16_t) bit
;
1178 r
= bitmap_set(*types
, n
);
1192 *start
= saved_rindex
;
1196 dns_packet_rewind(p
, saved_rindex
);
1200 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, size_t *start
) {
1201 _cleanup_free_
char *name
= NULL
;
1202 uint16_t class, type
;
1203 DnsResourceKey
*key
;
1204 size_t saved_rindex
;
1210 saved_rindex
= p
->rindex
;
1212 r
= dns_packet_read_name(p
, &name
, true, NULL
);
1216 r
= dns_packet_read_uint16(p
, &type
, NULL
);
1220 r
= dns_packet_read_uint16(p
, &class, NULL
);
1224 key
= dns_resource_key_new_consume(class, type
, name
);
1234 *start
= saved_rindex
;
1238 dns_packet_rewind(p
, saved_rindex
);
1242 static int dns_packet_read_public_key(DnsPacket
*p
, size_t length
,
1243 void **dp
, size_t *lengthp
,
1249 r
= dns_packet_read(p
, length
, &d
, NULL
);
1253 d2
= memdup(d
, length
);
1262 static bool loc_size_ok(uint8_t size
) {
1263 uint8_t m
= size
>> 4, e
= size
& 0xF;
1265 return m
<= 9 && e
<= 9 && (m
> 0 || e
== 0);
1268 static int dnskey_parse_flags(DnsResourceRecord
*rr
, uint16_t flags
) {
1271 if (flags
& ~(DNSKEY_FLAG_SEP
| DNSKEY_FLAG_ZONE_KEY
))
1274 rr
->dnskey
.zone_key_flag
= flags
& DNSKEY_FLAG_ZONE_KEY
;
1275 rr
->dnskey
.sep_flag
= flags
& DNSKEY_FLAG_SEP
;
1279 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, size_t *start
) {
1280 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1281 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1282 size_t saved_rindex
, offset
;
1290 saved_rindex
= p
->rindex
;
1292 r
= dns_packet_read_key(p
, &key
, NULL
);
1296 if (key
->class == DNS_CLASS_ANY
||
1297 key
->type
== DNS_TYPE_ANY
) {
1302 rr
= dns_resource_record_new(key
);
1308 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
1312 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
1316 if (p
->rindex
+ rdlength
> p
->size
) {
1323 switch (rr
->key
->type
) {
1326 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
1329 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
1332 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
1335 r
= dns_packet_read_name(p
, &rr
->srv
.name
, true, NULL
);
1340 case DNS_TYPE_CNAME
:
1341 case DNS_TYPE_DNAME
:
1342 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, true, NULL
);
1345 case DNS_TYPE_HINFO
:
1346 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1350 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1353 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1355 if (rdlength
<= 0) {
1356 /* RFC 6763, section 6.1 suggests to treat
1357 * empty TXT RRs as equivalent to a TXT record
1358 * with a single empty string. */
1360 r
= strv_extend(&rr
->txt
.strings
, "");
1364 while (p
->rindex
< offset
+ rdlength
) {
1367 r
= dns_packet_read_string(p
, &s
, NULL
);
1371 r
= strv_consume(&rr
->txt
.strings
, s
);
1381 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1385 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1389 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, true, NULL
);
1393 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, true, NULL
);
1397 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1401 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1405 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1409 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1413 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1417 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1421 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, true, NULL
);
1424 case DNS_TYPE_LOC
: {
1428 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1433 rr
->loc
.version
= t
;
1435 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1439 if (!loc_size_ok(rr
->loc
.size
)) {
1444 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1448 if (!loc_size_ok(rr
->loc
.horiz_pre
)) {
1453 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1457 if (!loc_size_ok(rr
->loc
.vert_pre
)) {
1462 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1466 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1470 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1476 dns_packet_rewind(p
, pos
);
1477 rr
->unparseable
= true;
1483 r
= dns_packet_read_uint16(p
, &rr
->ds
.key_tag
, NULL
);
1487 r
= dns_packet_read_uint8(p
, &rr
->ds
.algorithm
, NULL
);
1491 r
= dns_packet_read_uint8(p
, &rr
->ds
.digest_type
, NULL
);
1495 r
= dns_packet_read_public_key(p
, rdlength
- 4,
1496 &rr
->ds
.digest
, &rr
->ds
.digest_size
,
1502 case DNS_TYPE_SSHFP
:
1503 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1507 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1511 r
= dns_packet_read_public_key(p
, rdlength
- 2,
1512 &rr
->sshfp
.key
, &rr
->sshfp
.key_size
,
1516 case DNS_TYPE_DNSKEY
: {
1520 r
= dns_packet_read_uint16(p
, &flags
, NULL
);
1524 r
= dnskey_parse_flags(rr
, flags
);
1528 r
= dns_packet_read_uint8(p
, &proto
, NULL
);
1532 /* protocol is required to be always 3 */
1538 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.algorithm
, NULL
);
1542 r
= dns_packet_read_public_key(p
, rdlength
- 4,
1543 &rr
->dnskey
.key
, &rr
->dnskey
.key_size
,
1548 case DNS_TYPE_RRSIG
:
1549 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.type_covered
, NULL
);
1553 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.algorithm
, NULL
);
1557 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.labels
, NULL
);
1561 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.original_ttl
, NULL
);
1565 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.expiration
, NULL
);
1569 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.inception
, NULL
);
1573 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.key_tag
, NULL
);
1577 r
= dns_packet_read_name(p
, &rr
->rrsig
.signer
, false, NULL
);
1581 r
= dns_packet_read_public_key(p
, offset
+ rdlength
- p
->rindex
,
1582 &rr
->rrsig
.signature
, &rr
->rrsig
.signature_size
,
1587 r
= dns_packet_read_name(p
, &rr
->nsec
.next_domain_name
, false, NULL
);
1591 while (p
->rindex
!= offset
+ rdlength
) {
1592 r
= dns_packet_read_type_window(p
, &rr
->nsec
.types
, NULL
);
1599 case DNS_TYPE_NSEC3
: {
1602 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.algorithm
, NULL
);
1606 r
= dns_packet_read_uint8(p
, &rr
->nsec3
.flags
, NULL
);
1610 r
= dns_packet_read_uint16(p
, &rr
->nsec3
.iterations
, NULL
);
1614 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1618 rr
->nsec3
.salt_size
= size
;
1620 r
= dns_packet_read_blob(p
, &d
, rr
->nsec3
.salt_size
, NULL
);
1624 rr
->nsec3
.salt
= memdup(d
, rr
->nsec3
.salt_size
);
1625 if (!rr
->nsec3
.salt
) {
1630 r
= dns_packet_read_uint8(p
, &size
, NULL
);
1634 rr
->nsec3
.next_hashed_name_size
= size
;
1636 r
= dns_packet_read(p
, rr
->nsec3
.next_hashed_name_size
, &d
, NULL
);
1640 rr
->nsec3
.next_hashed_name
= memdup(d
, rr
->nsec3
.next_hashed_name_size
);
1641 if (!rr
->nsec3
.next_hashed_name
) {
1646 r
= dns_packet_append_types(p
, rr
->nsec3
.types
, NULL
);
1654 r
= dns_packet_read(p
, rdlength
, &d
, NULL
);
1658 rr
->generic
.data
= memdup(d
, rdlength
);
1659 if (!rr
->generic
.data
) {
1664 rr
->generic
.size
= rdlength
;
1669 if (p
->rindex
!= offset
+ rdlength
) {
1678 *start
= saved_rindex
;
1682 dns_packet_rewind(p
, saved_rindex
);
1686 int dns_packet_extract(DnsPacket
*p
) {
1687 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1688 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1689 size_t saved_rindex
;
1696 saved_rindex
= p
->rindex
;
1697 dns_packet_rewind(p
, DNS_PACKET_HEADER_SIZE
);
1699 n
= DNS_PACKET_QDCOUNT(p
);
1701 question
= dns_question_new(n
);
1707 for (i
= 0; i
< n
; i
++) {
1708 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1710 r
= dns_packet_read_key(p
, &key
, NULL
);
1714 r
= dns_question_add(question
, key
);
1720 n
= DNS_PACKET_RRCOUNT(p
);
1722 answer
= dns_answer_new(n
);
1728 for (i
= 0; i
< n
; i
++) {
1729 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1731 r
= dns_packet_read_rr(p
, &rr
, NULL
);
1735 r
= dns_answer_add(answer
, rr
);
1741 p
->question
= question
;
1747 p
->extracted
= true;
1752 p
->rindex
= saved_rindex
;
1756 static const char* const dns_rcode_table
[_DNS_RCODE_MAX_DEFINED
] = {
1757 [DNS_RCODE_SUCCESS
] = "SUCCESS",
1758 [DNS_RCODE_FORMERR
] = "FORMERR",
1759 [DNS_RCODE_SERVFAIL
] = "SERVFAIL",
1760 [DNS_RCODE_NXDOMAIN
] = "NXDOMAIN",
1761 [DNS_RCODE_NOTIMP
] = "NOTIMP",
1762 [DNS_RCODE_REFUSED
] = "REFUSED",
1763 [DNS_RCODE_YXDOMAIN
] = "YXDOMAIN",
1764 [DNS_RCODE_YXRRSET
] = "YRRSET",
1765 [DNS_RCODE_NXRRSET
] = "NXRRSET",
1766 [DNS_RCODE_NOTAUTH
] = "NOTAUTH",
1767 [DNS_RCODE_NOTZONE
] = "NOTZONE",
1768 [DNS_RCODE_BADVERS
] = "BADVERS",
1769 [DNS_RCODE_BADKEY
] = "BADKEY",
1770 [DNS_RCODE_BADTIME
] = "BADTIME",
1771 [DNS_RCODE_BADMODE
] = "BADMODE",
1772 [DNS_RCODE_BADNAME
] = "BADNAME",
1773 [DNS_RCODE_BADALG
] = "BADALG",
1774 [DNS_RCODE_BADTRUNC
] = "BADTRUNC",
1776 DEFINE_STRING_TABLE_LOOKUP(dns_rcode
, int);
1778 static const char* const dns_protocol_table
[_DNS_PROTOCOL_MAX
] = {
1779 [DNS_PROTOCOL_DNS
] = "dns",
1780 [DNS_PROTOCOL_MDNS
] = "mdns",
1781 [DNS_PROTOCOL_LLMNR
] = "llmnr",
1783 DEFINE_STRING_TABLE_LOOKUP(dns_protocol
, DnsProtocol
);
1785 static const char* const dnssec_algorithm_table
[_DNSSEC_ALGORITHM_MAX_DEFINED
] = {
1786 [DNSSEC_ALGORITHM_RSAMD5
] = "RSAMD5",
1787 [DNSSEC_ALGORITHM_DH
] = "DH",
1788 [DNSSEC_ALGORITHM_DSA
] = "DSA",
1789 [DNSSEC_ALGORITHM_ECC
] = "ECC",
1790 [DNSSEC_ALGORITHM_RSASHA1
] = "RSASHA1",
1791 [DNSSEC_ALGORITHM_DSA_NSEC3_SHA1
] = "DSA-NSEC3-SHA1",
1792 [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1
] = "RSASHA1-NSEC3-SHA1",
1793 [DNSSEC_ALGORITHM_INDIRECT
] = "INDIRECT",
1794 [DNSSEC_ALGORITHM_PRIVATEDNS
] = "PRIVATEDNS",
1795 [DNSSEC_ALGORITHM_PRIVATEOID
] = "PRIVATEOID",
1797 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm
, int);