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