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