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