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 int dns_packet_append_rr(DnsPacket
*p
, const DnsResourceRecord
*rr
, size_t *start
) {
506 size_t saved_size
, rdlength_offset
, end
, rdlength
;
512 saved_size
= p
->size
;
514 r
= dns_packet_append_key(p
, rr
->key
, NULL
);
518 r
= dns_packet_append_uint32(p
, rr
->ttl
, NULL
);
522 /* Initially we write 0 here */
523 r
= dns_packet_append_uint16(p
, 0, &rdlength_offset
);
527 switch (rr
->unparseable
? _DNS_TYPE_INVALID
: rr
->key
->type
) {
530 r
= dns_packet_append_uint16(p
, rr
->srv
.priority
, NULL
);
534 r
= dns_packet_append_uint16(p
, rr
->srv
.weight
, NULL
);
538 r
= dns_packet_append_uint16(p
, rr
->srv
.port
, NULL
);
542 r
= dns_packet_append_name(p
, rr
->srv
.name
, true, NULL
);
549 r
= dns_packet_append_name(p
, rr
->ptr
.name
, true, NULL
);
553 r
= dns_packet_append_string(p
, rr
->hinfo
.cpu
, NULL
);
557 r
= dns_packet_append_string(p
, rr
->hinfo
.os
, NULL
);
560 case DNS_TYPE_SPF
: /* exactly the same as TXT */
564 if (strv_isempty(rr
->txt
.strings
)) {
565 /* RFC 6763, section 6.1 suggests to generate
566 * single empty string for an empty array. */
568 r
= dns_packet_append_string(p
, "", NULL
);
572 STRV_FOREACH(s
, rr
->txt
.strings
) {
573 r
= dns_packet_append_string(p
, *s
, NULL
);
584 r
= dns_packet_append_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
588 r
= dns_packet_append_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
592 r
= dns_packet_append_name(p
, rr
->soa
.mname
, true, NULL
);
596 r
= dns_packet_append_name(p
, rr
->soa
.rname
, true, NULL
);
600 r
= dns_packet_append_uint32(p
, rr
->soa
.serial
, NULL
);
604 r
= dns_packet_append_uint32(p
, rr
->soa
.refresh
, NULL
);
608 r
= dns_packet_append_uint32(p
, rr
->soa
.retry
, NULL
);
612 r
= dns_packet_append_uint32(p
, rr
->soa
.expire
, NULL
);
616 r
= dns_packet_append_uint32(p
, rr
->soa
.minimum
, NULL
);
620 r
= dns_packet_append_uint16(p
, rr
->mx
.priority
, NULL
);
624 r
= dns_packet_append_name(p
, rr
->mx
.exchange
, true, NULL
);
628 r
= dns_packet_append_uint8(p
, rr
->loc
.version
, NULL
);
632 r
= dns_packet_append_uint8(p
, rr
->loc
.size
, NULL
);
636 r
= dns_packet_append_uint8(p
, rr
->loc
.horiz_pre
, NULL
);
640 r
= dns_packet_append_uint8(p
, rr
->loc
.vert_pre
, NULL
);
644 r
= dns_packet_append_uint32(p
, rr
->loc
.latitude
, NULL
);
648 r
= dns_packet_append_uint32(p
, rr
->loc
.longitude
, NULL
);
652 r
= dns_packet_append_uint32(p
, rr
->loc
.altitude
, NULL
);
656 r
= dns_packet_append_uint16(p
, rr
->ds
.key_tag
, NULL
);
660 r
= dns_packet_append_uint8(p
, rr
->ds
.algorithm
, NULL
);
664 r
= dns_packet_append_uint8(p
, rr
->ds
.digest_type
, NULL
);
668 r
= dns_packet_append_blob(p
, rr
->ds
.digest
, rr
->ds
.digest_size
, NULL
);
672 r
= dns_packet_append_uint8(p
, rr
->sshfp
.algorithm
, NULL
);
676 r
= dns_packet_append_uint8(p
, rr
->sshfp
.fptype
, NULL
);
680 r
= dns_packet_append_blob(p
, rr
->sshfp
.key
, rr
->sshfp
.key_size
, NULL
);
683 case DNS_TYPE_DNSKEY
:
684 r
= dns_packet_append_uint16(p
, dnskey_to_flags(rr
), NULL
);
688 r
= dns_packet_append_uint8(p
, 3u, NULL
);
692 r
= dns_packet_append_uint8(p
, rr
->dnskey
.algorithm
, NULL
);
696 r
= dns_packet_append_blob(p
, rr
->dnskey
.key
, rr
->dnskey
.key_size
, NULL
);
700 r
= dns_packet_append_uint16(p
, rr
->rrsig
.type_covered
, NULL
);
704 r
= dns_packet_append_uint8(p
, rr
->rrsig
.algorithm
, NULL
);
708 r
= dns_packet_append_uint8(p
, rr
->rrsig
.labels
, NULL
);
712 r
= dns_packet_append_uint32(p
, rr
->rrsig
.original_ttl
, NULL
);
716 r
= dns_packet_append_uint32(p
, rr
->rrsig
.expiration
, NULL
);
720 r
= dns_packet_append_uint32(p
, rr
->rrsig
.inception
, NULL
);
724 r
= dns_packet_append_uint16(p
, rr
->rrsig
.key_tag
, NULL
);
728 r
= dns_packet_append_name(p
, rr
->rrsig
.signer
, false, NULL
);
732 r
= dns_packet_append_blob(p
, rr
->rrsig
.signature
, rr
->rrsig
.signature_size
, NULL
);
735 case _DNS_TYPE_INVALID
: /* unparseable */
738 r
= dns_packet_append_blob(p
, rr
->generic
.data
, rr
->generic
.size
, NULL
);
744 /* Let's calculate the actual data size and update the field */
745 rdlength
= p
->size
- rdlength_offset
- sizeof(uint16_t);
746 if (rdlength
> 0xFFFF) {
752 p
->size
= rdlength_offset
;
753 r
= dns_packet_append_uint16(p
, rdlength
, NULL
);
764 dns_packet_truncate(p
, saved_size
);
769 int dns_packet_read(DnsPacket
*p
, size_t sz
, const void **ret
, size_t *start
) {
772 if (p
->rindex
+ sz
> p
->size
)
776 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->rindex
;
785 void dns_packet_rewind(DnsPacket
*p
, size_t idx
) {
787 assert(idx
<= p
->size
);
788 assert(idx
>= DNS_PACKET_HEADER_SIZE
);
793 int dns_packet_read_blob(DnsPacket
*p
, void *d
, size_t sz
, size_t *start
) {
800 r
= dns_packet_read(p
, sz
, &q
, start
);
808 int dns_packet_read_uint8(DnsPacket
*p
, uint8_t *ret
, size_t *start
) {
814 r
= dns_packet_read(p
, sizeof(uint8_t), &d
, start
);
818 *ret
= ((uint8_t*) d
)[0];
822 int dns_packet_read_uint16(DnsPacket
*p
, uint16_t *ret
, size_t *start
) {
828 r
= dns_packet_read(p
, sizeof(uint16_t), &d
, start
);
832 *ret
= unaligned_read_be16(d
);
837 int dns_packet_read_uint32(DnsPacket
*p
, uint32_t *ret
, size_t *start
) {
843 r
= dns_packet_read(p
, sizeof(uint32_t), &d
, start
);
847 *ret
= unaligned_read_be32(d
);
852 int dns_packet_read_string(DnsPacket
*p
, char **ret
, size_t *start
) {
861 saved_rindex
= p
->rindex
;
863 r
= dns_packet_read_uint8(p
, &c
, NULL
);
867 r
= dns_packet_read(p
, c
, &d
, NULL
);
871 if (memchr(d
, 0, c
)) {
882 if (!utf8_is_valid(t
)) {
891 *start
= saved_rindex
;
896 dns_packet_rewind(p
, saved_rindex
);
900 int dns_packet_read_name(DnsPacket
*p
, char **_ret
,
901 bool allow_compression
, size_t *start
) {
902 size_t saved_rindex
, after_rindex
= 0, jump_barrier
;
903 _cleanup_free_
char *ret
= NULL
;
904 size_t n
= 0, allocated
= 0;
911 saved_rindex
= p
->rindex
;
912 jump_barrier
= p
->rindex
;
917 r
= dns_packet_read_uint8(p
, &c
, NULL
);
925 _cleanup_free_
char *t
= NULL
;
929 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
933 r
= dns_label_escape(label
, c
, &t
);
937 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ strlen(t
) + 1)) {
947 memcpy(ret
+ n
, t
, r
);
950 } else if (allow_compression
&& (c
& 0xc0) == 0xc0) {
954 r
= dns_packet_read_uint8(p
, &d
, NULL
);
958 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
959 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= jump_barrier
) {
964 if (after_rindex
== 0)
965 after_rindex
= p
->rindex
;
967 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
976 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1)) {
983 if (after_rindex
!= 0)
984 p
->rindex
= after_rindex
;
990 *start
= saved_rindex
;
995 dns_packet_rewind(p
, saved_rindex
);
999 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, size_t *start
) {
1000 _cleanup_free_
char *name
= NULL
;
1001 uint16_t class, type
;
1002 DnsResourceKey
*key
;
1003 size_t saved_rindex
;
1009 saved_rindex
= p
->rindex
;
1011 r
= dns_packet_read_name(p
, &name
, true, NULL
);
1015 r
= dns_packet_read_uint16(p
, &type
, NULL
);
1019 r
= dns_packet_read_uint16(p
, &class, NULL
);
1023 key
= dns_resource_key_new_consume(class, type
, name
);
1033 *start
= saved_rindex
;
1037 dns_packet_rewind(p
, saved_rindex
);
1041 static int dns_packet_read_public_key(DnsPacket
*p
, size_t length
,
1042 void **dp
, size_t *lengthp
,
1048 r
= dns_packet_read(p
, length
, &d
, NULL
);
1052 d2
= memdup(d
, length
);
1061 static bool loc_size_ok(uint8_t size
) {
1062 uint8_t m
= size
>> 4, e
= size
& 0xF;
1064 return m
<= 9 && e
<= 9 && (m
> 0 || e
== 0);
1067 static int dnskey_parse_flags(DnsResourceRecord
*rr
, uint16_t flags
) {
1070 if (flags
& ~(DNSKEY_FLAG_SEP
| DNSKEY_FLAG_ZONE_KEY
))
1073 rr
->dnskey
.zone_key_flag
= flags
& DNSKEY_FLAG_ZONE_KEY
;
1074 rr
->dnskey
.sep_flag
= flags
& DNSKEY_FLAG_SEP
;
1078 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, size_t *start
) {
1079 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1080 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1081 size_t saved_rindex
, offset
;
1089 saved_rindex
= p
->rindex
;
1091 r
= dns_packet_read_key(p
, &key
, NULL
);
1095 if (key
->class == DNS_CLASS_ANY
||
1096 key
->type
== DNS_TYPE_ANY
) {
1101 rr
= dns_resource_record_new(key
);
1107 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
1111 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
1115 if (p
->rindex
+ rdlength
> p
->size
) {
1122 switch (rr
->key
->type
) {
1125 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
1128 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
1131 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
1134 r
= dns_packet_read_name(p
, &rr
->srv
.name
, true, NULL
);
1139 case DNS_TYPE_CNAME
:
1140 case DNS_TYPE_DNAME
:
1141 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, true, NULL
);
1144 case DNS_TYPE_HINFO
:
1145 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1149 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1152 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1154 if (rdlength
<= 0) {
1155 /* RFC 6763, section 6.1 suggests to treat
1156 * empty TXT RRs as equivalent to a TXT record
1157 * with a single empty string. */
1159 r
= strv_extend(&rr
->txt
.strings
, "");
1163 while (p
->rindex
< offset
+ rdlength
) {
1166 r
= dns_packet_read_string(p
, &s
, NULL
);
1170 r
= strv_consume(&rr
->txt
.strings
, s
);
1180 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1184 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1188 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, true, NULL
);
1192 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, true, NULL
);
1196 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1200 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1204 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1208 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1212 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1216 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1220 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, true, NULL
);
1223 case DNS_TYPE_LOC
: {
1227 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1232 rr
->loc
.version
= t
;
1234 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1238 if (!loc_size_ok(rr
->loc
.size
)) {
1243 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1247 if (!loc_size_ok(rr
->loc
.horiz_pre
)) {
1252 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1256 if (!loc_size_ok(rr
->loc
.vert_pre
)) {
1261 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1265 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1269 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1275 dns_packet_rewind(p
, pos
);
1276 rr
->unparseable
= true;
1282 r
= dns_packet_read_uint16(p
, &rr
->ds
.key_tag
, NULL
);
1286 r
= dns_packet_read_uint8(p
, &rr
->ds
.algorithm
, NULL
);
1290 r
= dns_packet_read_uint8(p
, &rr
->ds
.digest_type
, NULL
);
1294 r
= dns_packet_read_public_key(p
, rdlength
- 4,
1295 &rr
->ds
.digest
, &rr
->ds
.digest_size
,
1301 case DNS_TYPE_SSHFP
:
1302 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1306 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1310 r
= dns_packet_read_public_key(p
, rdlength
- 2,
1311 &rr
->sshfp
.key
, &rr
->sshfp
.key_size
,
1315 case DNS_TYPE_DNSKEY
: {
1319 r
= dns_packet_read_uint16(p
, &flags
, NULL
);
1323 r
= dnskey_parse_flags(rr
, flags
);
1327 r
= dns_packet_read_uint8(p
, &proto
, NULL
);
1331 /* protocol is required to be always 3 */
1337 r
= dns_packet_read_uint8(p
, &rr
->dnskey
.algorithm
, NULL
);
1341 r
= dns_packet_read_public_key(p
, rdlength
- 4,
1342 &rr
->dnskey
.key
, &rr
->dnskey
.key_size
,
1347 case DNS_TYPE_RRSIG
:
1348 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.type_covered
, NULL
);
1352 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.algorithm
, NULL
);
1356 r
= dns_packet_read_uint8(p
, &rr
->rrsig
.labels
, NULL
);
1360 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.original_ttl
, NULL
);
1364 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.expiration
, NULL
);
1368 r
= dns_packet_read_uint32(p
, &rr
->rrsig
.inception
, NULL
);
1372 r
= dns_packet_read_uint16(p
, &rr
->rrsig
.key_tag
, NULL
);
1376 r
= dns_packet_read_name(p
, &rr
->rrsig
.signer
, false, NULL
);
1380 r
= dns_packet_read_public_key(p
, offset
+ rdlength
- p
->rindex
,
1381 &rr
->rrsig
.signature
, &rr
->rrsig
.signature_size
,
1387 r
= dns_packet_read(p
, rdlength
, &d
, NULL
);
1391 rr
->generic
.data
= memdup(d
, rdlength
);
1392 if (!rr
->generic
.data
) {
1397 rr
->generic
.size
= rdlength
;
1402 if (p
->rindex
!= offset
+ rdlength
) {
1411 *start
= saved_rindex
;
1415 dns_packet_rewind(p
, saved_rindex
);
1419 int dns_packet_extract(DnsPacket
*p
) {
1420 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1421 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1422 size_t saved_rindex
;
1429 saved_rindex
= p
->rindex
;
1430 dns_packet_rewind(p
, DNS_PACKET_HEADER_SIZE
);
1432 n
= DNS_PACKET_QDCOUNT(p
);
1434 question
= dns_question_new(n
);
1440 for (i
= 0; i
< n
; i
++) {
1441 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1443 r
= dns_packet_read_key(p
, &key
, NULL
);
1447 r
= dns_question_add(question
, key
);
1453 n
= DNS_PACKET_RRCOUNT(p
);
1455 answer
= dns_answer_new(n
);
1461 for (i
= 0; i
< n
; i
++) {
1462 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1464 r
= dns_packet_read_rr(p
, &rr
, NULL
);
1468 r
= dns_answer_add(answer
, rr
);
1474 p
->question
= question
;
1480 p
->extracted
= true;
1485 p
->rindex
= saved_rindex
;
1489 static const char* const dns_rcode_table
[_DNS_RCODE_MAX_DEFINED
] = {
1490 [DNS_RCODE_SUCCESS
] = "SUCCESS",
1491 [DNS_RCODE_FORMERR
] = "FORMERR",
1492 [DNS_RCODE_SERVFAIL
] = "SERVFAIL",
1493 [DNS_RCODE_NXDOMAIN
] = "NXDOMAIN",
1494 [DNS_RCODE_NOTIMP
] = "NOTIMP",
1495 [DNS_RCODE_REFUSED
] = "REFUSED",
1496 [DNS_RCODE_YXDOMAIN
] = "YXDOMAIN",
1497 [DNS_RCODE_YXRRSET
] = "YRRSET",
1498 [DNS_RCODE_NXRRSET
] = "NXRRSET",
1499 [DNS_RCODE_NOTAUTH
] = "NOTAUTH",
1500 [DNS_RCODE_NOTZONE
] = "NOTZONE",
1501 [DNS_RCODE_BADVERS
] = "BADVERS",
1502 [DNS_RCODE_BADKEY
] = "BADKEY",
1503 [DNS_RCODE_BADTIME
] = "BADTIME",
1504 [DNS_RCODE_BADMODE
] = "BADMODE",
1505 [DNS_RCODE_BADNAME
] = "BADNAME",
1506 [DNS_RCODE_BADALG
] = "BADALG",
1507 [DNS_RCODE_BADTRUNC
] = "BADTRUNC",
1509 DEFINE_STRING_TABLE_LOOKUP(dns_rcode
, int);
1511 static const char* const dns_protocol_table
[_DNS_PROTOCOL_MAX
] = {
1512 [DNS_PROTOCOL_DNS
] = "dns",
1513 [DNS_PROTOCOL_MDNS
] = "mdns",
1514 [DNS_PROTOCOL_LLMNR
] = "llmnr",
1516 DEFINE_STRING_TABLE_LOOKUP(dns_protocol
, DnsProtocol
);
1518 static const char* const dnssec_algorithm_table
[_DNSSEC_ALGORITHM_MAX_DEFINED
] = {
1519 [DNSSEC_ALGORITHM_RSAMD5
] = "RSAMD5",
1520 [DNSSEC_ALGORITHM_DH
] = "DH",
1521 [DNSSEC_ALGORITHM_DSA
] = "DSA",
1522 [DNSSEC_ALGORITHM_ECC
] = "ECC",
1523 [DNSSEC_ALGORITHM_RSASHA1
] = "RSASHA1",
1524 [DNSSEC_ALGORITHM_INDIRECT
] = "INDIRECT",
1525 [DNSSEC_ALGORITHM_PRIVATEDNS
] = "PRIVATEDNS",
1526 [DNSSEC_ALGORITHM_PRIVATEOID
] = "PRIVATEOID",
1528 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm
, int);