1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <netinet/ip.h>
5 #include <netinet/ip6.h>
6 #include <netinet/udp.h>
9 #include "in-addr-util.h"
11 #include "sparse-endian.h"
13 typedef struct DnsPacketHeader DnsPacketHeader
;
14 typedef struct DnsPacket DnsPacket
;
16 #include "resolved-def.h"
17 #include "resolved-dns-answer.h"
18 #include "resolved-dns-question.h"
19 #include "resolved-dns-rr.h"
21 typedef enum DnsProtocol
{
26 _DNS_PROTOCOL_INVALID
= -EINVAL
,
29 struct DnsPacketHeader
{
38 #define DNS_PACKET_HEADER_SIZE sizeof(DnsPacketHeader)
39 #define UDP4_PACKET_HEADER_SIZE (sizeof(struct iphdr) + sizeof(struct udphdr))
40 #define UDP6_PACKET_HEADER_SIZE (sizeof(struct ip6_hdr) + sizeof(struct udphdr))
42 assert_cc(sizeof(struct ip6_hdr
) == 40);
43 assert_cc(sizeof(struct iphdr
) == 20);
44 assert_cc(sizeof(struct udphdr
) == 8);
45 assert_cc(sizeof(DnsPacketHeader
) == 12);
47 /* The various DNS protocols deviate in how large a packet can grow, but the TCP transport has a 16-bit size
48 * field, hence that appears to be the absolute maximum. */
49 #define DNS_PACKET_SIZE_MAX 0xFFFFu
51 /* The default size to use for allocation when we don't know how large
52 * the packet will turn out to be. */
53 #define DNS_PACKET_SIZE_START 512u
55 /* RFC 1035 say 512 is the maximum, for classic unicast DNS */
56 #define DNS_PACKET_UNICAST_SIZE_MAX 512u
58 /* With EDNS0 we can use larger packets, default to 1232, which is what is commonly used */
59 #define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 1232u
64 size_t size
, allocated
, rindex
, max_size
, fragsize
;
65 void *_data
; /* don't access directly, use DNS_PACKET_DATA()! */
66 Hashmap
*names
; /* For name compression */
67 size_t opt_start
, opt_size
;
70 DnsQuestion
*question
;
72 DnsResourceRecord
*opt
;
74 /* For support of truncated packets */
77 /* Packet reception metadata */
78 usec_t timestamp
; /* CLOCK_BOOTTIME (or CLOCK_MONOTONIC if the former doesn't exist) */
81 union in_addr_union sender
, destination
;
82 uint16_t sender_port
, destination_port
;
87 bool refuse_compression
;
90 /* Note: fields should be ordered to minimize alignment gaps. Use pahole! */
93 static inline uint8_t* DNS_PACKET_DATA(const DnsPacket
*p
) {
100 return ((uint8_t*) p
) + ALIGN(sizeof(DnsPacket
));
103 #define DNS_PACKET_HEADER(p) ((DnsPacketHeader*) DNS_PACKET_DATA(p))
104 #define DNS_PACKET_ID(p) DNS_PACKET_HEADER(p)->id
105 #define DNS_PACKET_QR(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 15) & 1)
106 #define DNS_PACKET_OPCODE(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 11) & 15)
107 #define DNS_PACKET_AA(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 10) & 1)
108 #define DNS_PACKET_TC(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 9) & 1)
109 #define DNS_PACKET_RD(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 8) & 1)
110 #define DNS_PACKET_RA(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 7) & 1)
111 #define DNS_PACKET_AD(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 5) & 1)
112 #define DNS_PACKET_CD(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 4) & 1)
114 #define DNS_PACKET_FLAG_TC (UINT16_C(1) << 9)
116 static inline uint16_t DNS_PACKET_RCODE(DnsPacket
*p
) {
120 rcode
= (uint16_t) (p
->opt
->ttl
>> 24);
124 return rcode
| (be16toh(DNS_PACKET_HEADER(p
)->flags
) & 0xF);
127 static inline uint16_t DNS_PACKET_PAYLOAD_SIZE_MAX(DnsPacket
*p
) {
129 /* Returns the advertised maximum size for replies, or the DNS default if there's nothing defined. */
131 if (p
->ipproto
== IPPROTO_TCP
) /* we ignore EDNS(0) size data on TCP, like everybody else */
132 return DNS_PACKET_SIZE_MAX
;
135 return MAX(DNS_PACKET_UNICAST_SIZE_MAX
, p
->opt
->key
->class);
137 return DNS_PACKET_UNICAST_SIZE_MAX
;
140 static inline bool DNS_PACKET_DO(DnsPacket
*p
) {
144 return !!(p
->opt
->ttl
& (1U << 15));
147 static inline bool DNS_PACKET_VERSION_SUPPORTED(DnsPacket
*p
) {
148 /* Returns true if this packet is in a version we support. Which means either non-EDNS or EDNS(0), but not EDNS
149 * of any newer versions */
154 return DNS_RESOURCE_RECORD_OPT_VERSION_SUPPORTED(p
->opt
);
157 static inline bool DNS_PACKET_IS_FRAGMENTED(DnsPacket
*p
) {
160 /* For ingress packets: was this packet fragmented according to our knowledge? */
162 return p
->fragsize
!= 0;
165 /* LLMNR defines some bits differently */
166 #define DNS_PACKET_LLMNR_C(p) DNS_PACKET_AA(p)
167 #define DNS_PACKET_LLMNR_T(p) DNS_PACKET_RD(p)
169 #define DNS_PACKET_QDCOUNT(p) be16toh(DNS_PACKET_HEADER(p)->qdcount)
170 #define DNS_PACKET_ANCOUNT(p) be16toh(DNS_PACKET_HEADER(p)->ancount)
171 #define DNS_PACKET_NSCOUNT(p) be16toh(DNS_PACKET_HEADER(p)->nscount)
172 #define DNS_PACKET_ARCOUNT(p) be16toh(DNS_PACKET_HEADER(p)->arcount)
174 #define DNS_PACKET_MAKE_FLAGS(qr, opcode, aa, tc, rd, ra, ad, cd, rcode) \
175 (((uint16_t) !!(qr) << 15) | \
176 ((uint16_t) ((opcode) & 15) << 11) | \
177 ((uint16_t) !!(aa) << 10) | /* on LLMNR: c */ \
178 ((uint16_t) !!(tc) << 9) | \
179 ((uint16_t) !!(rd) << 8) | /* on LLMNR: t */ \
180 ((uint16_t) !!(ra) << 7) | \
181 ((uint16_t) !!(ad) << 5) | \
182 ((uint16_t) !!(cd) << 4) | \
183 ((uint16_t) ((rcode) & 15)))
185 static inline unsigned DNS_PACKET_RRCOUNT(DnsPacket
*p
) {
187 (unsigned) DNS_PACKET_ANCOUNT(p
) +
188 (unsigned) DNS_PACKET_NSCOUNT(p
) +
189 (unsigned) DNS_PACKET_ARCOUNT(p
);
192 int dns_packet_new(DnsPacket
**p
, DnsProtocol protocol
, size_t min_alloc_dsize
, size_t max_size
);
193 int dns_packet_new_query(DnsPacket
**p
, DnsProtocol protocol
, size_t min_alloc_dsize
, bool dnssec_checking_disabled
);
195 int dns_packet_dup(DnsPacket
**ret
, DnsPacket
*p
);
197 void dns_packet_set_flags(DnsPacket
*p
, bool dnssec_checking_disabled
, bool truncated
);
199 DnsPacket
*dns_packet_ref(DnsPacket
*p
);
200 DnsPacket
*dns_packet_unref(DnsPacket
*p
);
202 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsPacket
*, dns_packet_unref
);
204 #define DNS_PACKET_REPLACE(a, b) \
206 typeof(a)* _a = &(a); \
207 typeof(b) _b = (b); \
208 dns_packet_unref(*_a); \
212 int dns_packet_validate(DnsPacket
*p
);
213 int dns_packet_validate_reply(DnsPacket
*p
);
214 int dns_packet_validate_query(DnsPacket
*p
);
216 int dns_packet_is_reply_for(DnsPacket
*p
, const DnsResourceKey
*key
);
218 int dns_packet_append_blob(DnsPacket
*p
, const void *d
, size_t sz
, size_t *start
);
219 int dns_packet_append_uint8(DnsPacket
*p
, uint8_t v
, size_t *start
);
220 int dns_packet_append_uint16(DnsPacket
*p
, uint16_t v
, size_t *start
);
221 int dns_packet_append_uint32(DnsPacket
*p
, uint32_t v
, size_t *start
);
222 int dns_packet_append_string(DnsPacket
*p
, const char *s
, size_t *start
);
223 int dns_packet_append_raw_string(DnsPacket
*p
, const void *s
, size_t size
, size_t *start
);
224 int dns_packet_append_label(DnsPacket
*p
, const char *s
, size_t l
, bool canonical_candidate
, size_t *start
);
225 int dns_packet_append_name(DnsPacket
*p
, const char *name
, bool allow_compression
, bool canonical_candidate
, size_t *start
);
226 int dns_packet_append_key(DnsPacket
*p
, const DnsResourceKey
*key
, const DnsAnswerFlags flags
, size_t *start
);
227 int dns_packet_append_rr(DnsPacket
*p
, const DnsResourceRecord
*rr
, const DnsAnswerFlags flags
, size_t *start
, size_t *rdata_start
);
228 int dns_packet_append_opt(DnsPacket
*p
, uint16_t max_udp_size
, bool edns0_do
, bool include_rfc6975
, const char *nsid
, int rcode
, size_t *ret_start
);
229 int dns_packet_append_question(DnsPacket
*p
, DnsQuestion
*q
);
230 int dns_packet_append_answer(DnsPacket
*p
, DnsAnswer
*a
, unsigned *completed
);
232 int dns_packet_patch_max_udp_size(DnsPacket
*p
, uint16_t max_udp_size
);
233 int dns_packet_patch_ttls(DnsPacket
*p
, usec_t timestamp
);
235 void dns_packet_truncate(DnsPacket
*p
, size_t sz
);
236 int dns_packet_truncate_opt(DnsPacket
*p
);
238 int dns_packet_read(DnsPacket
*p
, size_t sz
, const void **ret
, size_t *start
);
239 int dns_packet_read_blob(DnsPacket
*p
, void *d
, size_t sz
, size_t *start
);
240 int dns_packet_read_uint8(DnsPacket
*p
, uint8_t *ret
, size_t *start
);
241 int dns_packet_read_uint16(DnsPacket
*p
, uint16_t *ret
, size_t *start
);
242 int dns_packet_read_uint32(DnsPacket
*p
, uint32_t *ret
, size_t *start
);
243 int dns_packet_read_string(DnsPacket
*p
, char **ret
, size_t *start
);
244 int dns_packet_read_raw_string(DnsPacket
*p
, const void **ret
, size_t *size
, size_t *start
);
245 int dns_packet_read_name(DnsPacket
*p
, char **ret
, bool allow_compression
, size_t *start
);
246 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, bool *ret_cache_flush_or_qu
, size_t *start
);
247 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, bool *ret_cache_flush
, size_t *start
);
249 void dns_packet_rewind(DnsPacket
*p
, size_t idx
);
251 int dns_packet_skip_question(DnsPacket
*p
);
252 int dns_packet_extract(DnsPacket
*p
);
254 bool dns_packet_equal(const DnsPacket
*a
, const DnsPacket
*b
);
256 int dns_packet_ede_rcode(DnsPacket
*p
, int *ret_ede_rcode
, char **ret_ede_msg
);
257 bool dns_ede_rcode_is_dnssec(int ede_rcode
);
258 int dns_packet_has_nsid_request(DnsPacket
*p
);
260 /* https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6 */
262 DNS_RCODE_SUCCESS
= 0,
263 DNS_RCODE_FORMERR
= 1,
264 DNS_RCODE_SERVFAIL
= 2,
265 DNS_RCODE_NXDOMAIN
= 3,
266 DNS_RCODE_NOTIMP
= 4,
267 DNS_RCODE_REFUSED
= 5,
268 DNS_RCODE_YXDOMAIN
= 6,
269 DNS_RCODE_YXRRSET
= 7,
270 DNS_RCODE_NXRRSET
= 8,
271 DNS_RCODE_NOTAUTH
= 9,
272 DNS_RCODE_NOTZONE
= 10,
273 DNS_RCODE_DSOTYPENI
= 11,
274 /* 12-15 are unassigned. */
275 DNS_RCODE_BADVERS
= 16,
276 DNS_RCODE_BADSIG
= 16, /* duplicate value! */
277 DNS_RCODE_BADKEY
= 17,
278 DNS_RCODE_BADTIME
= 18,
279 DNS_RCODE_BADMODE
= 19,
280 DNS_RCODE_BADNAME
= 20,
281 DNS_RCODE_BADALG
= 21,
282 DNS_RCODE_BADTRUNC
= 22,
283 DNS_RCODE_BADCOOKIE
= 23,
284 /* 24-3840 are unassigned. */
285 /* 3841-4095 are for private use. */
286 /* 4096-65534 are unassigned. */
287 _DNS_RCODE_MAX_DEFINED
,
288 _DNS_RCODE_MAX
= 65535, /* reserved */
289 _DNS_RCODE_INVALID
= -EINVAL
,
292 /* https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-11 */
294 DNS_EDNS_OPT_RESERVED
= 0, /* RFC 6891 */
295 DNS_EDNS_OPT_LLQ
= 1, /* RFC 8764 */
297 DNS_EDNS_OPT_NSID
= 3, /* RFC 5001 */
298 /* DNS_EDNS_OPT_RESERVED = 4 */
299 DNS_EDNS_OPT_DAU
= 5, /* RFC 6975 */
300 DNS_EDNS_OPT_DHU
= 6, /* RFC 6975 */
301 DNS_EDNS_OPT_N3U
= 7, /* RFC 6975 */
302 DNS_EDNS_OPT_CLIENT_SUBNET
= 8, /* RFC 7871 */
303 DNS_EDNS_OPT_EXPIRE
= 9, /* RFC 7314 */
304 DNS_EDNS_OPT_COOKIE
= 10, /* RFC 7873 */
305 DNS_EDNS_OPT_TCP_KEEPALIVE
= 11, /* RFC 7828 */
306 DNS_EDNS_OPT_PADDING
= 12, /* RFC 7830 */
307 DNS_EDNS_OPT_CHAIN
= 13, /* RFC 7901 */
308 DNS_EDNS_OPT_KEY_TAG
= 14, /* RFC 8145 */
309 DNS_EDNS_OPT_EXT_ERROR
= 15, /* RFC 8914 */
310 DNS_EDNS_OPT_CLIENT_TAG
= 16,
311 DNS_EDNS_OPT_SERVER_TAG
= 17,
312 _DNS_EDNS_OPT_MAX_DEFINED
,
313 _DNS_EDNS_OPT_INVALID
= -EINVAL
,
316 /* https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#extended-dns-error-codes */
318 DNS_EDE_RCODE_OTHER
= 0, /* RFC 8914, Section 4.1 */
319 DNS_EDE_RCODE_UNSUPPORTED_DNSKEY_ALG
= 1, /* RFC 8914, Section 4.2 */
320 DNS_EDE_RCODE_UNSUPPORTED_DS_DIGEST
= 2, /* RFC 8914, Section 4.3 */
321 DNS_EDE_RCODE_STALE_ANSWER
= 3, /* RFC 8914, Section 4.4 */
322 DNS_EDE_RCODE_FORGED_ANSWER
= 4, /* RFC 8914, Section 4.5 */
323 DNS_EDE_RCODE_DNSSEC_INDETERMINATE
= 5, /* RFC 8914, Section 4.6 */
324 DNS_EDE_RCODE_DNSSEC_BOGUS
= 6, /* RFC 8914, Section 4.7 */
325 DNS_EDE_RCODE_SIG_EXPIRED
= 7, /* RFC 8914, Section 4.8 */
326 DNS_EDE_RCODE_SIG_NOT_YET_VALID
= 8, /* RFC 8914, Section 4.9 */
327 DNS_EDE_RCODE_DNSKEY_MISSING
= 9, /* RFC 8914, Section 4.10 */
328 DNS_EDE_RCODE_RRSIG_MISSING
= 10, /* RFC 8914, Section 4.11 */
329 DNS_EDE_RCODE_NO_ZONE_KEY_BIT
= 11, /* RFC 8914, Section 4.12 */
330 DNS_EDE_RCODE_NSEC_MISSING
= 12, /* RFC 8914, Section 4.13 */
331 DNS_EDE_RCODE_CACHED_ERROR
= 13, /* RFC 8914, Section 4.14 */
332 DNS_EDE_RCODE_NOT_READY
= 14, /* RFC 8914, Section 4.15 */
333 DNS_EDE_RCODE_BLOCKED
= 15, /* RFC 8914, Section 4.16 */
334 DNS_EDE_RCODE_CENSORED
= 16, /* RFC 8914, Section 4.17 */
335 DNS_EDE_RCODE_FILTERED
= 17, /* RFC 8914, Section 4.18 */
336 DNS_EDE_RCODE_PROHIBITIED
= 18, /* RFC 8914, Section 4.19 */
337 DNS_EDE_RCODE_STALE_NXDOMAIN_ANSWER
= 19, /* RFC 8914, Section 4.20 */
338 DNS_EDE_RCODE_NOT_AUTHORITATIVE
= 20, /* RFC 8914, Section 4.21 */
339 DNS_EDE_RCODE_NOT_SUPPORTED
= 21, /* RFC 8914, Section 4.22 */
340 DNS_EDE_RCODE_UNREACH_AUTHORITY
= 22, /* RFC 8914, Section 4.23 */
341 DNS_EDE_RCODE_NET_ERROR
= 23, /* RFC 8914, Section 4.24 */
342 DNS_EDE_RCODE_INVALID_DATA
= 24, /* RFC 8914, Section 4.25 */
343 DNS_EDE_RCODE_SIG_NEVER
= 25,
344 DNS_EDE_RCODE_TOO_EARLY
= 26, /* RFC 9250 */
345 DNS_EDE_RCODE_UNSUPPORTED_NSEC3_ITER
= 27, /* RFC 9276 */
346 DNS_EDE_RCODE_TRANSPORT_POLICY
= 28,
347 DNS_EDE_RCODE_SYNTHESIZED
= 29,
348 _DNS_EDE_RCODE_MAX_DEFINED
,
349 _DNS_EDE_RCODE_INVALID
= -EINVAL
,
352 const char* dns_rcode_to_string(int i
) _const_
;
353 int dns_rcode_from_string(const char *s
) _pure_
;
354 const char *format_dns_rcode(int i
, char buf
[static DECIMAL_STR_MAX(int)]);
355 #define FORMAT_DNS_RCODE(i) format_dns_rcode(i, (char [DECIMAL_STR_MAX(int)]) {})
357 const char* dns_ede_rcode_to_string(int i
) _const_
;
358 const char *format_dns_ede_rcode(int i
, char buf
[static DECIMAL_STR_MAX(int)]);
359 #define FORMAT_DNS_EDE_RCODE(i) format_dns_ede_rcode(i, (char [DECIMAL_STR_MAX(int)]) {})
361 const char* dns_protocol_to_string(DnsProtocol p
) _const_
;
362 DnsProtocol
dns_protocol_from_string(const char *s
) _pure_
;
364 /* https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml#dns-svcparamkeys */
366 DNS_SVC_PARAM_KEY_MANDATORY
= 0, /* RFC 9460 section 8 */
367 DNS_SVC_PARAM_KEY_ALPN
= 1, /* RFC 9460 section 7.1 */
368 DNS_SVC_PARAM_KEY_NO_DEFAULT_ALPN
= 2, /* RFC 9460 Section 7.1 */
369 DNS_SVC_PARAM_KEY_PORT
= 3, /* RFC 9460 section 7.2 */
370 DNS_SVC_PARAM_KEY_IPV4HINT
= 4, /* RFC 9460 section 7.3 */
371 DNS_SVC_PARAM_KEY_ECH
= 5, /* RFC 9460 */
372 DNS_SVC_PARAM_KEY_IPV6HINT
= 6, /* RFC 9460 section 7.3 */
373 DNS_SVC_PARAM_KEY_DOHPATH
= 7, /* RFC 9461 */
374 DNS_SVC_PARAM_KEY_OHTTP
= 8,
375 _DNS_SVC_PARAM_KEY_MAX_DEFINED
,
376 DNS_SVC_PARAM_KEY_INVALID
= 65535 /* RFC 9460 */
379 const char* dns_svc_param_key_to_string(int i
) _const_
;
380 const char *format_dns_svc_param_key(uint16_t i
, char buf
[static DECIMAL_STR_MAX(uint16_t)+3]);
381 #define FORMAT_DNS_SVC_PARAM_KEY(i) format_dns_svc_param_key(i, (char [DECIMAL_STR_MAX(uint16_t)+3]) {})
383 #define LLMNR_MULTICAST_IPV4_ADDRESS ((struct in_addr) { .s_addr = htobe32(224U << 24 | 252U) })
384 #define LLMNR_MULTICAST_IPV6_ADDRESS ((struct in6_addr) { .s6_addr = { 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03 } })
386 #define MDNS_MULTICAST_IPV4_ADDRESS ((struct in_addr) { .s_addr = htobe32(224U << 24 | 251U) })
387 #define MDNS_MULTICAST_IPV6_ADDRESS ((struct in6_addr) { .s6_addr = { 0xFF, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb } })
389 extern const struct hash_ops dns_packet_hash_ops
;
391 static inline uint64_t SD_RESOLVED_FLAGS_MAKE(
392 DnsProtocol protocol
,
398 /* Converts a protocol + family into a flags field as used in queries and responses */
400 f
= (authenticated
? SD_RESOLVED_AUTHENTICATED
: 0) |
401 (confidential
? SD_RESOLVED_CONFIDENTIAL
: 0);
404 case DNS_PROTOCOL_DNS
:
405 return f
|SD_RESOLVED_DNS
;
407 case DNS_PROTOCOL_LLMNR
:
408 return f
|(family
== AF_INET6
? SD_RESOLVED_LLMNR_IPV6
: SD_RESOLVED_LLMNR_IPV4
);
410 case DNS_PROTOCOL_MDNS
:
411 return f
|(family
== AF_INET6
? SD_RESOLVED_MDNS_IPV6
: SD_RESOLVED_MDNS_IPV4
);
418 static inline size_t dns_packet_size_max(DnsPacket
*p
) {
421 /* Why not insist on a fully initialized max_size during DnsPacket construction? Well, this way it's easy to
422 * allocate a transient, throw-away DnsPacket on the stack by simple zero initialization, without having to
423 * deal with explicit field initialization. */
425 return p
->max_size
!= 0 ? p
->max_size
: DNS_PACKET_SIZE_MAX
;
428 static inline size_t udp_header_size(int af
) {
432 return UDP4_PACKET_HEADER_SIZE
;
434 return UDP6_PACKET_HEADER_SIZE
;
436 assert_not_reached();
440 size_t dns_packet_size_unfragmented(DnsPacket
*p
);