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