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