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