]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-packet.c
resolved: add RFC 5702 defined DNSSEC algorithms to table
[thirdparty/systemd.git] / src / resolve / resolved-dns-packet.c
CommitLineData
74b2466e
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
b5efdb8a 22#include "alloc-util.h"
4ad7f276 23#include "dns-domain.h"
74b2466e 24#include "resolved-dns-packet.h"
8b43440b
LP
25#include "string-table.h"
26#include "strv.h"
27#include "unaligned.h"
28#include "utf8.h"
29#include "util.h"
74b2466e 30
7586f4d1
TG
31#define EDNS0_OPT_DO (1<<15)
32
1716f6dc 33int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
74b2466e
LP
34 DnsPacket *p;
35 size_t a;
36
37 assert(ret);
38
a0166609 39 if (mtu <= UDP_PACKET_HEADER_SIZE)
74b2466e
LP
40 a = DNS_PACKET_SIZE_START;
41 else
a0166609 42 a = mtu - UDP_PACKET_HEADER_SIZE;
74b2466e
LP
43
44 if (a < DNS_PACKET_HEADER_SIZE)
45 a = DNS_PACKET_HEADER_SIZE;
46
c73ce96b
LP
47 /* round up to next page size */
48 a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
49
50 /* make sure we never allocate more than useful */
51 if (a > DNS_PACKET_SIZE_MAX)
52 a = DNS_PACKET_SIZE_MAX;
53
74b2466e
LP
54 p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
55 if (!p)
56 return -ENOMEM;
57
58 p->size = p->rindex = DNS_PACKET_HEADER_SIZE;
59 p->allocated = a;
1716f6dc 60 p->protocol = protocol;
74b2466e
LP
61 p->n_ref = 1;
62
63 *ret = p;
64
65 return 0;
66}
67
1716f6dc 68int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
74b2466e
LP
69 DnsPacket *p;
70 DnsPacketHeader *h;
069360a6 71 int r;
74b2466e
LP
72
73 assert(ret);
74
1716f6dc 75 r = dns_packet_new(&p, protocol, mtu);
74b2466e
LP
76 if (r < 0)
77 return r;
78
79 h = DNS_PACKET_HEADER(p);
1716f6dc 80
069360a6
LP
81 if (protocol == DNS_PROTOCOL_LLMNR)
82 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
83 0 /* opcode */,
84 0 /* c */,
85 0 /* tc */,
86 0 /* t */,
87 0 /* ra */,
88 0 /* ad */,
89 0 /* cd */,
90 0 /* rcode */));
91 else
92 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
93 0 /* opcode */,
94 0 /* aa */,
95 0 /* tc */,
96 1 /* rd (ask for recursion) */,
97 0 /* ra */,
98 0 /* ad */,
99 0 /* cd */,
100 0 /* rcode */));
74b2466e
LP
101
102 *ret = p;
103 return 0;
104}
105
106DnsPacket *dns_packet_ref(DnsPacket *p) {
107
108 if (!p)
109 return NULL;
110
111 assert(p->n_ref > 0);
112 p->n_ref++;
113 return p;
114}
115
116static void dns_packet_free(DnsPacket *p) {
117 char *s;
118
119 assert(p);
120
faa133f3
LP
121 dns_question_unref(p->question);
122 dns_answer_unref(p->answer);
322345fd 123
74b2466e
LP
124 while ((s = hashmap_steal_first_key(p->names)))
125 free(s);
126 hashmap_free(p->names);
127
faa133f3 128 free(p->_data);
74b2466e
LP
129 free(p);
130}
131
132DnsPacket *dns_packet_unref(DnsPacket *p) {
133 if (!p)
134 return NULL;
135
136 assert(p->n_ref > 0);
137
138 if (p->n_ref == 1)
139 dns_packet_free(p);
140 else
141 p->n_ref--;
142
143 return NULL;
144}
145
146int dns_packet_validate(DnsPacket *p) {
147 assert(p);
148
149 if (p->size < DNS_PACKET_HEADER_SIZE)
150 return -EBADMSG;
151
c73ce96b
LP
152 if (p->size > DNS_PACKET_SIZE_MAX)
153 return -EBADMSG;
154
623a4c97 155 return 1;
74b2466e
LP
156}
157
158int dns_packet_validate_reply(DnsPacket *p) {
74b2466e
LP
159 int r;
160
161 assert(p);
162
163 r = dns_packet_validate(p);
164 if (r < 0)
165 return r;
166
623a4c97
LP
167 if (DNS_PACKET_QR(p) != 1)
168 return 0;
169
170 if (DNS_PACKET_OPCODE(p) != 0)
74b2466e
LP
171 return -EBADMSG;
172
818ef443
DM
173 switch (p->protocol) {
174 case DNS_PROTOCOL_LLMNR:
175 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
176 if (DNS_PACKET_QDCOUNT(p) != 1)
177 return -EBADMSG;
178
179 break;
180
181 default:
182 break;
183 }
ea917db9 184
623a4c97
LP
185 return 1;
186}
187
188int dns_packet_validate_query(DnsPacket *p) {
189 int r;
190
191 assert(p);
192
193 r = dns_packet_validate(p);
194 if (r < 0)
195 return r;
196
197 if (DNS_PACKET_QR(p) != 0)
198 return 0;
199
3cb10d3a 200 if (DNS_PACKET_OPCODE(p) != 0)
74b2466e
LP
201 return -EBADMSG;
202
623a4c97
LP
203 if (DNS_PACKET_TC(p))
204 return -EBADMSG;
205
818ef443
DM
206 switch (p->protocol) {
207 case DNS_PROTOCOL_LLMNR:
208 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
209 if (DNS_PACKET_QDCOUNT(p) != 1)
210 return -EBADMSG;
623a4c97 211
818ef443
DM
212 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
213 if (DNS_PACKET_ANCOUNT(p) > 0)
214 return -EBADMSG;
623a4c97 215
818ef443
DM
216 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
217 if (DNS_PACKET_NSCOUNT(p) > 0)
218 return -EBADMSG;
219
220 break;
221
222 default:
223 break;
224 }
623a4c97
LP
225
226 return 1;
74b2466e
LP
227}
228
229static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
230 assert(p);
231
c73ce96b
LP
232 if (p->size + add > p->allocated) {
233 size_t a;
234
235 a = PAGE_ALIGN((p->size + add) * 2);
236 if (a > DNS_PACKET_SIZE_MAX)
237 a = DNS_PACKET_SIZE_MAX;
238
239 if (p->size + add > a)
240 return -EMSGSIZE;
241
faa133f3 242 if (p->_data) {
c73ce96b
LP
243 void *d;
244
faa133f3 245 d = realloc(p->_data, a);
c73ce96b
LP
246 if (!d)
247 return -ENOMEM;
248
faa133f3 249 p->_data = d;
c73ce96b 250 } else {
faa133f3
LP
251 p->_data = malloc(a);
252 if (!p->_data)
c73ce96b
LP
253 return -ENOMEM;
254
faa133f3
LP
255 memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
256 memzero((uint8_t*) p->_data + p->size, a - p->size);
c73ce96b
LP
257 }
258
259 p->allocated = a;
260 }
74b2466e
LP
261
262 if (start)
263 *start = p->size;
264
265 if (ret)
266 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;
267
268 p->size += add;
269 return 0;
270}
271
9c5e12a4 272void dns_packet_truncate(DnsPacket *p, size_t sz) {
74b2466e
LP
273 Iterator i;
274 char *s;
275 void *n;
276
277 assert(p);
278
279 if (p->size <= sz)
280 return;
281
0e03ade5 282 HASHMAP_FOREACH_KEY(n, s, p->names, i) {
74b2466e
LP
283
284 if (PTR_TO_SIZE(n) < sz)
285 continue;
286
287 hashmap_remove(p->names, s);
288 free(s);
289 }
290
291 p->size = sz;
292}
293
623a4c97
LP
294int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
295 void *q;
296 int r;
297
298 assert(p);
299
300 r = dns_packet_extend(p, l, &q, start);
301 if (r < 0)
302 return r;
303
304 memcpy(q, d, l);
305 return 0;
306}
307
74b2466e
LP
308int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
309 void *d;
310 int r;
311
312 assert(p);
313
314 r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
315 if (r < 0)
316 return r;
317
318 ((uint8_t*) d)[0] = v;
319
320 return 0;
321}
322
323int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
324 void *d;
325 int r;
326
327 assert(p);
328
329 r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
330 if (r < 0)
331 return r;
332
725ca0e5 333 unaligned_write_be16(d, v);
623a4c97
LP
334
335 return 0;
336}
337
338int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start) {
339 void *d;
340 int r;
341
342 assert(p);
343
344 r = dns_packet_extend(p, sizeof(uint32_t), &d, start);
345 if (r < 0)
346 return r;
347
725ca0e5 348 unaligned_write_be32(d, v);
74b2466e
LP
349
350 return 0;
351}
352
353int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
74b2466e
LP
354 assert(p);
355 assert(s);
356
c38a52da 357 return dns_packet_append_raw_string(p, s, strlen(s), start);
74b2466e
LP
358}
359
2001c805
LP
360int dns_packet_append_raw_string(DnsPacket *p, const void *s, size_t size, size_t *start) {
361 void *d;
362 int r;
363
364 assert(p);
365 assert(s || size == 0);
366
367 if (size > 255)
368 return -E2BIG;
369
370 r = dns_packet_extend(p, 1 + size, &d, start);
371 if (r < 0)
372 return r;
373
374 ((uint8_t*) d)[0] = (uint8_t) size;
375
376 if (size > 0)
377 memcpy(((uint8_t*) d) + 1, s, size);
378
379 return 0;
380}
381
74b2466e
LP
382int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start) {
383 void *w;
384 int r;
385
386 assert(p);
387 assert(d);
388
389 if (l > DNS_LABEL_MAX)
390 return -E2BIG;
391
392 r = dns_packet_extend(p, 1 + l, &w, start);
393 if (r < 0)
394 return r;
395
396 ((uint8_t*) w)[0] = (uint8_t) l;
397 memcpy(((uint8_t*) w) + 1, d, l);
398
399 return 0;
400}
401
f6a5fec6
LP
402int dns_packet_append_name(
403 DnsPacket *p,
404 const char *name,
405 bool allow_compression,
406 size_t *start) {
407
74b2466e
LP
408 size_t saved_size;
409 int r;
410
411 assert(p);
412 assert(name);
413
f6a5fec6
LP
414 if (p->refuse_compression)
415 allow_compression = false;
416
74b2466e
LP
417 saved_size = p->size;
418
419 while (*name) {
420 _cleanup_free_ char *s = NULL;
421 char label[DNS_LABEL_MAX];
151226ab 422 size_t n = 0;
bdf10b5b 423 int k;
74b2466e 424
151226ab
ZJS
425 if (allow_compression)
426 n = PTR_TO_SIZE(hashmap_get(p->names, name));
74b2466e
LP
427 if (n > 0) {
428 assert(n < p->size);
429
430 if (n < 0x4000) {
431 r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
432 if (r < 0)
433 goto fail;
434
435 goto done;
436 }
437 }
438
439 s = strdup(name);
440 if (!s) {
441 r = -ENOMEM;
442 goto fail;
443 }
444
445 r = dns_label_unescape(&name, label, sizeof(label));
446 if (r < 0)
447 goto fail;
448
bdf10b5b
LP
449 if (p->protocol == DNS_PROTOCOL_DNS)
450 k = dns_label_apply_idna(label, r, label, sizeof(label));
451 else
452 k = dns_label_undo_idna(label, r, label, sizeof(label));
453 if (k < 0) {
454 r = k;
455 goto fail;
456 }
457 if (k > 0)
458 r = k;
459
74b2466e
LP
460 r = dns_packet_append_label(p, label, r, &n);
461 if (r < 0)
462 goto fail;
463
151226ab 464 if (allow_compression) {
d5099efc 465 r = hashmap_ensure_allocated(&p->names, &dns_name_hash_ops);
151226ab
ZJS
466 if (r < 0)
467 goto fail;
74b2466e 468
151226ab
ZJS
469 r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
470 if (r < 0)
471 goto fail;
74b2466e 472
151226ab
ZJS
473 s = NULL;
474 }
74b2466e
LP
475 }
476
477 r = dns_packet_append_uint8(p, 0, NULL);
478 if (r < 0)
479 return r;
480
481done:
482 if (start)
483 *start = saved_size;
484
485 return 0;
486
487fail:
488 dns_packet_truncate(p, saved_size);
489 return r;
490}
491
492int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
493 size_t saved_size;
494 int r;
495
496 assert(p);
497 assert(k);
498
499 saved_size = p->size;
500
151226ab 501 r = dns_packet_append_name(p, DNS_RESOURCE_KEY_NAME(k), true, NULL);
74b2466e
LP
502 if (r < 0)
503 goto fail;
504
505 r = dns_packet_append_uint16(p, k->type, NULL);
506 if (r < 0)
507 goto fail;
508
509 r = dns_packet_append_uint16(p, k->class, NULL);
510 if (r < 0)
511 goto fail;
512
513 if (start)
514 *start = saved_size;
515
516 return 0;
517
518fail:
519 dns_packet_truncate(p, saved_size);
520 return r;
521}
522
50f1e641
TG
523static int dns_packet_append_type_window(DnsPacket *p, uint8_t window, uint8_t length, uint8_t *types, size_t *start) {
524 size_t saved_size;
525 int r;
526
527 assert(p);
528 assert(types);
1792f223 529 assert(length > 0);
50f1e641 530
50f1e641
TG
531 saved_size = p->size;
532
1792f223
TG
533 r = dns_packet_append_uint8(p, window, NULL);
534 if (r < 0)
535 goto fail;
50f1e641 536
1792f223
TG
537 r = dns_packet_append_uint8(p, length, NULL);
538 if (r < 0)
539 goto fail;
6fa91901 540
1792f223
TG
541 r = dns_packet_append_blob(p, types, length, NULL);
542 if (r < 0)
543 goto fail;
50f1e641
TG
544
545 if (start)
546 *start = saved_size;
547
548 return 0;
549fail:
550 dns_packet_truncate(p, saved_size);
551 return r;
552}
553
554static int dns_packet_append_types(DnsPacket *p, Bitmap *types, size_t *start) {
cb57dd41 555 Iterator i;
50f1e641 556 uint8_t window = 0;
1792f223 557 uint8_t entry = 0;
50f1e641
TG
558 uint8_t bitmaps[32] = {};
559 unsigned n;
560 size_t saved_size;
561 int r;
562
563 assert(p);
564 assert(types);
565
566 saved_size = p->size;
567
cb57dd41 568 BITMAP_FOREACH(n, types, i) {
50f1e641
TG
569 assert(n <= 0xffff);
570
1792f223
TG
571 if ((n >> 8) != window && bitmaps[entry / 8] != 0) {
572 r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
50f1e641
TG
573 if (r < 0)
574 goto fail;
575
1792f223 576 zero(bitmaps);
50f1e641
TG
577 }
578
1792f223 579 window = n >> 8;
50f1e641
TG
580
581 entry = n & 255;
582
583 bitmaps[entry / 8] |= 1 << (7 - (entry % 8));
584 }
585
1792f223 586 r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
50f1e641
TG
587 if (r < 0)
588 goto fail;
589
590 if (start)
591 *start = saved_size;
592
593 return 0;
594fail:
595 dns_packet_truncate(p, saved_size);
596 return r;
597}
598
dc913c9a 599/* Append the OPT pseudo-RR described in RFC6891 */
7586f4d1 600int dns_packet_append_opt_rr(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, size_t *start) {
dc913c9a
TG
601 size_t saved_size;
602 int r;
603
604 assert(p);
605 /* we must never advertise supported packet size smaller than the legacy max */
606 assert(max_udp_size >= DNS_PACKET_UNICAST_SIZE_MAX);
607
608 saved_size = p->size;
609
610 /* empty name */
611 r = dns_packet_append_uint8(p, 0, NULL);
612 if (r < 0)
613 return r;
614
615 /* type */
616 r = dns_packet_append_uint16(p, DNS_TYPE_OPT, NULL);
617 if (r < 0)
618 goto fail;
619
620 /* maximum udp packet that can be received */
621 r = dns_packet_append_uint16(p, max_udp_size, NULL);
622 if (r < 0)
623 goto fail;
624
625 /* extended RCODE and VERSION */
626 r = dns_packet_append_uint16(p, 0, NULL);
627 if (r < 0)
628 goto fail;
629
7586f4d1
TG
630 /* flags: DNSSEC OK (DO), see RFC3225 */
631 r = dns_packet_append_uint16(p, edns0_do ? EDNS0_OPT_DO : 0, NULL);
dc913c9a
TG
632 if (r < 0)
633 goto fail;
634
635 /* RDLENGTH */
636 r = dns_packet_append_uint16(p, 0, NULL);
637 if (r < 0)
638 goto fail;
639
640 if (start)
641 *start = saved_size;
642
643 return 0;
644
645fail:
646 dns_packet_truncate(p, saved_size);
647 return r;
648}
649
623a4c97
LP
650int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start) {
651 size_t saved_size, rdlength_offset, end, rdlength;
652 int r;
653
654 assert(p);
655 assert(rr);
656
657 saved_size = p->size;
658
659 r = dns_packet_append_key(p, rr->key, NULL);
660 if (r < 0)
661 goto fail;
662
663 r = dns_packet_append_uint32(p, rr->ttl, NULL);
664 if (r < 0)
665 goto fail;
666
667 /* Initially we write 0 here */
668 r = dns_packet_append_uint16(p, 0, &rdlength_offset);
669 if (r < 0)
670 goto fail;
671
0dae31d4 672 switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
623a4c97 673
9c92ce6d
LP
674 case DNS_TYPE_SRV:
675 r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
676 if (r < 0)
677 goto fail;
678
679 r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
680 if (r < 0)
681 goto fail;
682
683 r = dns_packet_append_uint16(p, rr->srv.port, NULL);
684 if (r < 0)
685 goto fail;
686
151226ab 687 r = dns_packet_append_name(p, rr->srv.name, true, NULL);
9c92ce6d
LP
688 break;
689
623a4c97
LP
690 case DNS_TYPE_PTR:
691 case DNS_TYPE_NS:
692 case DNS_TYPE_CNAME:
8ac4e9e1 693 case DNS_TYPE_DNAME:
151226ab 694 r = dns_packet_append_name(p, rr->ptr.name, true, NULL);
623a4c97
LP
695 break;
696
697 case DNS_TYPE_HINFO:
698 r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
699 if (r < 0)
700 goto fail;
701
702 r = dns_packet_append_string(p, rr->hinfo.os, NULL);
703 break;
704
9de3e329 705 case DNS_TYPE_SPF: /* exactly the same as TXT */
2001c805 706 case DNS_TYPE_TXT:
2e276efc 707
2001c805 708 if (!rr->txt.items) {
1ccda9b7
LP
709 /* RFC 6763, section 6.1 suggests to generate
710 * single empty string for an empty array. */
711
2001c805 712 r = dns_packet_append_raw_string(p, NULL, 0, NULL);
2e276efc
ZJS
713 if (r < 0)
714 goto fail;
1ccda9b7 715 } else {
2001c805
LP
716 DnsTxtItem *i;
717
718 LIST_FOREACH(items, i, rr->txt.items) {
719 r = dns_packet_append_raw_string(p, i->data, i->length, NULL);
1ccda9b7
LP
720 if (r < 0)
721 goto fail;
722 }
2e276efc
ZJS
723 }
724
6a6fc3df 725 r = 0;
2e276efc 726 break;
2e276efc 727
623a4c97
LP
728 case DNS_TYPE_A:
729 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
730 break;
731
732 case DNS_TYPE_AAAA:
733 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
734 break;
735
736 case DNS_TYPE_SOA:
151226ab 737 r = dns_packet_append_name(p, rr->soa.mname, true, NULL);
623a4c97
LP
738 if (r < 0)
739 goto fail;
740
151226ab 741 r = dns_packet_append_name(p, rr->soa.rname, true, NULL);
623a4c97
LP
742 if (r < 0)
743 goto fail;
744
745 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
746 if (r < 0)
747 goto fail;
748
749 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
750 if (r < 0)
751 goto fail;
752
753 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
754 if (r < 0)
755 goto fail;
756
757 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
758 if (r < 0)
759 goto fail;
760
761 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
762 break;
763
764 case DNS_TYPE_MX:
946c7094
ZJS
765 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
766 if (r < 0)
767 goto fail;
768
151226ab 769 r = dns_packet_append_name(p, rr->mx.exchange, true, NULL);
946c7094
ZJS
770 break;
771
0dae31d4
ZJS
772 case DNS_TYPE_LOC:
773 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
774 if (r < 0)
775 goto fail;
776
777 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
778 if (r < 0)
779 goto fail;
780
781 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
782 if (r < 0)
783 goto fail;
784
785 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
786 if (r < 0)
787 goto fail;
788
afbc4f26 789 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
0dae31d4
ZJS
790 if (r < 0)
791 goto fail;
792
afbc4f26 793 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
0dae31d4
ZJS
794 if (r < 0)
795 goto fail;
796
afbc4f26 797 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
0dae31d4
ZJS
798 break;
799
abf126a3
TG
800 case DNS_TYPE_DS:
801 r = dns_packet_append_uint16(p, rr->ds.key_tag, NULL);
802 if (r < 0)
803 goto fail;
804
805 r = dns_packet_append_uint8(p, rr->ds.algorithm, NULL);
806 if (r < 0)
807 goto fail;
808
809 r = dns_packet_append_uint8(p, rr->ds.digest_type, NULL);
810 if (r < 0)
811 goto fail;
812
813 r = dns_packet_append_blob(p, rr->ds.digest, rr->ds.digest_size, NULL);
814 break;
815
623a4c97 816 case DNS_TYPE_SSHFP:
42cc2eeb
LP
817 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
818 if (r < 0)
819 goto fail;
8db0d2f5 820
42cc2eeb
LP
821 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
822 if (r < 0)
823 goto fail;
824
549c1a25 825 r = dns_packet_append_blob(p, rr->sshfp.fingerprint, rr->sshfp.fingerprint_size, NULL);
42cc2eeb
LP
826 break;
827
8db0d2f5
ZJS
828 case DNS_TYPE_DNSKEY:
829 r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
830 if (r < 0)
831 goto fail;
832
833 r = dns_packet_append_uint8(p, 3u, NULL);
834 if (r < 0)
835 goto fail;
836
837 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
838 if (r < 0)
839 goto fail;
840
841 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
842 break;
843
151226ab
ZJS
844 case DNS_TYPE_RRSIG:
845 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
846 if (r < 0)
847 goto fail;
848
849 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
850 if (r < 0)
851 goto fail;
852
853 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
854 if (r < 0)
855 goto fail;
856
857 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
858 if (r < 0)
859 goto fail;
860
861 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
862 if (r < 0)
863 goto fail;
864
865 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
866 if (r < 0)
867 goto fail;
868
0b1b17d3 869 r = dns_packet_append_uint16(p, rr->rrsig.key_tag, NULL);
151226ab
ZJS
870 if (r < 0)
871 goto fail;
872
873 r = dns_packet_append_name(p, rr->rrsig.signer, false, NULL);
874 if (r < 0)
875 goto fail;
876
877 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
878 break;
879
50f1e641
TG
880 case DNS_TYPE_NSEC:
881 r = dns_packet_append_name(p, rr->nsec.next_domain_name, false, NULL);
882 if (r < 0)
883 goto fail;
884
885 r = dns_packet_append_types(p, rr->nsec.types, NULL);
886 if (r < 0)
887 goto fail;
888
5d45a880
TG
889 break;
890 case DNS_TYPE_NSEC3:
891 r = dns_packet_append_uint8(p, rr->nsec3.algorithm, NULL);
892 if (r < 0)
893 goto fail;
894
895 r = dns_packet_append_uint8(p, rr->nsec3.flags, NULL);
896 if (r < 0)
897 goto fail;
898
899 r = dns_packet_append_uint16(p, rr->nsec3.iterations, NULL);
900 if (r < 0)
901 goto fail;
902
903 r = dns_packet_append_uint8(p, rr->nsec3.salt_size, NULL);
904 if (r < 0)
905 goto fail;
906
907 r = dns_packet_append_blob(p, rr->nsec3.salt, rr->nsec3.salt_size, NULL);
908 if (r < 0)
909 goto fail;
910
911 r = dns_packet_append_uint8(p, rr->nsec3.next_hashed_name_size, NULL);
912 if (r < 0)
913 goto fail;
914
915 r = dns_packet_append_blob(p, rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, NULL);
916 if (r < 0)
917 goto fail;
918
919 r = dns_packet_append_types(p, rr->nsec3.types, NULL);
920 if (r < 0)
921 goto fail;
922
50f1e641 923 break;
0dae31d4 924 case _DNS_TYPE_INVALID: /* unparseable */
623a4c97 925 default:
0dae31d4 926
623a4c97
LP
927 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
928 break;
929 }
930 if (r < 0)
931 goto fail;
932
933 /* Let's calculate the actual data size and update the field */
934 rdlength = p->size - rdlength_offset - sizeof(uint16_t);
935 if (rdlength > 0xFFFF) {
936 r = ENOSPC;
937 goto fail;
938 }
939
940 end = p->size;
941 p->size = rdlength_offset;
942 r = dns_packet_append_uint16(p, rdlength, NULL);
943 if (r < 0)
944 goto fail;
945 p->size = end;
946
351e6342
LP
947 if (start)
948 *start = saved_size;
949
623a4c97
LP
950 return 0;
951
952fail:
953 dns_packet_truncate(p, saved_size);
954 return r;
955}
956
957
74b2466e
LP
958int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
959 assert(p);
960
961 if (p->rindex + sz > p->size)
962 return -EMSGSIZE;
963
964 if (ret)
965 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
966
967 if (start)
968 *start = p->rindex;
969
970 p->rindex += sz;
971 return 0;
972}
973
8ba9fd9c 974void dns_packet_rewind(DnsPacket *p, size_t idx) {
74b2466e
LP
975 assert(p);
976 assert(idx <= p->size);
977 assert(idx >= DNS_PACKET_HEADER_SIZE);
978
979 p->rindex = idx;
980}
981
623a4c97
LP
982int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
983 const void *q;
984 int r;
985
986 assert(p);
987 assert(d);
988
989 r = dns_packet_read(p, sz, &q, start);
990 if (r < 0)
991 return r;
992
993 memcpy(d, q, sz);
994 return 0;
995}
996
f5430a3e
LP
997static int dns_packet_read_memdup(
998 DnsPacket *p, size_t size,
999 void **ret, size_t *ret_size,
1000 size_t *ret_start) {
1001
1002 const void *src;
1003 size_t start;
1004 int r;
1005
1006 assert(p);
1007 assert(ret);
1008
1009 r = dns_packet_read(p, size, &src, &start);
1010 if (r < 0)
1011 return r;
1012
1013 if (size <= 0)
1014 *ret = NULL;
1015 else {
1016 void *copy;
1017
1018 copy = memdup(src, size);
1019 if (!copy)
1020 return -ENOMEM;
1021
1022 *ret = copy;
1023 }
1024
1025 if (ret_size)
1026 *ret_size = size;
1027 if (ret_start)
1028 *ret_start = start;
1029
1030 return 0;
1031}
1032
74b2466e
LP
1033int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
1034 const void *d;
1035 int r;
1036
1037 assert(p);
1038
1039 r = dns_packet_read(p, sizeof(uint8_t), &d, start);
1040 if (r < 0)
1041 return r;
1042
1043 *ret = ((uint8_t*) d)[0];
1044 return 0;
1045}
1046
1047int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
1048 const void *d;
1049 int r;
1050
1051 assert(p);
1052
1053 r = dns_packet_read(p, sizeof(uint16_t), &d, start);
1054 if (r < 0)
1055 return r;
1056
725ca0e5
TG
1057 *ret = unaligned_read_be16(d);
1058
74b2466e
LP
1059 return 0;
1060}
1061
1062int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
1063 const void *d;
1064 int r;
1065
1066 assert(p);
1067
1068 r = dns_packet_read(p, sizeof(uint32_t), &d, start);
1069 if (r < 0)
1070 return r;
1071
725ca0e5 1072 *ret = unaligned_read_be32(d);
74b2466e
LP
1073
1074 return 0;
1075}
1076
1077int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
1078 size_t saved_rindex;
1079 const void *d;
1080 char *t;
1081 uint8_t c;
1082 int r;
1083
1084 assert(p);
1085
1086 saved_rindex = p->rindex;
1087
1088 r = dns_packet_read_uint8(p, &c, NULL);
1089 if (r < 0)
1090 goto fail;
1091
1092 r = dns_packet_read(p, c, &d, NULL);
1093 if (r < 0)
1094 goto fail;
1095
1096 if (memchr(d, 0, c)) {
1097 r = -EBADMSG;
1098 goto fail;
1099 }
1100
1101 t = strndup(d, c);
1102 if (!t) {
1103 r = -ENOMEM;
1104 goto fail;
1105 }
1106
1107 if (!utf8_is_valid(t)) {
1108 free(t);
1109 r = -EBADMSG;
1110 goto fail;
1111 }
1112
1113 *ret = t;
1114
1115 if (start)
1116 *start = saved_rindex;
1117
1118 return 0;
1119
1120fail:
1121 dns_packet_rewind(p, saved_rindex);
1122 return r;
1123}
1124
2001c805
LP
1125int dns_packet_read_raw_string(DnsPacket *p, const void **ret, size_t *size, size_t *start) {
1126 size_t saved_rindex;
1127 uint8_t c;
1128 int r;
1129
1130 assert(p);
1131
1132 saved_rindex = p->rindex;
1133
1134 r = dns_packet_read_uint8(p, &c, NULL);
1135 if (r < 0)
1136 goto fail;
1137
1138 r = dns_packet_read(p, c, ret, NULL);
1139 if (r < 0)
1140 goto fail;
1141
1142 if (size)
1143 *size = c;
1144 if (start)
1145 *start = saved_rindex;
1146
1147 return 0;
1148
1149fail:
1150 dns_packet_rewind(p, saved_rindex);
1151 return r;
1152}
1153
f6a5fec6
LP
1154int dns_packet_read_name(
1155 DnsPacket *p,
1156 char **_ret,
1157 bool allow_compression,
1158 size_t *start) {
1159
c75dbf9b 1160 size_t saved_rindex, after_rindex = 0, jump_barrier;
74b2466e
LP
1161 _cleanup_free_ char *ret = NULL;
1162 size_t n = 0, allocated = 0;
1163 bool first = true;
1164 int r;
1165
1166 assert(p);
1167 assert(_ret);
1168
f6a5fec6
LP
1169 if (p->refuse_compression)
1170 allow_compression = false;
1171
74b2466e 1172 saved_rindex = p->rindex;
c75dbf9b 1173 jump_barrier = p->rindex;
74b2466e
LP
1174
1175 for (;;) {
1176 uint8_t c, d;
1177
1178 r = dns_packet_read_uint8(p, &c, NULL);
1179 if (r < 0)
1180 goto fail;
1181
1182 if (c == 0)
1183 /* End of name */
1184 break;
1185 else if (c <= 63) {
74b2466e
LP
1186 const char *label;
1187
1188 /* Literal label */
1189 r = dns_packet_read(p, c, (const void**) &label, NULL);
1190 if (r < 0)
1191 goto fail;
1192
422baca0 1193 if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX)) {
74b2466e
LP
1194 r = -ENOMEM;
1195 goto fail;
1196 }
1197
422baca0 1198 if (first)
74b2466e 1199 first = false;
422baca0
LP
1200 else
1201 ret[n++] = '.';
1202
1203 r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
1204 if (r < 0)
1205 goto fail;
74b2466e 1206
74b2466e
LP
1207 n += r;
1208 continue;
151226ab 1209 } else if (allow_compression && (c & 0xc0) == 0xc0) {
74b2466e
LP
1210 uint16_t ptr;
1211
1212 /* Pointer */
1213 r = dns_packet_read_uint8(p, &d, NULL);
1214 if (r < 0)
1215 goto fail;
1216
1217 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
c75dbf9b 1218 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier) {
74b2466e
LP
1219 r = -EBADMSG;
1220 goto fail;
1221 }
1222
1223 if (after_rindex == 0)
1224 after_rindex = p->rindex;
1225
f131770b 1226 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
c75dbf9b 1227 jump_barrier = ptr;
74b2466e 1228 p->rindex = ptr;
59aa5821
SP
1229 } else {
1230 r = -EBADMSG;
74b2466e 1231 goto fail;
59aa5821 1232 }
74b2466e
LP
1233 }
1234
1235 if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
1236 r = -ENOMEM;
1237 goto fail;
1238 }
1239
1240 ret[n] = 0;
1241
1242 if (after_rindex != 0)
1243 p->rindex= after_rindex;
1244
1245 *_ret = ret;
1246 ret = NULL;
1247
1248 if (start)
1249 *start = saved_rindex;
1250
1251 return 0;
1252
1253fail:
1254 dns_packet_rewind(p, saved_rindex);
1255 return r;
1256}
1257
50f1e641
TG
1258static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *start) {
1259 uint8_t window;
1260 uint8_t length;
1261 const uint8_t *bitmap;
2ad613ad 1262 uint8_t bit = 0;
50f1e641
TG
1263 unsigned i;
1264 bool found = false;
1265 size_t saved_rindex;
1266 int r;
1267
1268 assert(p);
1269 assert(types);
1270
1271 saved_rindex = p->rindex;
1272
1273 r = bitmap_ensure_allocated(types);
1274 if (r < 0)
1275 goto fail;
1276
1277 r = dns_packet_read_uint8(p, &window, NULL);
1278 if (r < 0)
1279 goto fail;
1280
1281 r = dns_packet_read_uint8(p, &length, NULL);
1282 if (r < 0)
1283 goto fail;
1284
1285 if (length == 0 || length > 32)
1286 return -EBADMSG;
1287
1288 r = dns_packet_read(p, length, (const void **)&bitmap, NULL);
1289 if (r < 0)
1290 goto fail;
1291
1292 for (i = 0; i < length; i++) {
1293 uint8_t bitmask = 1 << 7;
50f1e641
TG
1294
1295 if (!bitmap[i]) {
1296 found = false;
2ad613ad 1297 bit += 8;
50f1e641
TG
1298 continue;
1299 }
1300
1301 found = true;
1302
1303 while (bitmask) {
1304 if (bitmap[i] & bitmask) {
1305 uint16_t n;
1306
50f1e641
TG
1307 n = (uint16_t) window << 8 | (uint16_t) bit;
1308
8e6edc49
TG
1309 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1310 if (dns_type_is_pseudo(n))
1311 continue;
1312
50f1e641
TG
1313 r = bitmap_set(*types, n);
1314 if (r < 0)
1315 goto fail;
1316 }
1317
1318 bit ++;
1319 bitmask >>= 1;
1320 }
1321 }
1322
1323 if (!found)
1324 return -EBADMSG;
1325
1326 if (start)
1327 *start = saved_rindex;
1328
1329 return 0;
1330fail:
1331 dns_packet_rewind(p, saved_rindex);
1332 return r;
1333}
1334
89492aaf
TG
1335static int dns_packet_read_type_windows(DnsPacket *p, Bitmap **types, size_t size, size_t *start) {
1336 size_t saved_rindex;
1337 int r;
1338
1339 saved_rindex = p->rindex;
1340
1341 while (p->rindex < saved_rindex + size) {
1342 r = dns_packet_read_type_window(p, types, NULL);
1343 if (r < 0)
1344 goto fail;
1345
1346 /* don't read past end of current RR */
1347 if (p->rindex > saved_rindex + size) {
1348 r = -EBADMSG;
1349 goto fail;
1350 }
1351 }
1352
1353 if (p->rindex != saved_rindex + size) {
1354 r = -EBADMSG;
1355 goto fail;
1356 }
1357
1358 if (start)
1359 *start = saved_rindex;
1360
1361 return 0;
1362fail:
1363 dns_packet_rewind(p, saved_rindex);
1364 return r;
1365}
1366
faa133f3
LP
1367int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
1368 _cleanup_free_ char *name = NULL;
1369 uint16_t class, type;
1370 DnsResourceKey *key;
74b2466e
LP
1371 size_t saved_rindex;
1372 int r;
1373
1374 assert(p);
1375 assert(ret);
1376
1377 saved_rindex = p->rindex;
1378
151226ab 1379 r = dns_packet_read_name(p, &name, true, NULL);
74b2466e
LP
1380 if (r < 0)
1381 goto fail;
1382
faa133f3 1383 r = dns_packet_read_uint16(p, &type, NULL);
74b2466e
LP
1384 if (r < 0)
1385 goto fail;
1386
faa133f3 1387 r = dns_packet_read_uint16(p, &class, NULL);
74b2466e
LP
1388 if (r < 0)
1389 goto fail;
1390
faa133f3
LP
1391 key = dns_resource_key_new_consume(class, type, name);
1392 if (!key) {
1393 r = -ENOMEM;
1394 goto fail;
1395 }
1396
1397 name = NULL;
1398 *ret = key;
74b2466e
LP
1399
1400 if (start)
1401 *start = saved_rindex;
1402
1403 return 0;
1404fail:
1405 dns_packet_rewind(p, saved_rindex);
1406 return r;
1407}
1408
afbc4f26
ZJS
1409static bool loc_size_ok(uint8_t size) {
1410 uint8_t m = size >> 4, e = size & 0xF;
1411
1412 return m <= 9 && e <= 9 && (m > 0 || e == 0);
1413}
1414
8db0d2f5 1415static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
3ef77d04
LP
1416 assert(rr);
1417
8db0d2f5
ZJS
1418 if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
1419 return -EBADMSG;
1420
1421 rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
1422 rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
1423 return 0;
1424}
1425
74b2466e 1426int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
faa133f3
LP
1427 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1428 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
74b2466e
LP
1429 size_t saved_rindex, offset;
1430 uint16_t rdlength;
74b2466e
LP
1431 int r;
1432
1433 assert(p);
1434 assert(ret);
1435
4e0296a9 1436 saved_rindex = p->rindex;
74b2466e 1437
faa133f3 1438 r = dns_packet_read_key(p, &key, NULL);
74b2466e
LP
1439 if (r < 0)
1440 goto fail;
1441
0e2bcd6a
LP
1442 if (key->class == DNS_CLASS_ANY ||
1443 key->type == DNS_TYPE_ANY) {
1444 r = -EBADMSG;
1445 goto fail;
1446 }
1447
faa133f3
LP
1448 rr = dns_resource_record_new(key);
1449 if (!rr) {
1450 r = -ENOMEM;
1451 goto fail;
1452 }
1453
74b2466e
LP
1454 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1455 if (r < 0)
1456 goto fail;
1457
1458 r = dns_packet_read_uint16(p, &rdlength, NULL);
1459 if (r < 0)
1460 goto fail;
1461
1462 if (p->rindex + rdlength > p->size) {
1463 r = -EBADMSG;
1464 goto fail;
1465 }
1466
1467 offset = p->rindex;
1468
faa133f3 1469 switch (rr->key->type) {
74b2466e 1470
9c92ce6d
LP
1471 case DNS_TYPE_SRV:
1472 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1473 if (r < 0)
1474 goto fail;
1475 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1476 if (r < 0)
1477 goto fail;
1478 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1479 if (r < 0)
1480 goto fail;
151226ab 1481 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
9c92ce6d
LP
1482 break;
1483
74b2466e
LP
1484 case DNS_TYPE_PTR:
1485 case DNS_TYPE_NS:
1486 case DNS_TYPE_CNAME:
8ac4e9e1 1487 case DNS_TYPE_DNAME:
151226ab 1488 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
74b2466e
LP
1489 break;
1490
dc913c9a
TG
1491 case DNS_TYPE_OPT: /* we only care about the header */
1492 r = 0;
1493 break;
1494
74b2466e
LP
1495 case DNS_TYPE_HINFO:
1496 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1497 if (r < 0)
1498 goto fail;
1499
1500 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1501 break;
1502
9de3e329 1503 case DNS_TYPE_SPF: /* exactly the same as TXT */
1ccda9b7
LP
1504 case DNS_TYPE_TXT:
1505 if (rdlength <= 0) {
2001c805 1506 DnsTxtItem *i;
1ccda9b7
LP
1507 /* RFC 6763, section 6.1 suggests to treat
1508 * empty TXT RRs as equivalent to a TXT record
1509 * with a single empty string. */
0e3434ae 1510
2001c805
LP
1511 i = malloc0(offsetof(DnsTxtItem, data) + 1); /* for safety reasons we add an extra NUL byte */
1512 if (!i)
1513 return -ENOMEM;
1514
1515 rr->txt.items = i;
1ccda9b7 1516 } else {
2001c805
LP
1517 DnsTxtItem *last = NULL;
1518
1ccda9b7 1519 while (p->rindex < offset + rdlength) {
2001c805
LP
1520 DnsTxtItem *i;
1521 const void *data;
1522 size_t sz;
2e276efc 1523
2001c805 1524 r = dns_packet_read_raw_string(p, &data, &sz, NULL);
1ccda9b7 1525 if (r < 0)
2001c805 1526 return r;
1ccda9b7 1527
2001c805
LP
1528 i = malloc0(offsetof(DnsTxtItem, data) + sz + 1); /* extra NUL byte at the end */
1529 if (!i)
1530 return -ENOMEM;
1531
1532 memcpy(i->data, data, sz);
1533 i->length = sz;
1534
1535 LIST_INSERT_AFTER(items, rr->txt.items, last, i);
1536 last = i;
1ccda9b7 1537 }
6a6fc3df
LP
1538 }
1539
1540 r = 0;
2e276efc 1541 break;
2e276efc 1542
74b2466e 1543 case DNS_TYPE_A:
623a4c97 1544 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
74b2466e
LP
1545 break;
1546
1547 case DNS_TYPE_AAAA:
623a4c97 1548 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
74b2466e
LP
1549 break;
1550
7e8e0422 1551 case DNS_TYPE_SOA:
151226ab 1552 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
7e8e0422
LP
1553 if (r < 0)
1554 goto fail;
1555
151226ab 1556 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
7e8e0422
LP
1557 if (r < 0)
1558 goto fail;
1559
1560 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1561 if (r < 0)
1562 goto fail;
1563
1564 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1565 if (r < 0)
1566 goto fail;
1567
1568 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1569 if (r < 0)
1570 goto fail;
1571
1572 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1573 if (r < 0)
1574 goto fail;
1575
1576 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1577 break;
1578
623a4c97 1579 case DNS_TYPE_MX:
946c7094
ZJS
1580 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1581 if (r < 0)
1582 goto fail;
1583
151226ab 1584 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
946c7094
ZJS
1585 break;
1586
0dae31d4
ZJS
1587 case DNS_TYPE_LOC: {
1588 uint8_t t;
1589 size_t pos;
1590
1591 r = dns_packet_read_uint8(p, &t, &pos);
1592 if (r < 0)
1593 goto fail;
1594
1595 if (t == 0) {
1596 rr->loc.version = t;
1597
1598 r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1599 if (r < 0)
1600 goto fail;
1601
afbc4f26
ZJS
1602 if (!loc_size_ok(rr->loc.size)) {
1603 r = -EBADMSG;
1604 goto fail;
1605 }
1606
0dae31d4
ZJS
1607 r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1608 if (r < 0)
1609 goto fail;
1610
afbc4f26
ZJS
1611 if (!loc_size_ok(rr->loc.horiz_pre)) {
1612 r = -EBADMSG;
1613 goto fail;
1614 }
1615
0dae31d4
ZJS
1616 r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1617 if (r < 0)
1618 goto fail;
1619
afbc4f26
ZJS
1620 if (!loc_size_ok(rr->loc.vert_pre)) {
1621 r = -EBADMSG;
1622 goto fail;
1623 }
1624
0dae31d4
ZJS
1625 r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1626 if (r < 0)
1627 goto fail;
1628
1629 r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1630 if (r < 0)
1631 goto fail;
1632
1633 r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1634 if (r < 0)
1635 goto fail;
1636
1637 break;
1638 } else {
1639 dns_packet_rewind(p, pos);
1640 rr->unparseable = true;
afbc4f26 1641 goto unparseable;
0dae31d4
ZJS
1642 }
1643 }
1644
abf126a3
TG
1645 case DNS_TYPE_DS:
1646 r = dns_packet_read_uint16(p, &rr->ds.key_tag, NULL);
1647 if (r < 0)
1648 goto fail;
1649
1650 r = dns_packet_read_uint8(p, &rr->ds.algorithm, NULL);
1651 if (r < 0)
1652 goto fail;
1653
1654 r = dns_packet_read_uint8(p, &rr->ds.digest_type, NULL);
1655 if (r < 0)
1656 goto fail;
1657
f5430a3e
LP
1658 r = dns_packet_read_memdup(p, rdlength - 4,
1659 &rr->ds.digest, &rr->ds.digest_size,
1660 NULL);
abf126a3
TG
1661 if (r < 0)
1662 goto fail;
1663
f1d178cc
TG
1664 if (rr->ds.digest_size <= 0) {
1665 /* the accepted size depends on the algorithm, but for now
1666 just ensure that the value is greater than zero */
1667 r = -EBADMSG;
1668 goto fail;
1669 }
1670
abf126a3 1671 break;
623a4c97 1672 case DNS_TYPE_SSHFP:
42cc2eeb
LP
1673 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1674 if (r < 0)
1675 goto fail;
1676
1677 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1678 if (r < 0)
1679 goto fail;
1680
f5430a3e 1681 r = dns_packet_read_memdup(p, rdlength - 2,
549c1a25 1682 &rr->sshfp.fingerprint, &rr->sshfp.fingerprint_size,
f5430a3e 1683 NULL);
f1d178cc 1684
549c1a25 1685 if (rr->sshfp.fingerprint_size <= 0) {
f1d178cc
TG
1686 /* the accepted size depends on the algorithm, but for now
1687 just ensure that the value is greater than zero */
1688 r = -EBADMSG;
1689 goto fail;
1690 }
1691
8db0d2f5
ZJS
1692 break;
1693
1694 case DNS_TYPE_DNSKEY: {
1695 uint16_t flags;
1696 uint8_t proto;
1697
1698 r = dns_packet_read_uint16(p, &flags, NULL);
42cc2eeb
LP
1699 if (r < 0)
1700 goto fail;
1701
8db0d2f5
ZJS
1702 r = dnskey_parse_flags(rr, flags);
1703 if (r < 0)
1704 goto fail;
1705
1706 r = dns_packet_read_uint8(p, &proto, NULL);
1707 if (r < 0)
1708 goto fail;
1709
1710 /* protocol is required to be always 3 */
1711 if (proto != 3) {
1712 r = -EBADMSG;
42cc2eeb
LP
1713 goto fail;
1714 }
1715
8db0d2f5
ZJS
1716 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1717 if (r < 0)
1718 goto fail;
1719
f5430a3e
LP
1720 r = dns_packet_read_memdup(p, rdlength - 4,
1721 &rr->dnskey.key, &rr->dnskey.key_size,
1722 NULL);
f1d178cc
TG
1723
1724 if (rr->dnskey.key_size <= 0) {
1725 /* the accepted size depends on the algorithm, but for now
1726 just ensure that the value is greater than zero */
1727 r = -EBADMSG;
1728 goto fail;
1729 }
1730
42cc2eeb 1731 break;
8db0d2f5 1732 }
42cc2eeb 1733
151226ab
ZJS
1734 case DNS_TYPE_RRSIG:
1735 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1736 if (r < 0)
1737 goto fail;
1738
1739 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1740 if (r < 0)
1741 goto fail;
1742
1743 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1744 if (r < 0)
1745 goto fail;
1746
1747 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1748 if (r < 0)
1749 goto fail;
1750
1751 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1752 if (r < 0)
1753 goto fail;
1754
1755 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1756 if (r < 0)
1757 goto fail;
1758
1759 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1760 if (r < 0)
1761 goto fail;
1762
1763 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1764 if (r < 0)
1765 goto fail;
1766
f5430a3e
LP
1767 r = dns_packet_read_memdup(p, offset + rdlength - p->rindex,
1768 &rr->rrsig.signature, &rr->rrsig.signature_size,
1769 NULL);
f1d178cc
TG
1770
1771 if (rr->rrsig.signature_size <= 0) {
1772 /* the accepted size depends on the algorithm, but for now
1773 just ensure that the value is greater than zero */
1774 r = -EBADMSG;
1775 goto fail;
1776 }
1777
151226ab
ZJS
1778 break;
1779
50f1e641
TG
1780 case DNS_TYPE_NSEC:
1781 r = dns_packet_read_name(p, &rr->nsec.next_domain_name, false, NULL);
1782 if (r < 0)
1783 goto fail;
1784
89492aaf
TG
1785 r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL);
1786 if (r < 0)
1787 goto fail;
1788
09eaf68c
TG
1789 /* We accept empty NSEC bitmaps. The bit indicating the presence of the NSEC record itself
1790 * is redundant and in e.g., RFC4956 this fact is used to define a use for NSEC records
1791 * without the NSEC bit set. */
50f1e641
TG
1792
1793 break;
5d45a880
TG
1794
1795 case DNS_TYPE_NSEC3: {
1796 uint8_t size;
1797
1798 r = dns_packet_read_uint8(p, &rr->nsec3.algorithm, NULL);
1799 if (r < 0)
1800 goto fail;
1801
1802 r = dns_packet_read_uint8(p, &rr->nsec3.flags, NULL);
1803 if (r < 0)
1804 goto fail;
1805
1806 r = dns_packet_read_uint16(p, &rr->nsec3.iterations, NULL);
1807 if (r < 0)
1808 goto fail;
1809
f1d178cc 1810 /* this may be zero */
5d45a880
TG
1811 r = dns_packet_read_uint8(p, &size, NULL);
1812 if (r < 0)
1813 goto fail;
1814
f5430a3e 1815 r = dns_packet_read_memdup(p, size, &rr->nsec3.salt, &rr->nsec3.salt_size, NULL);
5d45a880
TG
1816 if (r < 0)
1817 goto fail;
1818
5d45a880
TG
1819 r = dns_packet_read_uint8(p, &size, NULL);
1820 if (r < 0)
1821 goto fail;
1822
f1d178cc
TG
1823 if (size <= 0) {
1824 r = -EBADMSG;
1825 goto fail;
1826 }
1827
f5430a3e 1828 r = dns_packet_read_memdup(p, size, &rr->nsec3.next_hashed_name, &rr->nsec3.next_hashed_name_size, NULL);
5d45a880
TG
1829 if (r < 0)
1830 goto fail;
1831
6b9308d1 1832 r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL);
5d45a880
TG
1833 if (r < 0)
1834 goto fail;
1835
0bbd72b2
TG
1836 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
1837
5d45a880
TG
1838 break;
1839 }
74b2466e 1840 default:
afbc4f26 1841 unparseable:
f5430a3e 1842 r = dns_packet_read_memdup(p, rdlength, &rr->generic.data, &rr->generic.size, NULL);
74b2466e
LP
1843 if (r < 0)
1844 goto fail;
74b2466e
LP
1845 break;
1846 }
1847 if (r < 0)
1848 goto fail;
1849 if (p->rindex != offset + rdlength) {
1850 r = -EBADMSG;
1851 goto fail;
1852 }
1853
1854 *ret = rr;
1855 rr = NULL;
1856
1857 if (start)
1858 *start = saved_rindex;
1859
1860 return 0;
1861fail:
1862 dns_packet_rewind(p, saved_rindex);
1863 return r;
1864}
1865
faa133f3
LP
1866int dns_packet_extract(DnsPacket *p) {
1867 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1868 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1869 size_t saved_rindex;
1870 unsigned n, i;
74b2466e
LP
1871 int r;
1872
a4076574
LP
1873 if (p->extracted)
1874 return 0;
1875
faa133f3 1876 saved_rindex = p->rindex;
322345fd
LP
1877 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1878
3cb10d3a 1879 n = DNS_PACKET_QDCOUNT(p);
faa133f3
LP
1880 if (n > 0) {
1881 question = dns_question_new(n);
1882 if (!question) {
1883 r = -ENOMEM;
1884 goto finish;
1885 }
74b2466e 1886
faa133f3
LP
1887 for (i = 0; i < n; i++) {
1888 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
74b2466e 1889
faa133f3
LP
1890 r = dns_packet_read_key(p, &key, NULL);
1891 if (r < 0)
1892 goto finish;
74b2466e 1893
faa133f3
LP
1894 r = dns_question_add(question, key);
1895 if (r < 0)
1896 goto finish;
1897 }
1898 }
322345fd 1899
faa133f3
LP
1900 n = DNS_PACKET_RRCOUNT(p);
1901 if (n > 0) {
1902 answer = dns_answer_new(n);
1903 if (!answer) {
1904 r = -ENOMEM;
1905 goto finish;
1906 }
322345fd 1907
faa133f3
LP
1908 for (i = 0; i < n; i++) {
1909 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
322345fd 1910
faa133f3
LP
1911 r = dns_packet_read_rr(p, &rr, NULL);
1912 if (r < 0)
1913 goto finish;
322345fd 1914
78c6a153 1915 r = dns_answer_add(answer, rr, p->ifindex);
faa133f3
LP
1916 if (r < 0)
1917 goto finish;
1918 }
322345fd
LP
1919 }
1920
faa133f3
LP
1921 p->question = question;
1922 question = NULL;
322345fd 1923
faa133f3
LP
1924 p->answer = answer;
1925 answer = NULL;
322345fd 1926
a4076574
LP
1927 p->extracted = true;
1928
faa133f3 1929 r = 0;
322345fd
LP
1930
1931finish:
1932 p->rindex = saved_rindex;
1933 return r;
1934}
1935
74b2466e
LP
1936static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
1937 [DNS_RCODE_SUCCESS] = "SUCCESS",
1938 [DNS_RCODE_FORMERR] = "FORMERR",
1939 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
1940 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
1941 [DNS_RCODE_NOTIMP] = "NOTIMP",
1942 [DNS_RCODE_REFUSED] = "REFUSED",
1943 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
1944 [DNS_RCODE_YXRRSET] = "YRRSET",
1945 [DNS_RCODE_NXRRSET] = "NXRRSET",
1946 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
1947 [DNS_RCODE_NOTZONE] = "NOTZONE",
1948 [DNS_RCODE_BADVERS] = "BADVERS",
1949 [DNS_RCODE_BADKEY] = "BADKEY",
1950 [DNS_RCODE_BADTIME] = "BADTIME",
1951 [DNS_RCODE_BADMODE] = "BADMODE",
1952 [DNS_RCODE_BADNAME] = "BADNAME",
1953 [DNS_RCODE_BADALG] = "BADALG",
1954 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
1955};
1956DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1716f6dc
LP
1957
1958static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
1959 [DNS_PROTOCOL_DNS] = "dns",
1960 [DNS_PROTOCOL_MDNS] = "mdns",
1961 [DNS_PROTOCOL_LLMNR] = "llmnr",
1962};
1963DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
ff3d6560
ZJS
1964
1965static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
5d45a880
TG
1966 [DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
1967 [DNSSEC_ALGORITHM_DH] = "DH",
1968 [DNSSEC_ALGORITHM_DSA] = "DSA",
1969 [DNSSEC_ALGORITHM_ECC] = "ECC",
1970 [DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
1971 [DNSSEC_ALGORITHM_DSA_NSEC3_SHA1] = "DSA-NSEC3-SHA1",
1972 [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1] = "RSASHA1-NSEC3-SHA1",
e30ec345
LP
1973 [DNSSEC_ALGORITHM_RSASHA256] = "RSASHA256",
1974 [DNSSEC_ALGORITHM_RSASHA512] = "RSASHA512",
5d45a880
TG
1975 [DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
1976 [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
1977 [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
ff3d6560
ZJS
1978};
1979DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);