]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-packet.c
Merge pull request #7971 from poettering/dev-node-fixes
[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
8a0f6d1f
SL
1840 if (rdlength < 4)
1841 return -EBADMSG;
1842
f5430a3e
LP
1843 r = dns_packet_read_memdup(p, rdlength - 4,
1844 &rr->ds.digest, &rr->ds.digest_size,
1845 NULL);
abf126a3 1846 if (r < 0)
e18a3c73 1847 return r;
abf126a3 1848
e18a3c73 1849 if (rr->ds.digest_size <= 0)
f1d178cc
TG
1850 /* the accepted size depends on the algorithm, but for now
1851 just ensure that the value is greater than zero */
e18a3c73 1852 return -EBADMSG;
f1d178cc 1853
abf126a3 1854 break;
d75acfb0 1855
623a4c97 1856 case DNS_TYPE_SSHFP:
42cc2eeb
LP
1857 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1858 if (r < 0)
e18a3c73 1859 return r;
42cc2eeb
LP
1860
1861 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1862 if (r < 0)
e18a3c73 1863 return r;
42cc2eeb 1864
8a0f6d1f
SL
1865 if (rdlength < 2)
1866 return -EBADMSG;
1867
f5430a3e 1868 r = dns_packet_read_memdup(p, rdlength - 2,
549c1a25 1869 &rr->sshfp.fingerprint, &rr->sshfp.fingerprint_size,
f5430a3e 1870 NULL);
f1d178cc 1871
e18a3c73 1872 if (rr->sshfp.fingerprint_size <= 0)
f1d178cc
TG
1873 /* the accepted size depends on the algorithm, but for now
1874 just ensure that the value is greater than zero */
e18a3c73 1875 return -EBADMSG;
f1d178cc 1876
8db0d2f5
ZJS
1877 break;
1878
f91dc240
LP
1879 case DNS_TYPE_DNSKEY:
1880 r = dns_packet_read_uint16(p, &rr->dnskey.flags, NULL);
8db0d2f5 1881 if (r < 0)
e18a3c73 1882 return r;
8db0d2f5 1883
f91dc240 1884 r = dns_packet_read_uint8(p, &rr->dnskey.protocol, NULL);
8db0d2f5 1885 if (r < 0)
e18a3c73 1886 return r;
8db0d2f5 1887
8db0d2f5
ZJS
1888 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1889 if (r < 0)
e18a3c73 1890 return r;
8db0d2f5 1891
8a0f6d1f
SL
1892 if (rdlength < 4)
1893 return -EBADMSG;
1894
f5430a3e
LP
1895 r = dns_packet_read_memdup(p, rdlength - 4,
1896 &rr->dnskey.key, &rr->dnskey.key_size,
1897 NULL);
f1d178cc 1898
e18a3c73 1899 if (rr->dnskey.key_size <= 0)
f1d178cc
TG
1900 /* the accepted size depends on the algorithm, but for now
1901 just ensure that the value is greater than zero */
e18a3c73 1902 return -EBADMSG;
f1d178cc 1903
42cc2eeb
LP
1904 break;
1905
151226ab
ZJS
1906 case DNS_TYPE_RRSIG:
1907 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1908 if (r < 0)
e18a3c73 1909 return r;
151226ab
ZJS
1910
1911 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1912 if (r < 0)
e18a3c73 1913 return r;
151226ab
ZJS
1914
1915 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1916 if (r < 0)
e18a3c73 1917 return r;
151226ab
ZJS
1918
1919 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1920 if (r < 0)
e18a3c73 1921 return r;
151226ab
ZJS
1922
1923 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1924 if (r < 0)
e18a3c73 1925 return r;
151226ab
ZJS
1926
1927 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1928 if (r < 0)
e18a3c73 1929 return r;
151226ab
ZJS
1930
1931 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1932 if (r < 0)
e18a3c73 1933 return r;
151226ab
ZJS
1934
1935 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1936 if (r < 0)
e18a3c73 1937 return r;
151226ab 1938
8a0f6d1f
SL
1939 if (rdlength + offset < p->rindex)
1940 return -EBADMSG;
1941
f5430a3e
LP
1942 r = dns_packet_read_memdup(p, offset + rdlength - p->rindex,
1943 &rr->rrsig.signature, &rr->rrsig.signature_size,
1944 NULL);
f1d178cc 1945
e18a3c73 1946 if (rr->rrsig.signature_size <= 0)
f1d178cc
TG
1947 /* the accepted size depends on the algorithm, but for now
1948 just ensure that the value is greater than zero */
e18a3c73 1949 return -EBADMSG;
f1d178cc 1950
151226ab
ZJS
1951 break;
1952
d84e543d
DM
1953 case DNS_TYPE_NSEC: {
1954
1955 /*
e5abebab 1956 * RFC6762, section 18.14 explictly states mDNS should use name compression.
d84e543d
DM
1957 * This contradicts RFC3845, section 2.1.1
1958 */
1959
1960 bool allow_compressed = p->protocol == DNS_PROTOCOL_MDNS;
1961
1962 r = dns_packet_read_name(p, &rr->nsec.next_domain_name, allow_compressed, NULL);
50f1e641 1963 if (r < 0)
e18a3c73 1964 return r;
50f1e641 1965
89492aaf 1966 r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL);
89492aaf 1967
09eaf68c
TG
1968 /* We accept empty NSEC bitmaps. The bit indicating the presence of the NSEC record itself
1969 * is redundant and in e.g., RFC4956 this fact is used to define a use for NSEC records
1970 * without the NSEC bit set. */
50f1e641
TG
1971
1972 break;
d84e543d 1973 }
5d45a880
TG
1974 case DNS_TYPE_NSEC3: {
1975 uint8_t size;
1976
1977 r = dns_packet_read_uint8(p, &rr->nsec3.algorithm, NULL);
1978 if (r < 0)
e18a3c73 1979 return r;
5d45a880
TG
1980
1981 r = dns_packet_read_uint8(p, &rr->nsec3.flags, NULL);
1982 if (r < 0)
e18a3c73 1983 return r;
5d45a880
TG
1984
1985 r = dns_packet_read_uint16(p, &rr->nsec3.iterations, NULL);
1986 if (r < 0)
e18a3c73 1987 return r;
5d45a880 1988
f1d178cc 1989 /* this may be zero */
5d45a880
TG
1990 r = dns_packet_read_uint8(p, &size, NULL);
1991 if (r < 0)
e18a3c73 1992 return r;
5d45a880 1993
f5430a3e 1994 r = dns_packet_read_memdup(p, size, &rr->nsec3.salt, &rr->nsec3.salt_size, NULL);
5d45a880 1995 if (r < 0)
e18a3c73 1996 return r;
5d45a880 1997
5d45a880
TG
1998 r = dns_packet_read_uint8(p, &size, NULL);
1999 if (r < 0)
e18a3c73 2000 return r;
5d45a880 2001
e18a3c73
ZJS
2002 if (size <= 0)
2003 return -EBADMSG;
f1d178cc 2004
e18a3c73
ZJS
2005 r = dns_packet_read_memdup(p, size,
2006 &rr->nsec3.next_hashed_name, &rr->nsec3.next_hashed_name_size,
2007 NULL);
5d45a880 2008 if (r < 0)
e18a3c73 2009 return r;
5d45a880 2010
6b9308d1 2011 r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL);
5d45a880 2012
0bbd72b2
TG
2013 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
2014
5d45a880
TG
2015 break;
2016 }
d75acfb0 2017
48d45d2b
ZJS
2018 case DNS_TYPE_TLSA:
2019 r = dns_packet_read_uint8(p, &rr->tlsa.cert_usage, NULL);
2020 if (r < 0)
e18a3c73 2021 return r;
48d45d2b
ZJS
2022
2023 r = dns_packet_read_uint8(p, &rr->tlsa.selector, NULL);
2024 if (r < 0)
e18a3c73 2025 return r;
48d45d2b
ZJS
2026
2027 r = dns_packet_read_uint8(p, &rr->tlsa.matching_type, NULL);
2028 if (r < 0)
e18a3c73 2029 return r;
48d45d2b 2030
8a0f6d1f
SL
2031 if (rdlength < 3)
2032 return -EBADMSG;
2033
48d45d2b
ZJS
2034 r = dns_packet_read_memdup(p, rdlength - 3,
2035 &rr->tlsa.data, &rr->tlsa.data_size,
2036 NULL);
e18a3c73
ZJS
2037
2038 if (rr->tlsa.data_size <= 0)
48d45d2b
ZJS
2039 /* the accepted size depends on the algorithm, but for now
2040 just ensure that the value is greater than zero */
e18a3c73 2041 return -EBADMSG;
48d45d2b
ZJS
2042
2043 break;
2044
95052df3
ZJS
2045 case DNS_TYPE_CAA:
2046 r = dns_packet_read_uint8(p, &rr->caa.flags, NULL);
2047 if (r < 0)
2048 return r;
2049
2050 r = dns_packet_read_string(p, &rr->caa.tag, NULL);
2051 if (r < 0)
2052 return r;
2053
8a0f6d1f
SL
2054 if (rdlength + offset < p->rindex)
2055 return -EBADMSG;
2056
95052df3
ZJS
2057 r = dns_packet_read_memdup(p,
2058 rdlength + offset - p->rindex,
2059 &rr->caa.value, &rr->caa.value_size, NULL);
48d45d2b
ZJS
2060
2061 break;
2062
d75acfb0 2063 case DNS_TYPE_OPT: /* we only care about the header of OPT for now. */
d93a16b8 2064 case DNS_TYPE_OPENPGPKEY:
74b2466e 2065 default:
afbc4f26 2066 unparseable:
a43a068a 2067 r = dns_packet_read_memdup(p, rdlength, &rr->generic.data, &rr->generic.data_size, NULL);
e18a3c73 2068
74b2466e
LP
2069 break;
2070 }
2071 if (r < 0)
e18a3c73
ZJS
2072 return r;
2073 if (p->rindex != offset + rdlength)
2074 return -EBADMSG;
74b2466e
LP
2075
2076 *ret = rr;
2077 rr = NULL;
2078
d2579eec
LP
2079 if (ret_cache_flush)
2080 *ret_cache_flush = cache_flush;
74b2466e 2081 if (start)
e18a3c73
ZJS
2082 *start = rewinder.saved_rindex;
2083 CANCEL_REWINDER(rewinder);
74b2466e
LP
2084
2085 return 0;
74b2466e
LP
2086}
2087
c3f7000e
LP
2088static bool opt_is_good(DnsResourceRecord *rr, bool *rfc6975) {
2089 const uint8_t* p;
2090 bool found_dau_dhu_n3u = false;
2091 size_t l;
2092
2093 /* Checks whether the specified OPT RR is well-formed and whether it contains RFC6975 data (which is not OK in
2094 * a reply). */
2095
2096 assert(rr);
2097 assert(rr->key->type == DNS_TYPE_OPT);
2098
2099 /* Check that the version is 0 */
b30bf55d
LP
2100 if (((rr->ttl >> 16) & UINT32_C(0xFF)) != 0) {
2101 *rfc6975 = false;
2102 return true; /* if it's not version 0, it's OK, but we will ignore the OPT field contents */
2103 }
c3f7000e
LP
2104
2105 p = rr->opt.data;
a43a068a 2106 l = rr->opt.data_size;
c3f7000e
LP
2107 while (l > 0) {
2108 uint16_t option_code, option_length;
2109
2110 /* At least four bytes for OPTION-CODE and OPTION-LENGTH are required */
2111 if (l < 4U)
2112 return false;
2113
2114 option_code = unaligned_read_be16(p);
2115 option_length = unaligned_read_be16(p + 2);
2116
2117 if (l < option_length + 4U)
2118 return false;
2119
2120 /* RFC 6975 DAU, DHU or N3U fields found. */
2121 if (IN_SET(option_code, 5, 6, 7))
2122 found_dau_dhu_n3u = true;
2123
2124 p += option_length + 4U;
2125 l -= option_length + 4U;
2126 }
2127
2128 *rfc6975 = found_dau_dhu_n3u;
2129 return true;
2130}
2131
4a49e560 2132static int dns_packet_extract_question(DnsPacket *p, DnsQuestion **ret_question) {
faa133f3 2133 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
faa133f3 2134 unsigned n, i;
74b2466e
LP
2135 int r;
2136
3cb10d3a 2137 n = DNS_PACKET_QDCOUNT(p);
faa133f3
LP
2138 if (n > 0) {
2139 question = dns_question_new(n);
e18a3c73
ZJS
2140 if (!question)
2141 return -ENOMEM;
74b2466e 2142
faa133f3
LP
2143 for (i = 0; i < n; i++) {
2144 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
d2579eec 2145 bool cache_flush;
74b2466e 2146
d2579eec 2147 r = dns_packet_read_key(p, &key, &cache_flush, NULL);
faa133f3 2148 if (r < 0)
e18a3c73 2149 return r;
74b2466e 2150
e18a3c73
ZJS
2151 if (cache_flush)
2152 return -EBADMSG;
d2579eec 2153
e18a3c73
ZJS
2154 if (!dns_type_is_valid_query(key->type))
2155 return -EBADMSG;
c463eb78 2156
faa133f3
LP
2157 r = dns_question_add(question, key);
2158 if (r < 0)
e18a3c73 2159 return r;
faa133f3
LP
2160 }
2161 }
322345fd 2162
4a49e560
ZJS
2163 *ret_question = question;
2164 question = NULL;
2165 return 0;
2166}
2167
2168static int dns_packet_extract_answer(DnsPacket *p, DnsAnswer **ret_answer) {
2169 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
2170 unsigned n, i;
2171 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *previous = NULL;
2172 bool bad_opt = false;
2173 int r;
2174
faa133f3 2175 n = DNS_PACKET_RRCOUNT(p);
4a49e560
ZJS
2176 if (n == 0)
2177 return 0;
c3f7000e 2178
4a49e560
ZJS
2179 answer = dns_answer_new(n);
2180 if (!answer)
2181 return -ENOMEM;
322345fd 2182
4a49e560
ZJS
2183 for (i = 0; i < n; i++) {
2184 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
2185 bool cache_flush = false;
322345fd 2186
4a49e560
ZJS
2187 r = dns_packet_read_rr(p, &rr, &cache_flush, NULL);
2188 if (r < 0)
2189 return r;
322345fd 2190
4a49e560
ZJS
2191 /* Try to reduce memory usage a bit */
2192 if (previous)
2193 dns_resource_key_reduce(&rr->key, &previous->key);
f57e3cd5 2194
4a49e560
ZJS
2195 if (rr->key->type == DNS_TYPE_OPT) {
2196 bool has_rfc6975;
c3f7000e 2197
4a49e560
ZJS
2198 if (p->opt || bad_opt) {
2199 /* Multiple OPT RRs? if so, let's ignore all, because there's
2200 * something wrong with the server, and if one is valid we wouldn't
2201 * know which one. */
2202 log_debug("Multiple OPT RRs detected, ignoring all.");
2203 bad_opt = true;
2204 continue;
2205 }
e6b57b37 2206
4a49e560
ZJS
2207 if (!dns_name_is_root(dns_resource_key_name(rr->key))) {
2208 /* If the OPT RR is not owned by the root domain, then it is bad,
2209 * let's ignore it. */
2210 log_debug("OPT RR is not owned by root domain, ignoring.");
2211 bad_opt = true;
2212 continue;
2213 }
c3f7000e 2214
4a49e560
ZJS
2215 if (i < DNS_PACKET_ANCOUNT(p) + DNS_PACKET_NSCOUNT(p)) {
2216 /* OPT RR is in the wrong section? Some Belkin routers do this. This
2217 * is a hint the EDNS implementation is borked, like the Belkin one
2218 * is, hence ignore it. */
2219 log_debug("OPT RR in wrong section, ignoring.");
2220 bad_opt = true;
2221 continue;
2222 }
2223
2224 if (!opt_is_good(rr, &has_rfc6975)) {
2225 log_debug("Malformed OPT RR, ignoring.");
2226 bad_opt = true;
2227 continue;
2228 }
2229
2230 if (DNS_PACKET_QR(p)) {
2231 /* Additional checks for responses */
2232
2233 if (!DNS_RESOURCE_RECORD_OPT_VERSION_SUPPORTED(rr)) {
2234 /* If this is a reply and we don't know the EDNS version
2235 * then something is weird... */
2236 log_debug("EDNS version newer that our request, bad server.");
2237 return -EBADMSG;
ff7febd5
LP
2238 }
2239
4a49e560
ZJS
2240 if (has_rfc6975) {
2241 /* If the OPT RR contains RFC6975 algorithm data, then this
2242 * is indication that the server just copied the OPT it got
2243 * from us (which contained that data) back into the reply.
2244 * If so, then it doesn't properly support EDNS, as RFC6975
2245 * makes it very clear that the algorithm data should only
2246 * be contained in questions, never in replies. Crappy
2247 * Belkin routers copy the OPT data for example, hence let's
2248 * detect this so that we downgrade early. */
2249 log_debug("OPT RR contained RFC6975 data, ignoring.");
c3f7000e
LP
2250 bad_opt = true;
2251 continue;
2252 }
4a49e560 2253 }
e6b57b37 2254
4a49e560
ZJS
2255 p->opt = dns_resource_record_ref(rr);
2256 } else {
2257 /* According to RFC 4795, section 2.9. only the RRs from the Answer section
2258 * shall be cached. Hence mark only those RRs as cacheable by default, but
2259 * not the ones from the Additional or Authority sections. */
2260 DnsAnswerFlags flags =
2261 (i < DNS_PACKET_ANCOUNT(p) ? DNS_ANSWER_CACHEABLE : 0) |
2262 (p->protocol == DNS_PROTOCOL_MDNS && !cache_flush ? DNS_ANSWER_SHARED_OWNER : 0);
2263
2264 r = dns_answer_add(answer, rr, p->ifindex, flags);
2265 if (r < 0)
2266 return r;
2267 }
d75acfb0 2268
4a49e560
ZJS
2269 /* Remember this RR, so that we potentically can merge it's ->key object with the
2270 * next RR. Note that we only do this if we actually decided to keep the RR around.
2271 */
2272 dns_resource_record_unref(previous);
2273 previous = dns_resource_record_ref(rr);
2274 }
105e1512 2275
4a49e560
ZJS
2276 if (bad_opt)
2277 p->opt = dns_resource_record_unref(p->opt);
105e1512 2278
4a49e560
ZJS
2279 *ret_answer = answer;
2280 answer = NULL;
2281 return 0;
2282}
ebc8a106 2283
4a49e560
ZJS
2284int dns_packet_extract(DnsPacket *p) {
2285 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
2286 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
2287 _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = {};
2288 int r;
c3f7000e 2289
4a49e560
ZJS
2290 if (p->extracted)
2291 return 0;
2292
2293 INIT_REWINDER(rewinder, p);
2294 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
2295
2296 r = dns_packet_extract_question(p, &question);
2297 if (r < 0)
2298 return r;
2299
2300 r = dns_packet_extract_answer(p, &answer);
2301 if (r < 0)
2302 return r;
322345fd 2303
faa133f3
LP
2304 p->question = question;
2305 question = NULL;
322345fd 2306
faa133f3
LP
2307 p->answer = answer;
2308 answer = NULL;
322345fd 2309
a4076574
LP
2310 p->extracted = true;
2311
e18a3c73
ZJS
2312 /* no CANCEL, always rewind */
2313 return 0;
322345fd
LP
2314}
2315
8af5b883
LP
2316int dns_packet_is_reply_for(DnsPacket *p, const DnsResourceKey *key) {
2317 int r;
2318
2319 assert(p);
2320 assert(key);
2321
2322 /* Checks if the specified packet is a reply for the specified
2323 * key and the specified key is the only one in the question
2324 * section. */
2325
2326 if (DNS_PACKET_QR(p) != 1)
2327 return 0;
2328
2329 /* Let's unpack the packet, if that hasn't happened yet. */
2330 r = dns_packet_extract(p);
2331 if (r < 0)
2332 return r;
2333
a924f43f
EV
2334 if (!p->question)
2335 return 0;
2336
8af5b883
LP
2337 if (p->question->n_keys != 1)
2338 return 0;
2339
2340 return dns_resource_key_equal(p->question->keys[0], key);
2341}
2342
74b2466e
LP
2343static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
2344 [DNS_RCODE_SUCCESS] = "SUCCESS",
2345 [DNS_RCODE_FORMERR] = "FORMERR",
2346 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
2347 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
2348 [DNS_RCODE_NOTIMP] = "NOTIMP",
2349 [DNS_RCODE_REFUSED] = "REFUSED",
2350 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
2351 [DNS_RCODE_YXRRSET] = "YRRSET",
2352 [DNS_RCODE_NXRRSET] = "NXRRSET",
2353 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
2354 [DNS_RCODE_NOTZONE] = "NOTZONE",
2355 [DNS_RCODE_BADVERS] = "BADVERS",
2356 [DNS_RCODE_BADKEY] = "BADKEY",
2357 [DNS_RCODE_BADTIME] = "BADTIME",
2358 [DNS_RCODE_BADMODE] = "BADMODE",
2359 [DNS_RCODE_BADNAME] = "BADNAME",
2360 [DNS_RCODE_BADALG] = "BADALG",
2361 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
6f21e066 2362 [DNS_RCODE_BADCOOKIE] = "BADCOOKIE",
74b2466e
LP
2363};
2364DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1716f6dc
LP
2365
2366static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
2367 [DNS_PROTOCOL_DNS] = "dns",
2368 [DNS_PROTOCOL_MDNS] = "mdns",
2369 [DNS_PROTOCOL_LLMNR] = "llmnr",
2370};
2371DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);