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