]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-packet.c
pid1: do not reset subtree_control on already-existing units with delegation
[thirdparty/systemd.git] / src / resolve / resolved-dns-packet.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
74b2466e
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2014 Lennart Poettering
74b2466e
LP
6 ***/
7
73a4cd17
MCO
8#if HAVE_GCRYPT
9#include <gcrypt.h>
10#endif
11
b5efdb8a 12#include "alloc-util.h"
4ad7f276 13#include "dns-domain.h"
74b2466e 14#include "resolved-dns-packet.h"
8b43440b
LP
15#include "string-table.h"
16#include "strv.h"
17#include "unaligned.h"
18#include "utf8.h"
19#include "util.h"
74b2466e 20
7586f4d1
TG
21#define EDNS0_OPT_DO (1<<15)
22
46a58596 23assert_cc(DNS_PACKET_SIZE_START > DNS_PACKET_HEADER_SIZE)
88795538 24
e18a3c73
ZJS
25typedef struct DnsPacketRewinder {
26 DnsPacket *packet;
27 size_t saved_rindex;
28} DnsPacketRewinder;
29
30static void rewind_dns_packet(DnsPacketRewinder *rewinder) {
31 if (rewinder->packet)
32 dns_packet_rewind(rewinder->packet, rewinder->saved_rindex);
33}
34
9ed794a3
VC
35#define INIT_REWINDER(rewinder, p) do { rewinder.packet = p; rewinder.saved_rindex = p->rindex; } while (0)
36#define CANCEL_REWINDER(rewinder) do { rewinder.packet = NULL; } while (0)
e18a3c73 37
51027656
LP
38int dns_packet_new(
39 DnsPacket **ret,
40 DnsProtocol protocol,
41 size_t min_alloc_dsize,
42 size_t max_size) {
43
74b2466e
LP
44 DnsPacket *p;
45 size_t a;
46
47 assert(ret);
51027656
LP
48 assert(max_size >= DNS_PACKET_HEADER_SIZE);
49
50 if (max_size > DNS_PACKET_SIZE_MAX)
51 max_size = DNS_PACKET_SIZE_MAX;
74b2466e 52
46a58596
BR
53 /* The caller may not check what is going to be truly allocated, so do not allow to
54 * allocate a DNS packet bigger than DNS_PACKET_SIZE_MAX.
55 */
56 if (min_alloc_dsize > DNS_PACKET_SIZE_MAX) {
57 log_error("Requested packet data size too big: %zu", min_alloc_dsize);
58 return -EFBIG;
59 }
60
61 /* When dns_packet_new() is called with min_alloc_dsize == 0, allocate more than the
88795538
ZJS
62 * absolute minimum (which is the dns packet header size), to avoid
63 * resizing immediately again after appending the first data to the packet.
64 */
46a58596 65 if (min_alloc_dsize < DNS_PACKET_HEADER_SIZE)
88795538
ZJS
66 a = DNS_PACKET_SIZE_START;
67 else
46a58596 68 a = min_alloc_dsize;
74b2466e 69
c73ce96b
LP
70 /* round up to next page size */
71 a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
72
73 /* make sure we never allocate more than useful */
51027656
LP
74 if (a > max_size)
75 a = max_size;
c73ce96b 76
74b2466e
LP
77 p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
78 if (!p)
79 return -ENOMEM;
80
81 p->size = p->rindex = DNS_PACKET_HEADER_SIZE;
82 p->allocated = a;
51027656 83 p->max_size = max_size;
1716f6dc 84 p->protocol = protocol;
519ef046 85 p->opt_start = p->opt_size = (size_t) -1;
74b2466e
LP
86 p->n_ref = 1;
87
88 *ret = p;
89
90 return 0;
91}
92
dbfbb6e7 93void dns_packet_set_flags(DnsPacket *p, bool dnssec_checking_disabled, bool truncated) {
74b2466e 94
dbfbb6e7 95 DnsPacketHeader *h;
74b2466e 96
dbfbb6e7 97 assert(p);
74b2466e
LP
98
99 h = DNS_PACKET_HEADER(p);
1716f6dc 100
dbfbb6e7
DM
101 switch(p->protocol) {
102 case DNS_PROTOCOL_LLMNR:
103 assert(!truncated);
104
069360a6
LP
105 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
106 0 /* opcode */,
107 0 /* c */,
e5abebab 108 0 /* tc */,
069360a6
LP
109 0 /* t */,
110 0 /* ra */,
111 0 /* ad */,
112 0 /* cd */,
113 0 /* rcode */));
dbfbb6e7
DM
114 break;
115
116 case DNS_PROTOCOL_MDNS:
117 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
118 0 /* opcode */,
119 0 /* aa */,
120 truncated /* tc */,
121 0 /* rd (ask for recursion) */,
122 0 /* ra */,
123 0 /* ad */,
124 0 /* cd */,
125 0 /* rcode */));
126 break;
127
128 default:
129 assert(!truncated);
130
069360a6
LP
131 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
132 0 /* opcode */,
133 0 /* aa */,
134 0 /* tc */,
135 1 /* rd (ask for recursion) */,
136 0 /* ra */,
137 0 /* ad */,
24710c48 138 dnssec_checking_disabled /* cd */,
069360a6 139 0 /* rcode */));
dbfbb6e7
DM
140 }
141}
142
46a58596 143int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t min_alloc_dsize, bool dnssec_checking_disabled) {
dbfbb6e7
DM
144 DnsPacket *p;
145 int r;
146
147 assert(ret);
148
51027656 149 r = dns_packet_new(&p, protocol, min_alloc_dsize, DNS_PACKET_SIZE_MAX);
dbfbb6e7
DM
150 if (r < 0)
151 return r;
152
153 /* Always set the TC bit to 0 initially.
154 * If there are multiple packets later, we'll update the bit shortly before sending.
155 */
156 dns_packet_set_flags(p, dnssec_checking_disabled, false);
74b2466e
LP
157
158 *ret = p;
159 return 0;
160}
161
162DnsPacket *dns_packet_ref(DnsPacket *p) {
163
164 if (!p)
165 return NULL;
166
a8812dd7
LP
167 assert(!p->on_stack);
168
74b2466e
LP
169 assert(p->n_ref > 0);
170 p->n_ref++;
171 return p;
172}
173
174static void dns_packet_free(DnsPacket *p) {
175 char *s;
176
177 assert(p);
178
faa133f3
LP
179 dns_question_unref(p->question);
180 dns_answer_unref(p->answer);
d75acfb0 181 dns_resource_record_unref(p->opt);
322345fd 182
74b2466e
LP
183 while ((s = hashmap_steal_first_key(p->names)))
184 free(s);
185 hashmap_free(p->names);
186
faa133f3 187 free(p->_data);
a8812dd7
LP
188
189 if (!p->on_stack)
190 free(p);
74b2466e
LP
191}
192
193DnsPacket *dns_packet_unref(DnsPacket *p) {
194 if (!p)
195 return NULL;
196
197 assert(p->n_ref > 0);
198
6728a58d 199 dns_packet_unref(p->more);
9c491563 200
74b2466e
LP
201 if (p->n_ref == 1)
202 dns_packet_free(p);
203 else
204 p->n_ref--;
205
206 return NULL;
207}
208
209int dns_packet_validate(DnsPacket *p) {
210 assert(p);
211
212 if (p->size < DNS_PACKET_HEADER_SIZE)
213 return -EBADMSG;
214
c73ce96b
LP
215 if (p->size > DNS_PACKET_SIZE_MAX)
216 return -EBADMSG;
217
623a4c97 218 return 1;
74b2466e
LP
219}
220
221int dns_packet_validate_reply(DnsPacket *p) {
74b2466e
LP
222 int r;
223
224 assert(p);
225
226 r = dns_packet_validate(p);
227 if (r < 0)
228 return r;
229
623a4c97
LP
230 if (DNS_PACKET_QR(p) != 1)
231 return 0;
232
233 if (DNS_PACKET_OPCODE(p) != 0)
74b2466e
LP
234 return -EBADMSG;
235
818ef443 236 switch (p->protocol) {
d75acfb0 237
818ef443
DM
238 case DNS_PROTOCOL_LLMNR:
239 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
240 if (DNS_PACKET_QDCOUNT(p) != 1)
241 return -EBADMSG;
242
243 break;
244
4e5bf5e1
DM
245 case DNS_PROTOCOL_MDNS:
246 /* RFC 6762, Section 18 */
247 if (DNS_PACKET_RCODE(p) != 0)
248 return -EBADMSG;
249
250 break;
251
818ef443
DM
252 default:
253 break;
254 }
ea917db9 255
623a4c97
LP
256 return 1;
257}
258
259int dns_packet_validate_query(DnsPacket *p) {
260 int r;
261
262 assert(p);
263
264 r = dns_packet_validate(p);
265 if (r < 0)
266 return r;
267
268 if (DNS_PACKET_QR(p) != 0)
269 return 0;
270
3cb10d3a 271 if (DNS_PACKET_OPCODE(p) != 0)
74b2466e
LP
272 return -EBADMSG;
273
623a4c97
LP
274 if (DNS_PACKET_TC(p))
275 return -EBADMSG;
276
818ef443 277 switch (p->protocol) {
d75acfb0 278
818ef443 279 case DNS_PROTOCOL_LLMNR:
b30bf55d 280 case DNS_PROTOCOL_DNS:
818ef443
DM
281 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
282 if (DNS_PACKET_QDCOUNT(p) != 1)
283 return -EBADMSG;
623a4c97 284
818ef443
DM
285 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
286 if (DNS_PACKET_ANCOUNT(p) > 0)
287 return -EBADMSG;
623a4c97 288
818ef443
DM
289 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
290 if (DNS_PACKET_NSCOUNT(p) > 0)
291 return -EBADMSG;
292
293 break;
294
4e5bf5e1
DM
295 case DNS_PROTOCOL_MDNS:
296 /* RFC 6762, Section 18 */
297 if (DNS_PACKET_AA(p) != 0 ||
298 DNS_PACKET_RD(p) != 0 ||
299 DNS_PACKET_RA(p) != 0 ||
300 DNS_PACKET_AD(p) != 0 ||
301 DNS_PACKET_CD(p) != 0 ||
302 DNS_PACKET_RCODE(p) != 0)
303 return -EBADMSG;
304
305 break;
306
818ef443
DM
307 default:
308 break;
309 }
623a4c97
LP
310
311 return 1;
74b2466e
LP
312}
313
314static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
315 assert(p);
316
c73ce96b 317 if (p->size + add > p->allocated) {
51027656 318 size_t a, ms;
c73ce96b
LP
319
320 a = PAGE_ALIGN((p->size + add) * 2);
51027656
LP
321
322 ms = dns_packet_size_max(p);
323 if (a > ms)
324 a = ms;
c73ce96b
LP
325
326 if (p->size + add > a)
327 return -EMSGSIZE;
328
faa133f3 329 if (p->_data) {
c73ce96b
LP
330 void *d;
331
faa133f3 332 d = realloc(p->_data, a);
c73ce96b
LP
333 if (!d)
334 return -ENOMEM;
335
faa133f3 336 p->_data = d;
c73ce96b 337 } else {
faa133f3
LP
338 p->_data = malloc(a);
339 if (!p->_data)
c73ce96b
LP
340 return -ENOMEM;
341
faa133f3
LP
342 memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
343 memzero((uint8_t*) p->_data + p->size, a - p->size);
c73ce96b
LP
344 }
345
346 p->allocated = a;
347 }
74b2466e
LP
348
349 if (start)
350 *start = p->size;
351
352 if (ret)
353 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;
354
355 p->size += add;
356 return 0;
357}
358
9c5e12a4 359void dns_packet_truncate(DnsPacket *p, size_t sz) {
74b2466e
LP
360 Iterator i;
361 char *s;
362 void *n;
363
364 assert(p);
365
366 if (p->size <= sz)
367 return;
368
0e03ade5 369 HASHMAP_FOREACH_KEY(n, s, p->names, i) {
74b2466e
LP
370
371 if (PTR_TO_SIZE(n) < sz)
372 continue;
373
374 hashmap_remove(p->names, s);
375 free(s);
376 }
377
378 p->size = sz;
379}
380
623a4c97
LP
381int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
382 void *q;
383 int r;
384
385 assert(p);
386
387 r = dns_packet_extend(p, l, &q, start);
388 if (r < 0)
389 return r;
390
391 memcpy(q, d, l);
392 return 0;
393}
394
74b2466e
LP
395int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
396 void *d;
397 int r;
398
399 assert(p);
400
401 r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
402 if (r < 0)
403 return r;
404
405 ((uint8_t*) d)[0] = v;
406
407 return 0;
408}
409
410int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
411 void *d;
412 int r;
413
414 assert(p);
415
416 r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
417 if (r < 0)
418 return r;
419
725ca0e5 420 unaligned_write_be16(d, v);
623a4c97
LP
421
422 return 0;
423}
424
425int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start) {
426 void *d;
427 int r;
428
429 assert(p);
430
431 r = dns_packet_extend(p, sizeof(uint32_t), &d, start);
432 if (r < 0)
433 return r;
434
725ca0e5 435 unaligned_write_be32(d, v);
74b2466e
LP
436
437 return 0;
438}
439
440int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
74b2466e
LP
441 assert(p);
442 assert(s);
443
c38a52da 444 return dns_packet_append_raw_string(p, s, strlen(s), start);
74b2466e
LP
445}
446
2001c805
LP
447int dns_packet_append_raw_string(DnsPacket *p, const void *s, size_t size, size_t *start) {
448 void *d;
449 int r;
450
451 assert(p);
452 assert(s || size == 0);
453
454 if (size > 255)
455 return -E2BIG;
456
457 r = dns_packet_extend(p, 1 + size, &d, start);
458 if (r < 0)
459 return r;
460
461 ((uint8_t*) d)[0] = (uint8_t) size;
462
75f32f04 463 memcpy_safe(((uint8_t*) d) + 1, s, size);
2001c805
LP
464
465 return 0;
466}
467
a3db237b 468int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, bool canonical_candidate, size_t *start) {
a8812dd7 469 uint8_t *w;
74b2466e
LP
470 int r;
471
a3db237b
LP
472 /* Append a label to a packet. Optionally, does this in DNSSEC
473 * canonical form, if this label is marked as a candidate for
474 * it, and the canonical form logic is enabled for the
475 * packet */
476
74b2466e
LP
477 assert(p);
478 assert(d);
479
480 if (l > DNS_LABEL_MAX)
481 return -E2BIG;
482
a8812dd7 483 r = dns_packet_extend(p, 1 + l, (void**) &w, start);
74b2466e
LP
484 if (r < 0)
485 return r;
486
a8812dd7
LP
487 *(w++) = (uint8_t) l;
488
a3db237b 489 if (p->canonical_form && canonical_candidate) {
a8812dd7
LP
490 size_t i;
491
492 /* Generate in canonical form, as defined by DNSSEC
493 * RFC 4034, Section 6.2, i.e. all lower-case. */
494
b577e3d5
LP
495 for (i = 0; i < l; i++)
496 w[i] = (uint8_t) ascii_tolower(d[i]);
a8812dd7
LP
497 } else
498 /* Otherwise, just copy the string unaltered. This is
499 * essential for DNS-SD, where the casing of labels
500 * matters and needs to be retained. */
501 memcpy(w, d, l);
74b2466e
LP
502
503 return 0;
504}
505
f6a5fec6
LP
506int dns_packet_append_name(
507 DnsPacket *p,
508 const char *name,
509 bool allow_compression,
a3db237b 510 bool canonical_candidate,
f6a5fec6
LP
511 size_t *start) {
512
74b2466e
LP
513 size_t saved_size;
514 int r;
515
516 assert(p);
517 assert(name);
518
f6a5fec6
LP
519 if (p->refuse_compression)
520 allow_compression = false;
521
74b2466e
LP
522 saved_size = p->size;
523
e48b9a64 524 while (!dns_name_is_root(name)) {
08f904fd 525 const char *z = name;
74b2466e 526 char label[DNS_LABEL_MAX];
151226ab 527 size_t n = 0;
74b2466e 528
151226ab
ZJS
529 if (allow_compression)
530 n = PTR_TO_SIZE(hashmap_get(p->names, name));
74b2466e
LP
531 if (n > 0) {
532 assert(n < p->size);
533
534 if (n < 0x4000) {
535 r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
536 if (r < 0)
537 goto fail;
538
539 goto done;
540 }
541 }
542
74b2466e
LP
543 r = dns_label_unescape(&name, label, sizeof(label));
544 if (r < 0)
545 goto fail;
546
a3db237b 547 r = dns_packet_append_label(p, label, r, canonical_candidate, &n);
74b2466e
LP
548 if (r < 0)
549 goto fail;
550
151226ab 551 if (allow_compression) {
08f904fd
LP
552 _cleanup_free_ char *s = NULL;
553
554 s = strdup(z);
555 if (!s) {
556 r = -ENOMEM;
557 goto fail;
558 }
559
d5099efc 560 r = hashmap_ensure_allocated(&p->names, &dns_name_hash_ops);
151226ab
ZJS
561 if (r < 0)
562 goto fail;
74b2466e 563
151226ab
ZJS
564 r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
565 if (r < 0)
566 goto fail;
74b2466e 567
151226ab
ZJS
568 s = NULL;
569 }
74b2466e
LP
570 }
571
572 r = dns_packet_append_uint8(p, 0, NULL);
573 if (r < 0)
574 return r;
575
576done:
577 if (start)
578 *start = saved_size;
579
580 return 0;
581
582fail:
583 dns_packet_truncate(p, saved_size);
584 return r;
585}
586
58ab31d5 587int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, const DnsAnswerFlags flags, size_t *start) {
74b2466e 588 size_t saved_size;
58ab31d5 589 uint16_t class;
74b2466e
LP
590 int r;
591
592 assert(p);
593 assert(k);
594
595 saved_size = p->size;
596
1c02e7ba 597 r = dns_packet_append_name(p, dns_resource_key_name(k), true, true, NULL);
74b2466e
LP
598 if (r < 0)
599 goto fail;
600
601 r = dns_packet_append_uint16(p, k->type, NULL);
602 if (r < 0)
603 goto fail;
604
58ab31d5
DR
605 class = flags & DNS_ANSWER_CACHE_FLUSH ? k->class | MDNS_RR_CACHE_FLUSH : k->class;
606 r = dns_packet_append_uint16(p, class, NULL);
74b2466e
LP
607 if (r < 0)
608 goto fail;
609
610 if (start)
611 *start = saved_size;
612
613 return 0;
614
615fail:
616 dns_packet_truncate(p, saved_size);
617 return r;
618}
619
e1a9f1a8 620static int dns_packet_append_type_window(DnsPacket *p, uint8_t window, uint8_t length, const uint8_t *types, size_t *start) {
50f1e641
TG
621 size_t saved_size;
622 int r;
623
624 assert(p);
625 assert(types);
1792f223 626 assert(length > 0);
50f1e641 627
50f1e641
TG
628 saved_size = p->size;
629
1792f223
TG
630 r = dns_packet_append_uint8(p, window, NULL);
631 if (r < 0)
632 goto fail;
50f1e641 633
1792f223
TG
634 r = dns_packet_append_uint8(p, length, NULL);
635 if (r < 0)
636 goto fail;
6fa91901 637
1792f223
TG
638 r = dns_packet_append_blob(p, types, length, NULL);
639 if (r < 0)
640 goto fail;
50f1e641
TG
641
642 if (start)
643 *start = saved_size;
644
645 return 0;
646fail:
647 dns_packet_truncate(p, saved_size);
648 return r;
649}
650
651static int dns_packet_append_types(DnsPacket *p, Bitmap *types, size_t *start) {
cb57dd41 652 Iterator i;
50f1e641 653 uint8_t window = 0;
1792f223 654 uint8_t entry = 0;
50f1e641
TG
655 uint8_t bitmaps[32] = {};
656 unsigned n;
657 size_t saved_size;
658 int r;
659
660 assert(p);
50f1e641
TG
661
662 saved_size = p->size;
663
cb57dd41 664 BITMAP_FOREACH(n, types, i) {
50f1e641
TG
665 assert(n <= 0xffff);
666
1792f223
TG
667 if ((n >> 8) != window && bitmaps[entry / 8] != 0) {
668 r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
50f1e641
TG
669 if (r < 0)
670 goto fail;
671
1792f223 672 zero(bitmaps);
50f1e641
TG
673 }
674
1792f223 675 window = n >> 8;
50f1e641
TG
676 entry = n & 255;
677
678 bitmaps[entry / 8] |= 1 << (7 - (entry % 8));
679 }
680
d0ae14ff
LP
681 if (bitmaps[entry / 8] != 0) {
682 r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
683 if (r < 0)
684 goto fail;
685 }
50f1e641
TG
686
687 if (start)
688 *start = saved_size;
689
690 return 0;
691fail:
692 dns_packet_truncate(p, saved_size);
693 return r;
694}
695
dc913c9a 696/* Append the OPT pseudo-RR described in RFC6891 */
f2ed4c69 697int dns_packet_append_opt(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, int rcode, size_t *start) {
dc913c9a
TG
698 size_t saved_size;
699 int r;
700
701 assert(p);
702 /* we must never advertise supported packet size smaller than the legacy max */
703 assert(max_udp_size >= DNS_PACKET_UNICAST_SIZE_MAX);
f2ed4c69
LP
704 assert(rcode >= 0);
705 assert(rcode <= _DNS_RCODE_MAX);
dc913c9a 706
519ef046
LP
707 if (p->opt_start != (size_t) -1)
708 return -EBUSY;
709
710 assert(p->opt_size == (size_t) -1);
711
dc913c9a
TG
712 saved_size = p->size;
713
714 /* empty name */
715 r = dns_packet_append_uint8(p, 0, NULL);
716 if (r < 0)
717 return r;
718
719 /* type */
720 r = dns_packet_append_uint16(p, DNS_TYPE_OPT, NULL);
721 if (r < 0)
722 goto fail;
723
f2ed4c69 724 /* class: maximum udp packet that can be received */
dc913c9a
TG
725 r = dns_packet_append_uint16(p, max_udp_size, NULL);
726 if (r < 0)
727 goto fail;
728
729 /* extended RCODE and VERSION */
f2ed4c69 730 r = dns_packet_append_uint16(p, ((uint16_t) rcode & 0x0FF0) << 4, NULL);
dc913c9a
TG
731 if (r < 0)
732 goto fail;
733
7586f4d1
TG
734 /* flags: DNSSEC OK (DO), see RFC3225 */
735 r = dns_packet_append_uint16(p, edns0_do ? EDNS0_OPT_DO : 0, NULL);
dc913c9a
TG
736 if (r < 0)
737 goto fail;
738
739 /* RDLENGTH */
12c40d4c 740 if (edns0_do && !DNS_PACKET_QR(p)) {
b30bf55d 741 /* If DO is on and this is not a reply, also append RFC6975 Algorithm data */
665408ac
LP
742
743 static const uint8_t rfc6975[] = {
744
745 0, 5, /* OPTION_CODE: DAU */
546e635a 746#if HAVE_GCRYPT && GCRYPT_VERSION_NUMBER >= 0x010600
73a4cd17
MCO
747 0, 7, /* LIST_LENGTH */
748#else
665408ac 749 0, 6, /* LIST_LENGTH */
73a4cd17 750#endif
665408ac
LP
751 DNSSEC_ALGORITHM_RSASHA1,
752 DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1,
753 DNSSEC_ALGORITHM_RSASHA256,
754 DNSSEC_ALGORITHM_RSASHA512,
755 DNSSEC_ALGORITHM_ECDSAP256SHA256,
756 DNSSEC_ALGORITHM_ECDSAP384SHA384,
546e635a 757#if HAVE_GCRYPT && GCRYPT_VERSION_NUMBER >= 0x010600
73a4cd17
MCO
758 DNSSEC_ALGORITHM_ED25519,
759#endif
665408ac
LP
760
761 0, 6, /* OPTION_CODE: DHU */
762 0, 3, /* LIST_LENGTH */
763 DNSSEC_DIGEST_SHA1,
764 DNSSEC_DIGEST_SHA256,
765 DNSSEC_DIGEST_SHA384,
766
767 0, 7, /* OPTION_CODE: N3U */
768 0, 1, /* LIST_LENGTH */
769 NSEC3_ALGORITHM_SHA1,
770 };
771
772 r = dns_packet_append_uint16(p, sizeof(rfc6975), NULL);
773 if (r < 0)
774 goto fail;
775
776 r = dns_packet_append_blob(p, rfc6975, sizeof(rfc6975), NULL);
777 } else
778 r = dns_packet_append_uint16(p, 0, NULL);
dc913c9a
TG
779 if (r < 0)
780 goto fail;
781
519ef046
LP
782 DNS_PACKET_HEADER(p)->arcount = htobe16(DNS_PACKET_ARCOUNT(p) + 1);
783
784 p->opt_start = saved_size;
785 p->opt_size = p->size - saved_size;
786
dc913c9a
TG
787 if (start)
788 *start = saved_size;
789
790 return 0;
791
792fail:
793 dns_packet_truncate(p, saved_size);
794 return r;
795}
796
519ef046
LP
797int dns_packet_truncate_opt(DnsPacket *p) {
798 assert(p);
799
800 if (p->opt_start == (size_t) -1) {
801 assert(p->opt_size == (size_t) -1);
802 return 0;
803 }
804
805 assert(p->opt_size != (size_t) -1);
806 assert(DNS_PACKET_ARCOUNT(p) > 0);
807
808 if (p->opt_start + p->opt_size != p->size)
809 return -EBUSY;
810
811 dns_packet_truncate(p, p->opt_start);
812 DNS_PACKET_HEADER(p)->arcount = htobe16(DNS_PACKET_ARCOUNT(p) - 1);
813 p->opt_start = p->opt_size = (size_t) -1;
814
815 return 1;
816}
817
58ab31d5 818int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAnswerFlags flags, size_t *start, size_t *rdata_start) {
f471bc11 819
a8812dd7 820 size_t saved_size, rdlength_offset, end, rdlength, rds;
c3ae4188 821 uint32_t ttl;
623a4c97
LP
822 int r;
823
824 assert(p);
825 assert(rr);
826
827 saved_size = p->size;
828
58ab31d5 829 r = dns_packet_append_key(p, rr->key, flags, NULL);
623a4c97
LP
830 if (r < 0)
831 goto fail;
832
c3ae4188
DR
833 ttl = flags & DNS_ANSWER_GOODBYE ? 0 : rr->ttl;
834 r = dns_packet_append_uint32(p, ttl, NULL);
623a4c97
LP
835 if (r < 0)
836 goto fail;
837
838 /* Initially we write 0 here */
839 r = dns_packet_append_uint16(p, 0, &rdlength_offset);
840 if (r < 0)
841 goto fail;
842
a8812dd7
LP
843 rds = p->size - saved_size;
844
0dae31d4 845 switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
623a4c97 846
9c92ce6d
LP
847 case DNS_TYPE_SRV:
848 r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
849 if (r < 0)
850 goto fail;
851
852 r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
853 if (r < 0)
854 goto fail;
855
856 r = dns_packet_append_uint16(p, rr->srv.port, NULL);
857 if (r < 0)
858 goto fail;
859
a3db237b 860 r = dns_packet_append_name(p, rr->srv.name, true, false, NULL);
9c92ce6d
LP
861 break;
862
623a4c97
LP
863 case DNS_TYPE_PTR:
864 case DNS_TYPE_NS:
865 case DNS_TYPE_CNAME:
8ac4e9e1 866 case DNS_TYPE_DNAME:
a3db237b 867 r = dns_packet_append_name(p, rr->ptr.name, true, false, NULL);
623a4c97
LP
868 break;
869
870 case DNS_TYPE_HINFO:
871 r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
872 if (r < 0)
873 goto fail;
874
875 r = dns_packet_append_string(p, rr->hinfo.os, NULL);
876 break;
877
9de3e329 878 case DNS_TYPE_SPF: /* exactly the same as TXT */
2001c805 879 case DNS_TYPE_TXT:
2e276efc 880
2001c805 881 if (!rr->txt.items) {
1ccda9b7
LP
882 /* RFC 6763, section 6.1 suggests to generate
883 * single empty string for an empty array. */
884
2001c805 885 r = dns_packet_append_raw_string(p, NULL, 0, NULL);
2e276efc
ZJS
886 if (r < 0)
887 goto fail;
1ccda9b7 888 } else {
2001c805
LP
889 DnsTxtItem *i;
890
891 LIST_FOREACH(items, i, rr->txt.items) {
892 r = dns_packet_append_raw_string(p, i->data, i->length, NULL);
1ccda9b7
LP
893 if (r < 0)
894 goto fail;
895 }
2e276efc
ZJS
896 }
897
6a6fc3df 898 r = 0;
2e276efc 899 break;
2e276efc 900
623a4c97
LP
901 case DNS_TYPE_A:
902 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
903 break;
904
905 case DNS_TYPE_AAAA:
906 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
907 break;
908
909 case DNS_TYPE_SOA:
a3db237b 910 r = dns_packet_append_name(p, rr->soa.mname, true, false, NULL);
623a4c97
LP
911 if (r < 0)
912 goto fail;
913
a3db237b 914 r = dns_packet_append_name(p, rr->soa.rname, true, false, NULL);
623a4c97
LP
915 if (r < 0)
916 goto fail;
917
918 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
919 if (r < 0)
920 goto fail;
921
922 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
923 if (r < 0)
924 goto fail;
925
926 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
927 if (r < 0)
928 goto fail;
929
930 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
931 if (r < 0)
932 goto fail;
933
934 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
935 break;
936
937 case DNS_TYPE_MX:
946c7094
ZJS
938 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
939 if (r < 0)
940 goto fail;
941
a3db237b 942 r = dns_packet_append_name(p, rr->mx.exchange, true, false, NULL);
946c7094
ZJS
943 break;
944
0dae31d4
ZJS
945 case DNS_TYPE_LOC:
946 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
947 if (r < 0)
948 goto fail;
949
950 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
951 if (r < 0)
952 goto fail;
953
954 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
955 if (r < 0)
956 goto fail;
957
958 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
959 if (r < 0)
960 goto fail;
961
afbc4f26 962 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
0dae31d4
ZJS
963 if (r < 0)
964 goto fail;
965
afbc4f26 966 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
0dae31d4
ZJS
967 if (r < 0)
968 goto fail;
969
afbc4f26 970 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
0dae31d4
ZJS
971 break;
972
abf126a3
TG
973 case DNS_TYPE_DS:
974 r = dns_packet_append_uint16(p, rr->ds.key_tag, NULL);
975 if (r < 0)
976 goto fail;
977
978 r = dns_packet_append_uint8(p, rr->ds.algorithm, NULL);
979 if (r < 0)
980 goto fail;
981
982 r = dns_packet_append_uint8(p, rr->ds.digest_type, NULL);
983 if (r < 0)
984 goto fail;
985
986 r = dns_packet_append_blob(p, rr->ds.digest, rr->ds.digest_size, NULL);
987 break;
988
623a4c97 989 case DNS_TYPE_SSHFP:
42cc2eeb
LP
990 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
991 if (r < 0)
992 goto fail;
8db0d2f5 993
42cc2eeb
LP
994 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
995 if (r < 0)
996 goto fail;
997
549c1a25 998 r = dns_packet_append_blob(p, rr->sshfp.fingerprint, rr->sshfp.fingerprint_size, NULL);
42cc2eeb
LP
999 break;
1000
8db0d2f5 1001 case DNS_TYPE_DNSKEY:
f91dc240 1002 r = dns_packet_append_uint16(p, rr->dnskey.flags, NULL);
8db0d2f5
ZJS
1003 if (r < 0)
1004 goto fail;
1005
f91dc240 1006 r = dns_packet_append_uint8(p, rr->dnskey.protocol, NULL);
8db0d2f5
ZJS
1007 if (r < 0)
1008 goto fail;
1009
1010 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
1011 if (r < 0)
1012 goto fail;
1013
1014 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
1015 break;
1016
151226ab
ZJS
1017 case DNS_TYPE_RRSIG:
1018 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
1019 if (r < 0)
1020 goto fail;
1021
1022 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
1023 if (r < 0)
1024 goto fail;
1025
1026 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
1027 if (r < 0)
1028 goto fail;
1029
1030 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
1031 if (r < 0)
1032 goto fail;
1033
1034 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
1035 if (r < 0)
1036 goto fail;
1037
1038 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
1039 if (r < 0)
1040 goto fail;
1041
0b1b17d3 1042 r = dns_packet_append_uint16(p, rr->rrsig.key_tag, NULL);
151226ab
ZJS
1043 if (r < 0)
1044 goto fail;
1045
a3db237b 1046 r = dns_packet_append_name(p, rr->rrsig.signer, false, true, NULL);
151226ab
ZJS
1047 if (r < 0)
1048 goto fail;
1049
1050 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
1051 break;
1052
50f1e641 1053 case DNS_TYPE_NSEC:
a3db237b 1054 r = dns_packet_append_name(p, rr->nsec.next_domain_name, false, false, NULL);
50f1e641
TG
1055 if (r < 0)
1056 goto fail;
1057
1058 r = dns_packet_append_types(p, rr->nsec.types, NULL);
1059 if (r < 0)
1060 goto fail;
1061
5d45a880 1062 break;
d75acfb0 1063
5d45a880
TG
1064 case DNS_TYPE_NSEC3:
1065 r = dns_packet_append_uint8(p, rr->nsec3.algorithm, NULL);
1066 if (r < 0)
1067 goto fail;
1068
1069 r = dns_packet_append_uint8(p, rr->nsec3.flags, NULL);
1070 if (r < 0)
1071 goto fail;
1072
1073 r = dns_packet_append_uint16(p, rr->nsec3.iterations, NULL);
1074 if (r < 0)
1075 goto fail;
1076
1077 r = dns_packet_append_uint8(p, rr->nsec3.salt_size, NULL);
1078 if (r < 0)
1079 goto fail;
1080
1081 r = dns_packet_append_blob(p, rr->nsec3.salt, rr->nsec3.salt_size, NULL);
1082 if (r < 0)
1083 goto fail;
1084
1085 r = dns_packet_append_uint8(p, rr->nsec3.next_hashed_name_size, NULL);
1086 if (r < 0)
1087 goto fail;
1088
1089 r = dns_packet_append_blob(p, rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, NULL);
1090 if (r < 0)
1091 goto fail;
1092
1093 r = dns_packet_append_types(p, rr->nsec3.types, NULL);
1094 if (r < 0)
1095 goto fail;
1096
50f1e641 1097 break;
d75acfb0 1098
48d45d2b
ZJS
1099 case DNS_TYPE_TLSA:
1100 r = dns_packet_append_uint8(p, rr->tlsa.cert_usage, NULL);
1101 if (r < 0)
1102 goto fail;
1103
1104 r = dns_packet_append_uint8(p, rr->tlsa.selector, NULL);
1105 if (r < 0)
1106 goto fail;
1107
1108 r = dns_packet_append_uint8(p, rr->tlsa.matching_type, NULL);
1109 if (r < 0)
1110 goto fail;
1111
1112 r = dns_packet_append_blob(p, rr->tlsa.data, rr->tlsa.data_size, NULL);
1113 break;
1114
95052df3
ZJS
1115 case DNS_TYPE_CAA:
1116 r = dns_packet_append_uint8(p, rr->caa.flags, NULL);
1117 if (r < 0)
1118 goto fail;
1119
1120 r = dns_packet_append_string(p, rr->caa.tag, NULL);
1121 if (r < 0)
1122 goto fail;
1123
1124 r = dns_packet_append_blob(p, rr->caa.value, rr->caa.value_size, NULL);
1125 break;
1126
d75acfb0 1127 case DNS_TYPE_OPT:
d93a16b8 1128 case DNS_TYPE_OPENPGPKEY:
0dae31d4 1129 case _DNS_TYPE_INVALID: /* unparseable */
623a4c97 1130 default:
0dae31d4 1131
a43a068a 1132 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.data_size, NULL);
623a4c97
LP
1133 break;
1134 }
1135 if (r < 0)
1136 goto fail;
1137
1138 /* Let's calculate the actual data size and update the field */
1139 rdlength = p->size - rdlength_offset - sizeof(uint16_t);
1140 if (rdlength > 0xFFFF) {
555f5cdc 1141 r = -ENOSPC;
623a4c97
LP
1142 goto fail;
1143 }
1144
1145 end = p->size;
1146 p->size = rdlength_offset;
1147 r = dns_packet_append_uint16(p, rdlength, NULL);
1148 if (r < 0)
1149 goto fail;
1150 p->size = end;
1151
351e6342
LP
1152 if (start)
1153 *start = saved_size;
1154
a8812dd7
LP
1155 if (rdata_start)
1156 *rdata_start = rds;
1157
623a4c97
LP
1158 return 0;
1159
1160fail:
1161 dns_packet_truncate(p, saved_size);
1162 return r;
1163}
1164
f471bc11
LP
1165int dns_packet_append_question(DnsPacket *p, DnsQuestion *q) {
1166 DnsResourceKey *key;
1167 int r;
1168
1169 assert(p);
1170
1171 DNS_QUESTION_FOREACH(key, q) {
58ab31d5 1172 r = dns_packet_append_key(p, key, 0, NULL);
f471bc11
LP
1173 if (r < 0)
1174 return r;
1175 }
1176
1177 return 0;
1178}
1179
1180int dns_packet_append_answer(DnsPacket *p, DnsAnswer *a) {
1181 DnsResourceRecord *rr;
58ab31d5 1182 DnsAnswerFlags flags;
f471bc11
LP
1183 int r;
1184
1185 assert(p);
1186
58ab31d5
DR
1187 DNS_ANSWER_FOREACH_FLAGS(rr, flags, a) {
1188 r = dns_packet_append_rr(p, rr, flags, NULL, NULL);
f471bc11
LP
1189 if (r < 0)
1190 return r;
1191 }
1192
1193 return 0;
1194}
1195
74b2466e
LP
1196int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
1197 assert(p);
1198
1199 if (p->rindex + sz > p->size)
1200 return -EMSGSIZE;
1201
1202 if (ret)
1203 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
1204
1205 if (start)
1206 *start = p->rindex;
1207
1208 p->rindex += sz;
1209 return 0;
1210}
1211
8ba9fd9c 1212void dns_packet_rewind(DnsPacket *p, size_t idx) {
74b2466e
LP
1213 assert(p);
1214 assert(idx <= p->size);
1215 assert(idx >= DNS_PACKET_HEADER_SIZE);
1216
1217 p->rindex = idx;
1218}
1219
623a4c97
LP
1220int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
1221 const void *q;
1222 int r;
1223
1224 assert(p);
1225 assert(d);
1226
1227 r = dns_packet_read(p, sz, &q, start);
1228 if (r < 0)
1229 return r;
1230
1231 memcpy(d, q, sz);
1232 return 0;
1233}
1234
f5430a3e
LP
1235static int dns_packet_read_memdup(
1236 DnsPacket *p, size_t size,
1237 void **ret, size_t *ret_size,
1238 size_t *ret_start) {
1239
1240 const void *src;
1241 size_t start;
1242 int r;
1243
1244 assert(p);
1245 assert(ret);
1246
1247 r = dns_packet_read(p, size, &src, &start);
1248 if (r < 0)
1249 return r;
1250
1251 if (size <= 0)
1252 *ret = NULL;
1253 else {
1254 void *copy;
1255
1256 copy = memdup(src, size);
1257 if (!copy)
1258 return -ENOMEM;
1259
1260 *ret = copy;
1261 }
1262
1263 if (ret_size)
1264 *ret_size = size;
1265 if (ret_start)
1266 *ret_start = start;
1267
1268 return 0;
1269}
1270
74b2466e
LP
1271int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
1272 const void *d;
1273 int r;
1274
1275 assert(p);
1276
1277 r = dns_packet_read(p, sizeof(uint8_t), &d, start);
1278 if (r < 0)
1279 return r;
1280
1281 *ret = ((uint8_t*) d)[0];
1282 return 0;
1283}
1284
1285int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
1286 const void *d;
1287 int r;
1288
1289 assert(p);
1290
1291 r = dns_packet_read(p, sizeof(uint16_t), &d, start);
1292 if (r < 0)
1293 return r;
1294
725ca0e5
TG
1295 *ret = unaligned_read_be16(d);
1296
74b2466e
LP
1297 return 0;
1298}
1299
1300int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
1301 const void *d;
1302 int r;
1303
1304 assert(p);
1305
1306 r = dns_packet_read(p, sizeof(uint32_t), &d, start);
1307 if (r < 0)
1308 return r;
1309
725ca0e5 1310 *ret = unaligned_read_be32(d);
74b2466e
LP
1311
1312 return 0;
1313}
1314
1315int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
e18a3c73 1316 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
74b2466e
LP
1317 const void *d;
1318 char *t;
1319 uint8_t c;
1320 int r;
1321
1322 assert(p);
e18a3c73 1323 INIT_REWINDER(rewinder, p);
74b2466e
LP
1324
1325 r = dns_packet_read_uint8(p, &c, NULL);
1326 if (r < 0)
e18a3c73 1327 return r;
74b2466e
LP
1328
1329 r = dns_packet_read(p, c, &d, NULL);
1330 if (r < 0)
e18a3c73 1331 return r;
74b2466e 1332
e18a3c73
ZJS
1333 if (memchr(d, 0, c))
1334 return -EBADMSG;
74b2466e
LP
1335
1336 t = strndup(d, c);
e18a3c73
ZJS
1337 if (!t)
1338 return -ENOMEM;
74b2466e
LP
1339
1340 if (!utf8_is_valid(t)) {
1341 free(t);
e18a3c73 1342 return -EBADMSG;
74b2466e
LP
1343 }
1344
1345 *ret = t;
1346
1347 if (start)
e18a3c73
ZJS
1348 *start = rewinder.saved_rindex;
1349 CANCEL_REWINDER(rewinder);
74b2466e
LP
1350
1351 return 0;
74b2466e
LP
1352}
1353
2001c805 1354int dns_packet_read_raw_string(DnsPacket *p, const void **ret, size_t *size, size_t *start) {
e18a3c73 1355 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
2001c805
LP
1356 uint8_t c;
1357 int r;
1358
1359 assert(p);
e18a3c73 1360 INIT_REWINDER(rewinder, p);
2001c805
LP
1361
1362 r = dns_packet_read_uint8(p, &c, NULL);
1363 if (r < 0)
e18a3c73 1364 return r;
2001c805
LP
1365
1366 r = dns_packet_read(p, c, ret, NULL);
1367 if (r < 0)
e18a3c73 1368 return r;
2001c805
LP
1369
1370 if (size)
1371 *size = c;
1372 if (start)
e18a3c73
ZJS
1373 *start = rewinder.saved_rindex;
1374 CANCEL_REWINDER(rewinder);
2001c805
LP
1375
1376 return 0;
2001c805
LP
1377}
1378
f6a5fec6
LP
1379int dns_packet_read_name(
1380 DnsPacket *p,
1381 char **_ret,
1382 bool allow_compression,
1383 size_t *start) {
1384
e18a3c73
ZJS
1385 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
1386 size_t after_rindex = 0, jump_barrier;
74b2466e
LP
1387 _cleanup_free_ char *ret = NULL;
1388 size_t n = 0, allocated = 0;
1389 bool first = true;
1390 int r;
1391
1392 assert(p);
1393 assert(_ret);
e18a3c73
ZJS
1394 INIT_REWINDER(rewinder, p);
1395 jump_barrier = p->rindex;
74b2466e 1396
f6a5fec6
LP
1397 if (p->refuse_compression)
1398 allow_compression = false;
1399
74b2466e
LP
1400 for (;;) {
1401 uint8_t c, d;
1402
1403 r = dns_packet_read_uint8(p, &c, NULL);
1404 if (r < 0)
e18a3c73 1405 return r;
74b2466e
LP
1406
1407 if (c == 0)
1408 /* End of name */
1409 break;
1410 else if (c <= 63) {
74b2466e
LP
1411 const char *label;
1412
1413 /* Literal label */
1414 r = dns_packet_read(p, c, (const void**) &label, NULL);
1415 if (r < 0)
e18a3c73 1416 return r;
74b2466e 1417
e18a3c73
ZJS
1418 if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX))
1419 return -ENOMEM;
74b2466e 1420
422baca0 1421 if (first)
74b2466e 1422 first = false;
422baca0
LP
1423 else
1424 ret[n++] = '.';
1425
1426 r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
1427 if (r < 0)
e18a3c73 1428 return r;
74b2466e 1429
74b2466e
LP
1430 n += r;
1431 continue;
151226ab 1432 } else if (allow_compression && (c & 0xc0) == 0xc0) {
74b2466e
LP
1433 uint16_t ptr;
1434
1435 /* Pointer */
1436 r = dns_packet_read_uint8(p, &d, NULL);
1437 if (r < 0)
e18a3c73 1438 return r;
74b2466e
LP
1439
1440 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
e18a3c73
ZJS
1441 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier)
1442 return -EBADMSG;
74b2466e
LP
1443
1444 if (after_rindex == 0)
1445 after_rindex = p->rindex;
1446
f131770b 1447 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
c75dbf9b 1448 jump_barrier = ptr;
74b2466e 1449 p->rindex = ptr;
e18a3c73
ZJS
1450 } else
1451 return -EBADMSG;
74b2466e
LP
1452 }
1453
e18a3c73
ZJS
1454 if (!GREEDY_REALLOC(ret, allocated, n + 1))
1455 return -ENOMEM;
74b2466e
LP
1456
1457 ret[n] = 0;
1458
1459 if (after_rindex != 0)
1460 p->rindex= after_rindex;
1461
1cc6c93a 1462 *_ret = TAKE_PTR(ret);
74b2466e
LP
1463
1464 if (start)
e18a3c73
ZJS
1465 *start = rewinder.saved_rindex;
1466 CANCEL_REWINDER(rewinder);
74b2466e
LP
1467
1468 return 0;
74b2466e
LP
1469}
1470
50f1e641
TG
1471static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *start) {
1472 uint8_t window;
1473 uint8_t length;
1474 const uint8_t *bitmap;
2ad613ad 1475 uint8_t bit = 0;
50f1e641
TG
1476 unsigned i;
1477 bool found = false;
e18a3c73 1478 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
50f1e641
TG
1479 int r;
1480
1481 assert(p);
1482 assert(types);
e18a3c73 1483 INIT_REWINDER(rewinder, p);
50f1e641
TG
1484
1485 r = bitmap_ensure_allocated(types);
1486 if (r < 0)
e18a3c73 1487 return r;
50f1e641
TG
1488
1489 r = dns_packet_read_uint8(p, &window, NULL);
1490 if (r < 0)
e18a3c73 1491 return r;
50f1e641
TG
1492
1493 r = dns_packet_read_uint8(p, &length, NULL);
1494 if (r < 0)
e18a3c73 1495 return r;
50f1e641
TG
1496
1497 if (length == 0 || length > 32)
1498 return -EBADMSG;
1499
1500 r = dns_packet_read(p, length, (const void **)&bitmap, NULL);
1501 if (r < 0)
e18a3c73 1502 return r;
50f1e641
TG
1503
1504 for (i = 0; i < length; i++) {
1505 uint8_t bitmask = 1 << 7;
50f1e641
TG
1506
1507 if (!bitmap[i]) {
1508 found = false;
2ad613ad 1509 bit += 8;
50f1e641
TG
1510 continue;
1511 }
1512
1513 found = true;
1514
9f939335 1515 for (; bitmask; bit++, bitmask >>= 1)
50f1e641
TG
1516 if (bitmap[i] & bitmask) {
1517 uint16_t n;
1518
50f1e641
TG
1519 n = (uint16_t) window << 8 | (uint16_t) bit;
1520
8e6edc49
TG
1521 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1522 if (dns_type_is_pseudo(n))
1523 continue;
1524
50f1e641
TG
1525 r = bitmap_set(*types, n);
1526 if (r < 0)
e18a3c73 1527 return r;
50f1e641 1528 }
50f1e641
TG
1529 }
1530
1531 if (!found)
1532 return -EBADMSG;
1533
1534 if (start)
e18a3c73
ZJS
1535 *start = rewinder.saved_rindex;
1536 CANCEL_REWINDER(rewinder);
50f1e641
TG
1537
1538 return 0;
50f1e641
TG
1539}
1540
89492aaf 1541static int dns_packet_read_type_windows(DnsPacket *p, Bitmap **types, size_t size, size_t *start) {
e18a3c73 1542 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
89492aaf
TG
1543 int r;
1544
e18a3c73 1545 INIT_REWINDER(rewinder, p);
89492aaf 1546
e18a3c73 1547 while (p->rindex < rewinder.saved_rindex + size) {
89492aaf
TG
1548 r = dns_packet_read_type_window(p, types, NULL);
1549 if (r < 0)
e18a3c73 1550 return r;
89492aaf
TG
1551
1552 /* don't read past end of current RR */
e18a3c73
ZJS
1553 if (p->rindex > rewinder.saved_rindex + size)
1554 return -EBADMSG;
89492aaf
TG
1555 }
1556
e18a3c73
ZJS
1557 if (p->rindex != rewinder.saved_rindex + size)
1558 return -EBADMSG;
89492aaf
TG
1559
1560 if (start)
e18a3c73
ZJS
1561 *start = rewinder.saved_rindex;
1562 CANCEL_REWINDER(rewinder);
89492aaf
TG
1563
1564 return 0;
89492aaf
TG
1565}
1566
d2579eec 1567int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, bool *ret_cache_flush, size_t *start) {
e18a3c73 1568 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
faa133f3 1569 _cleanup_free_ char *name = NULL;
d2579eec 1570 bool cache_flush = false;
faa133f3
LP
1571 uint16_t class, type;
1572 DnsResourceKey *key;
74b2466e
LP
1573 int r;
1574
1575 assert(p);
1576 assert(ret);
e18a3c73 1577 INIT_REWINDER(rewinder, p);
74b2466e 1578
151226ab 1579 r = dns_packet_read_name(p, &name, true, NULL);
74b2466e 1580 if (r < 0)
e18a3c73 1581 return r;
74b2466e 1582
faa133f3 1583 r = dns_packet_read_uint16(p, &type, NULL);
74b2466e 1584 if (r < 0)
e18a3c73 1585 return r;
74b2466e 1586
faa133f3 1587 r = dns_packet_read_uint16(p, &class, NULL);
74b2466e 1588 if (r < 0)
e18a3c73 1589 return r;
74b2466e 1590
23502de3
DM
1591 if (p->protocol == DNS_PROTOCOL_MDNS) {
1592 /* See RFC6762, Section 10.2 */
1593
d2579eec 1594 if (type != DNS_TYPE_OPT && (class & MDNS_RR_CACHE_FLUSH)) {
23502de3 1595 class &= ~MDNS_RR_CACHE_FLUSH;
d2579eec
LP
1596 cache_flush = true;
1597 }
23502de3
DM
1598 }
1599
faa133f3 1600 key = dns_resource_key_new_consume(class, type, name);
e18a3c73
ZJS
1601 if (!key)
1602 return -ENOMEM;
faa133f3
LP
1603
1604 name = NULL;
1605 *ret = key;
74b2466e 1606
d2579eec
LP
1607 if (ret_cache_flush)
1608 *ret_cache_flush = cache_flush;
74b2466e 1609 if (start)
e18a3c73
ZJS
1610 *start = rewinder.saved_rindex;
1611 CANCEL_REWINDER(rewinder);
74b2466e
LP
1612
1613 return 0;
74b2466e
LP
1614}
1615
afbc4f26
ZJS
1616static bool loc_size_ok(uint8_t size) {
1617 uint8_t m = size >> 4, e = size & 0xF;
1618
1619 return m <= 9 && e <= 9 && (m > 0 || e == 0);
1620}
1621
d2579eec 1622int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_flush, size_t *start) {
faa133f3
LP
1623 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1624 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
e18a3c73
ZJS
1625 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder;
1626 size_t offset;
74b2466e 1627 uint16_t rdlength;
d2579eec 1628 bool cache_flush;
74b2466e
LP
1629 int r;
1630
1631 assert(p);
1632 assert(ret);
1633
e18a3c73 1634 INIT_REWINDER(rewinder, p);
74b2466e 1635
d2579eec 1636 r = dns_packet_read_key(p, &key, &cache_flush, NULL);
74b2466e 1637 if (r < 0)
e18a3c73 1638 return r;
74b2466e 1639
e18a3c73
ZJS
1640 if (!dns_class_is_valid_rr(key->class) || !dns_type_is_valid_rr(key->type))
1641 return -EBADMSG;
0e2bcd6a 1642
faa133f3 1643 rr = dns_resource_record_new(key);
e18a3c73
ZJS
1644 if (!rr)
1645 return -ENOMEM;
faa133f3 1646
74b2466e
LP
1647 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1648 if (r < 0)
e18a3c73 1649 return r;
74b2466e 1650
0d0b52d7
LP
1651 /* RFC 2181, Section 8, suggests to
1652 * treat a TTL with the MSB set as a zero TTL. */
1653 if (rr->ttl & UINT32_C(0x80000000))
1654 rr->ttl = 0;
1655
74b2466e
LP
1656 r = dns_packet_read_uint16(p, &rdlength, NULL);
1657 if (r < 0)
e18a3c73 1658 return r;
74b2466e 1659
e18a3c73
ZJS
1660 if (p->rindex + rdlength > p->size)
1661 return -EBADMSG;
74b2466e
LP
1662
1663 offset = p->rindex;
1664
faa133f3 1665 switch (rr->key->type) {
74b2466e 1666
9c92ce6d
LP
1667 case DNS_TYPE_SRV:
1668 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1669 if (r < 0)
e18a3c73 1670 return r;
9c92ce6d
LP
1671 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1672 if (r < 0)
e18a3c73 1673 return r;
9c92ce6d
LP
1674 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1675 if (r < 0)
e18a3c73 1676 return r;
151226ab 1677 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
9c92ce6d
LP
1678 break;
1679
74b2466e
LP
1680 case DNS_TYPE_PTR:
1681 case DNS_TYPE_NS:
1682 case DNS_TYPE_CNAME:
8ac4e9e1 1683 case DNS_TYPE_DNAME:
151226ab 1684 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
74b2466e
LP
1685 break;
1686
1687 case DNS_TYPE_HINFO:
1688 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1689 if (r < 0)
e18a3c73 1690 return r;
74b2466e
LP
1691
1692 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1693 break;
1694
9de3e329 1695 case DNS_TYPE_SPF: /* exactly the same as TXT */
1ccda9b7
LP
1696 case DNS_TYPE_TXT:
1697 if (rdlength <= 0) {
ebb779dc
DR
1698 r = dns_txt_item_new_empty(&rr->txt.items);
1699 if (r < 0)
1700 return r;
1ccda9b7 1701 } else {
2001c805
LP
1702 DnsTxtItem *last = NULL;
1703
1ccda9b7 1704 while (p->rindex < offset + rdlength) {
2001c805
LP
1705 DnsTxtItem *i;
1706 const void *data;
1707 size_t sz;
2e276efc 1708
2001c805 1709 r = dns_packet_read_raw_string(p, &data, &sz, NULL);
1ccda9b7 1710 if (r < 0)
2001c805 1711 return r;
1ccda9b7 1712
2001c805
LP
1713 i = malloc0(offsetof(DnsTxtItem, data) + sz + 1); /* extra NUL byte at the end */
1714 if (!i)
1715 return -ENOMEM;
1716
1717 memcpy(i->data, data, sz);
1718 i->length = sz;
1719
1720 LIST_INSERT_AFTER(items, rr->txt.items, last, i);
1721 last = i;
1ccda9b7 1722 }
6a6fc3df
LP
1723 }
1724
1725 r = 0;
2e276efc 1726 break;
2e276efc 1727
74b2466e 1728 case DNS_TYPE_A:
623a4c97 1729 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
74b2466e
LP
1730 break;
1731
1732 case DNS_TYPE_AAAA:
623a4c97 1733 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
74b2466e
LP
1734 break;
1735
7e8e0422 1736 case DNS_TYPE_SOA:
151226ab 1737 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
7e8e0422 1738 if (r < 0)
e18a3c73 1739 return r;
7e8e0422 1740
151226ab 1741 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
7e8e0422 1742 if (r < 0)
e18a3c73 1743 return r;
7e8e0422
LP
1744
1745 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1746 if (r < 0)
e18a3c73 1747 return r;
7e8e0422
LP
1748
1749 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1750 if (r < 0)
e18a3c73 1751 return r;
7e8e0422
LP
1752
1753 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1754 if (r < 0)
e18a3c73 1755 return r;
7e8e0422
LP
1756
1757 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1758 if (r < 0)
e18a3c73 1759 return r;
7e8e0422
LP
1760
1761 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1762 break;
1763
623a4c97 1764 case DNS_TYPE_MX:
946c7094
ZJS
1765 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1766 if (r < 0)
e18a3c73 1767 return r;
946c7094 1768
151226ab 1769 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
946c7094
ZJS
1770 break;
1771
0dae31d4
ZJS
1772 case DNS_TYPE_LOC: {
1773 uint8_t t;
1774 size_t pos;
1775
1776 r = dns_packet_read_uint8(p, &t, &pos);
1777 if (r < 0)
e18a3c73 1778 return r;
0dae31d4
ZJS
1779
1780 if (t == 0) {
1781 rr->loc.version = t;
1782
1783 r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1784 if (r < 0)
e18a3c73 1785 return r;
0dae31d4 1786
e18a3c73
ZJS
1787 if (!loc_size_ok(rr->loc.size))
1788 return -EBADMSG;
afbc4f26 1789
0dae31d4
ZJS
1790 r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1791 if (r < 0)
e18a3c73 1792 return r;
0dae31d4 1793
e18a3c73
ZJS
1794 if (!loc_size_ok(rr->loc.horiz_pre))
1795 return -EBADMSG;
afbc4f26 1796
0dae31d4
ZJS
1797 r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1798 if (r < 0)
e18a3c73 1799 return r;
0dae31d4 1800
e18a3c73
ZJS
1801 if (!loc_size_ok(rr->loc.vert_pre))
1802 return -EBADMSG;
afbc4f26 1803
0dae31d4
ZJS
1804 r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1805 if (r < 0)
e18a3c73 1806 return r;
0dae31d4
ZJS
1807
1808 r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1809 if (r < 0)
e18a3c73 1810 return r;
0dae31d4
ZJS
1811
1812 r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1813 if (r < 0)
e18a3c73 1814 return r;
0dae31d4
ZJS
1815
1816 break;
1817 } else {
1818 dns_packet_rewind(p, pos);
1819 rr->unparseable = true;
afbc4f26 1820 goto unparseable;
0dae31d4
ZJS
1821 }
1822 }
1823
abf126a3
TG
1824 case DNS_TYPE_DS:
1825 r = dns_packet_read_uint16(p, &rr->ds.key_tag, NULL);
1826 if (r < 0)
e18a3c73 1827 return r;
abf126a3
TG
1828
1829 r = dns_packet_read_uint8(p, &rr->ds.algorithm, NULL);
1830 if (r < 0)
e18a3c73 1831 return r;
abf126a3
TG
1832
1833 r = dns_packet_read_uint8(p, &rr->ds.digest_type, NULL);
1834 if (r < 0)
e18a3c73 1835 return r;
abf126a3 1836
8a0f6d1f
SL
1837 if (rdlength < 4)
1838 return -EBADMSG;
1839
f5430a3e
LP
1840 r = dns_packet_read_memdup(p, rdlength - 4,
1841 &rr->ds.digest, &rr->ds.digest_size,
1842 NULL);
abf126a3 1843 if (r < 0)
e18a3c73 1844 return r;
abf126a3 1845
e18a3c73 1846 if (rr->ds.digest_size <= 0)
f1d178cc
TG
1847 /* the accepted size depends on the algorithm, but for now
1848 just ensure that the value is greater than zero */
e18a3c73 1849 return -EBADMSG;
f1d178cc 1850
abf126a3 1851 break;
d75acfb0 1852
623a4c97 1853 case DNS_TYPE_SSHFP:
42cc2eeb
LP
1854 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1855 if (r < 0)
e18a3c73 1856 return r;
42cc2eeb
LP
1857
1858 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1859 if (r < 0)
e18a3c73 1860 return r;
42cc2eeb 1861
8a0f6d1f
SL
1862 if (rdlength < 2)
1863 return -EBADMSG;
1864
f5430a3e 1865 r = dns_packet_read_memdup(p, rdlength - 2,
549c1a25 1866 &rr->sshfp.fingerprint, &rr->sshfp.fingerprint_size,
f5430a3e 1867 NULL);
f1d178cc 1868
e18a3c73 1869 if (rr->sshfp.fingerprint_size <= 0)
f1d178cc
TG
1870 /* the accepted size depends on the algorithm, but for now
1871 just ensure that the value is greater than zero */
e18a3c73 1872 return -EBADMSG;
f1d178cc 1873
8db0d2f5
ZJS
1874 break;
1875
f91dc240
LP
1876 case DNS_TYPE_DNSKEY:
1877 r = dns_packet_read_uint16(p, &rr->dnskey.flags, NULL);
8db0d2f5 1878 if (r < 0)
e18a3c73 1879 return r;
8db0d2f5 1880
f91dc240 1881 r = dns_packet_read_uint8(p, &rr->dnskey.protocol, NULL);
8db0d2f5 1882 if (r < 0)
e18a3c73 1883 return r;
8db0d2f5 1884
8db0d2f5
ZJS
1885 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1886 if (r < 0)
e18a3c73 1887 return r;
8db0d2f5 1888
8a0f6d1f
SL
1889 if (rdlength < 4)
1890 return -EBADMSG;
1891
f5430a3e
LP
1892 r = dns_packet_read_memdup(p, rdlength - 4,
1893 &rr->dnskey.key, &rr->dnskey.key_size,
1894 NULL);
f1d178cc 1895
e18a3c73 1896 if (rr->dnskey.key_size <= 0)
f1d178cc
TG
1897 /* the accepted size depends on the algorithm, but for now
1898 just ensure that the value is greater than zero */
e18a3c73 1899 return -EBADMSG;
f1d178cc 1900
42cc2eeb
LP
1901 break;
1902
151226ab
ZJS
1903 case DNS_TYPE_RRSIG:
1904 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1905 if (r < 0)
e18a3c73 1906 return r;
151226ab
ZJS
1907
1908 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1909 if (r < 0)
e18a3c73 1910 return r;
151226ab
ZJS
1911
1912 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1913 if (r < 0)
e18a3c73 1914 return r;
151226ab
ZJS
1915
1916 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1917 if (r < 0)
e18a3c73 1918 return r;
151226ab
ZJS
1919
1920 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1921 if (r < 0)
e18a3c73 1922 return r;
151226ab
ZJS
1923
1924 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1925 if (r < 0)
e18a3c73 1926 return r;
151226ab
ZJS
1927
1928 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1929 if (r < 0)
e18a3c73 1930 return r;
151226ab
ZJS
1931
1932 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1933 if (r < 0)
e18a3c73 1934 return r;
151226ab 1935
8a0f6d1f
SL
1936 if (rdlength + offset < p->rindex)
1937 return -EBADMSG;
1938
f5430a3e
LP
1939 r = dns_packet_read_memdup(p, offset + rdlength - p->rindex,
1940 &rr->rrsig.signature, &rr->rrsig.signature_size,
1941 NULL);
f1d178cc 1942
e18a3c73 1943 if (rr->rrsig.signature_size <= 0)
f1d178cc
TG
1944 /* the accepted size depends on the algorithm, but for now
1945 just ensure that the value is greater than zero */
e18a3c73 1946 return -EBADMSG;
f1d178cc 1947
151226ab
ZJS
1948 break;
1949
d84e543d
DM
1950 case DNS_TYPE_NSEC: {
1951
1952 /*
e5abebab 1953 * RFC6762, section 18.14 explictly states mDNS should use name compression.
d84e543d
DM
1954 * This contradicts RFC3845, section 2.1.1
1955 */
1956
1957 bool allow_compressed = p->protocol == DNS_PROTOCOL_MDNS;
1958
1959 r = dns_packet_read_name(p, &rr->nsec.next_domain_name, allow_compressed, NULL);
50f1e641 1960 if (r < 0)
e18a3c73 1961 return r;
50f1e641 1962
89492aaf 1963 r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL);
89492aaf 1964
09eaf68c
TG
1965 /* We accept empty NSEC bitmaps. The bit indicating the presence of the NSEC record itself
1966 * is redundant and in e.g., RFC4956 this fact is used to define a use for NSEC records
1967 * without the NSEC bit set. */
50f1e641
TG
1968
1969 break;
d84e543d 1970 }
5d45a880
TG
1971 case DNS_TYPE_NSEC3: {
1972 uint8_t size;
1973
1974 r = dns_packet_read_uint8(p, &rr->nsec3.algorithm, NULL);
1975 if (r < 0)
e18a3c73 1976 return r;
5d45a880
TG
1977
1978 r = dns_packet_read_uint8(p, &rr->nsec3.flags, NULL);
1979 if (r < 0)
e18a3c73 1980 return r;
5d45a880
TG
1981
1982 r = dns_packet_read_uint16(p, &rr->nsec3.iterations, NULL);
1983 if (r < 0)
e18a3c73 1984 return r;
5d45a880 1985
f1d178cc 1986 /* this may be zero */
5d45a880
TG
1987 r = dns_packet_read_uint8(p, &size, NULL);
1988 if (r < 0)
e18a3c73 1989 return r;
5d45a880 1990
f5430a3e 1991 r = dns_packet_read_memdup(p, size, &rr->nsec3.salt, &rr->nsec3.salt_size, NULL);
5d45a880 1992 if (r < 0)
e18a3c73 1993 return r;
5d45a880 1994
5d45a880
TG
1995 r = dns_packet_read_uint8(p, &size, NULL);
1996 if (r < 0)
e18a3c73 1997 return r;
5d45a880 1998
e18a3c73
ZJS
1999 if (size <= 0)
2000 return -EBADMSG;
f1d178cc 2001
e18a3c73
ZJS
2002 r = dns_packet_read_memdup(p, size,
2003 &rr->nsec3.next_hashed_name, &rr->nsec3.next_hashed_name_size,
2004 NULL);
5d45a880 2005 if (r < 0)
e18a3c73 2006 return r;
5d45a880 2007
6b9308d1 2008 r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL);
5d45a880 2009
0bbd72b2
TG
2010 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
2011
5d45a880
TG
2012 break;
2013 }
d75acfb0 2014
48d45d2b
ZJS
2015 case DNS_TYPE_TLSA:
2016 r = dns_packet_read_uint8(p, &rr->tlsa.cert_usage, NULL);
2017 if (r < 0)
e18a3c73 2018 return r;
48d45d2b
ZJS
2019
2020 r = dns_packet_read_uint8(p, &rr->tlsa.selector, NULL);
2021 if (r < 0)
e18a3c73 2022 return r;
48d45d2b
ZJS
2023
2024 r = dns_packet_read_uint8(p, &rr->tlsa.matching_type, NULL);
2025 if (r < 0)
e18a3c73 2026 return r;
48d45d2b 2027
8a0f6d1f
SL
2028 if (rdlength < 3)
2029 return -EBADMSG;
2030
48d45d2b
ZJS
2031 r = dns_packet_read_memdup(p, rdlength - 3,
2032 &rr->tlsa.data, &rr->tlsa.data_size,
2033 NULL);
e18a3c73
ZJS
2034
2035 if (rr->tlsa.data_size <= 0)
48d45d2b
ZJS
2036 /* the accepted size depends on the algorithm, but for now
2037 just ensure that the value is greater than zero */
e18a3c73 2038 return -EBADMSG;
48d45d2b
ZJS
2039
2040 break;
2041
95052df3
ZJS
2042 case DNS_TYPE_CAA:
2043 r = dns_packet_read_uint8(p, &rr->caa.flags, NULL);
2044 if (r < 0)
2045 return r;
2046
2047 r = dns_packet_read_string(p, &rr->caa.tag, NULL);
2048 if (r < 0)
2049 return r;
2050
8a0f6d1f
SL
2051 if (rdlength + offset < p->rindex)
2052 return -EBADMSG;
2053
95052df3
ZJS
2054 r = dns_packet_read_memdup(p,
2055 rdlength + offset - p->rindex,
2056 &rr->caa.value, &rr->caa.value_size, NULL);
48d45d2b
ZJS
2057
2058 break;
2059
d75acfb0 2060 case DNS_TYPE_OPT: /* we only care about the header of OPT for now. */
d93a16b8 2061 case DNS_TYPE_OPENPGPKEY:
74b2466e 2062 default:
afbc4f26 2063 unparseable:
a43a068a 2064 r = dns_packet_read_memdup(p, rdlength, &rr->generic.data, &rr->generic.data_size, NULL);
e18a3c73 2065
74b2466e
LP
2066 break;
2067 }
2068 if (r < 0)
e18a3c73
ZJS
2069 return r;
2070 if (p->rindex != offset + rdlength)
2071 return -EBADMSG;
74b2466e 2072
1cc6c93a 2073 *ret = TAKE_PTR(rr);
74b2466e 2074
d2579eec
LP
2075 if (ret_cache_flush)
2076 *ret_cache_flush = cache_flush;
74b2466e 2077 if (start)
e18a3c73
ZJS
2078 *start = rewinder.saved_rindex;
2079 CANCEL_REWINDER(rewinder);
74b2466e
LP
2080
2081 return 0;
74b2466e
LP
2082}
2083
c3f7000e
LP
2084static bool opt_is_good(DnsResourceRecord *rr, bool *rfc6975) {
2085 const uint8_t* p;
2086 bool found_dau_dhu_n3u = false;
2087 size_t l;
2088
2089 /* Checks whether the specified OPT RR is well-formed and whether it contains RFC6975 data (which is not OK in
2090 * a reply). */
2091
2092 assert(rr);
2093 assert(rr->key->type == DNS_TYPE_OPT);
2094
2095 /* Check that the version is 0 */
b30bf55d
LP
2096 if (((rr->ttl >> 16) & UINT32_C(0xFF)) != 0) {
2097 *rfc6975 = false;
2098 return true; /* if it's not version 0, it's OK, but we will ignore the OPT field contents */
2099 }
c3f7000e
LP
2100
2101 p = rr->opt.data;
a43a068a 2102 l = rr->opt.data_size;
c3f7000e
LP
2103 while (l > 0) {
2104 uint16_t option_code, option_length;
2105
2106 /* At least four bytes for OPTION-CODE and OPTION-LENGTH are required */
2107 if (l < 4U)
2108 return false;
2109
2110 option_code = unaligned_read_be16(p);
2111 option_length = unaligned_read_be16(p + 2);
2112
2113 if (l < option_length + 4U)
2114 return false;
2115
2116 /* RFC 6975 DAU, DHU or N3U fields found. */
2117 if (IN_SET(option_code, 5, 6, 7))
2118 found_dau_dhu_n3u = true;
2119
2120 p += option_length + 4U;
2121 l -= option_length + 4U;
2122 }
2123
2124 *rfc6975 = found_dau_dhu_n3u;
2125 return true;
2126}
2127
4a49e560 2128static int dns_packet_extract_question(DnsPacket *p, DnsQuestion **ret_question) {
faa133f3 2129 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
faa133f3 2130 unsigned n, i;
74b2466e
LP
2131 int r;
2132
3cb10d3a 2133 n = DNS_PACKET_QDCOUNT(p);
faa133f3
LP
2134 if (n > 0) {
2135 question = dns_question_new(n);
e18a3c73
ZJS
2136 if (!question)
2137 return -ENOMEM;
74b2466e 2138
faa133f3
LP
2139 for (i = 0; i < n; i++) {
2140 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
d2579eec 2141 bool cache_flush;
74b2466e 2142
d2579eec 2143 r = dns_packet_read_key(p, &key, &cache_flush, NULL);
faa133f3 2144 if (r < 0)
e18a3c73 2145 return r;
74b2466e 2146
e18a3c73
ZJS
2147 if (cache_flush)
2148 return -EBADMSG;
d2579eec 2149
e18a3c73
ZJS
2150 if (!dns_type_is_valid_query(key->type))
2151 return -EBADMSG;
c463eb78 2152
faa133f3
LP
2153 r = dns_question_add(question, key);
2154 if (r < 0)
e18a3c73 2155 return r;
faa133f3
LP
2156 }
2157 }
322345fd 2158
1cc6c93a
YW
2159 *ret_question = TAKE_PTR(question);
2160
4a49e560
ZJS
2161 return 0;
2162}
2163
2164static int dns_packet_extract_answer(DnsPacket *p, DnsAnswer **ret_answer) {
2165 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
2166 unsigned n, i;
2167 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *previous = NULL;
2168 bool bad_opt = false;
2169 int r;
2170
faa133f3 2171 n = DNS_PACKET_RRCOUNT(p);
4a49e560
ZJS
2172 if (n == 0)
2173 return 0;
c3f7000e 2174
4a49e560
ZJS
2175 answer = dns_answer_new(n);
2176 if (!answer)
2177 return -ENOMEM;
322345fd 2178
4a49e560
ZJS
2179 for (i = 0; i < n; i++) {
2180 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
2181 bool cache_flush = false;
322345fd 2182
4a49e560
ZJS
2183 r = dns_packet_read_rr(p, &rr, &cache_flush, NULL);
2184 if (r < 0)
2185 return r;
322345fd 2186
4a49e560
ZJS
2187 /* Try to reduce memory usage a bit */
2188 if (previous)
2189 dns_resource_key_reduce(&rr->key, &previous->key);
f57e3cd5 2190
4a49e560
ZJS
2191 if (rr->key->type == DNS_TYPE_OPT) {
2192 bool has_rfc6975;
c3f7000e 2193
4a49e560
ZJS
2194 if (p->opt || bad_opt) {
2195 /* Multiple OPT RRs? if so, let's ignore all, because there's
2196 * something wrong with the server, and if one is valid we wouldn't
2197 * know which one. */
2198 log_debug("Multiple OPT RRs detected, ignoring all.");
2199 bad_opt = true;
2200 continue;
2201 }
e6b57b37 2202
4a49e560
ZJS
2203 if (!dns_name_is_root(dns_resource_key_name(rr->key))) {
2204 /* If the OPT RR is not owned by the root domain, then it is bad,
2205 * let's ignore it. */
2206 log_debug("OPT RR is not owned by root domain, ignoring.");
2207 bad_opt = true;
2208 continue;
2209 }
c3f7000e 2210
4a49e560
ZJS
2211 if (i < DNS_PACKET_ANCOUNT(p) + DNS_PACKET_NSCOUNT(p)) {
2212 /* OPT RR is in the wrong section? Some Belkin routers do this. This
2213 * is a hint the EDNS implementation is borked, like the Belkin one
2214 * is, hence ignore it. */
2215 log_debug("OPT RR in wrong section, ignoring.");
2216 bad_opt = true;
2217 continue;
2218 }
2219
2220 if (!opt_is_good(rr, &has_rfc6975)) {
2221 log_debug("Malformed OPT RR, ignoring.");
2222 bad_opt = true;
2223 continue;
2224 }
2225
2226 if (DNS_PACKET_QR(p)) {
2227 /* Additional checks for responses */
2228
2229 if (!DNS_RESOURCE_RECORD_OPT_VERSION_SUPPORTED(rr)) {
2230 /* If this is a reply and we don't know the EDNS version
2231 * then something is weird... */
2232 log_debug("EDNS version newer that our request, bad server.");
2233 return -EBADMSG;
ff7febd5
LP
2234 }
2235
4a49e560
ZJS
2236 if (has_rfc6975) {
2237 /* If the OPT RR contains RFC6975 algorithm data, then this
2238 * is indication that the server just copied the OPT it got
2239 * from us (which contained that data) back into the reply.
2240 * If so, then it doesn't properly support EDNS, as RFC6975
2241 * makes it very clear that the algorithm data should only
2242 * be contained in questions, never in replies. Crappy
2243 * Belkin routers copy the OPT data for example, hence let's
2244 * detect this so that we downgrade early. */
2245 log_debug("OPT RR contained RFC6975 data, ignoring.");
c3f7000e
LP
2246 bad_opt = true;
2247 continue;
2248 }
4a49e560 2249 }
e6b57b37 2250
4a49e560
ZJS
2251 p->opt = dns_resource_record_ref(rr);
2252 } else {
2253 /* According to RFC 4795, section 2.9. only the RRs from the Answer section
2254 * shall be cached. Hence mark only those RRs as cacheable by default, but
2255 * not the ones from the Additional or Authority sections. */
2256 DnsAnswerFlags flags =
2257 (i < DNS_PACKET_ANCOUNT(p) ? DNS_ANSWER_CACHEABLE : 0) |
2258 (p->protocol == DNS_PROTOCOL_MDNS && !cache_flush ? DNS_ANSWER_SHARED_OWNER : 0);
2259
2260 r = dns_answer_add(answer, rr, p->ifindex, flags);
2261 if (r < 0)
2262 return r;
2263 }
d75acfb0 2264
4a49e560
ZJS
2265 /* Remember this RR, so that we potentically can merge it's ->key object with the
2266 * next RR. Note that we only do this if we actually decided to keep the RR around.
2267 */
2268 dns_resource_record_unref(previous);
2269 previous = dns_resource_record_ref(rr);
2270 }
105e1512 2271
4a49e560
ZJS
2272 if (bad_opt)
2273 p->opt = dns_resource_record_unref(p->opt);
105e1512 2274
1cc6c93a
YW
2275 *ret_answer = TAKE_PTR(answer);
2276
4a49e560
ZJS
2277 return 0;
2278}
ebc8a106 2279
4a49e560
ZJS
2280int dns_packet_extract(DnsPacket *p) {
2281 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
2282 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
2283 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = {};
2284 int r;
c3f7000e 2285
4a49e560
ZJS
2286 if (p->extracted)
2287 return 0;
2288
2289 INIT_REWINDER(rewinder, p);
2290 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
2291
2292 r = dns_packet_extract_question(p, &question);
2293 if (r < 0)
2294 return r;
2295
2296 r = dns_packet_extract_answer(p, &answer);
2297 if (r < 0)
2298 return r;
322345fd 2299
1cc6c93a
YW
2300 p->question = TAKE_PTR(question);
2301 p->answer = TAKE_PTR(answer);
322345fd 2302
a4076574
LP
2303 p->extracted = true;
2304
e18a3c73
ZJS
2305 /* no CANCEL, always rewind */
2306 return 0;
322345fd
LP
2307}
2308
8af5b883
LP
2309int dns_packet_is_reply_for(DnsPacket *p, const DnsResourceKey *key) {
2310 int r;
2311
2312 assert(p);
2313 assert(key);
2314
2315 /* Checks if the specified packet is a reply for the specified
2316 * key and the specified key is the only one in the question
2317 * section. */
2318
2319 if (DNS_PACKET_QR(p) != 1)
2320 return 0;
2321
2322 /* Let's unpack the packet, if that hasn't happened yet. */
2323 r = dns_packet_extract(p);
2324 if (r < 0)
2325 return r;
2326
a924f43f
EV
2327 if (!p->question)
2328 return 0;
2329
8af5b883
LP
2330 if (p->question->n_keys != 1)
2331 return 0;
2332
2333 return dns_resource_key_equal(p->question->keys[0], key);
2334}
2335
74b2466e
LP
2336static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
2337 [DNS_RCODE_SUCCESS] = "SUCCESS",
2338 [DNS_RCODE_FORMERR] = "FORMERR",
2339 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
2340 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
2341 [DNS_RCODE_NOTIMP] = "NOTIMP",
2342 [DNS_RCODE_REFUSED] = "REFUSED",
2343 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
2344 [DNS_RCODE_YXRRSET] = "YRRSET",
2345 [DNS_RCODE_NXRRSET] = "NXRRSET",
2346 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
2347 [DNS_RCODE_NOTZONE] = "NOTZONE",
2348 [DNS_RCODE_BADVERS] = "BADVERS",
2349 [DNS_RCODE_BADKEY] = "BADKEY",
2350 [DNS_RCODE_BADTIME] = "BADTIME",
2351 [DNS_RCODE_BADMODE] = "BADMODE",
2352 [DNS_RCODE_BADNAME] = "BADNAME",
2353 [DNS_RCODE_BADALG] = "BADALG",
2354 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
6f21e066 2355 [DNS_RCODE_BADCOOKIE] = "BADCOOKIE",
74b2466e
LP
2356};
2357DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1716f6dc
LP
2358
2359static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
2360 [DNS_PROTOCOL_DNS] = "dns",
2361 [DNS_PROTOCOL_MDNS] = "mdns",
2362 [DNS_PROTOCOL_LLMNR] = "llmnr",
2363};
2364DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);