]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-packet.c
dns-domain: rework dns_label_escape() to not imply memory allocation
[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 const char *label;
1149
1150 /* Literal label */
1151 r = dns_packet_read(p, c, (const void**) &label, NULL);
1152 if (r < 0)
1153 goto fail;
1154
1155 if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX)) {
1156 r = -ENOMEM;
1157 goto fail;
1158 }
1159
1160 if (first)
1161 first = false;
1162 else
1163 ret[n++] = '.';
1164
1165 r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
1166 if (r < 0)
1167 goto fail;
1168
1169 n += r;
1170 continue;
1171 } else if (allow_compression && (c & 0xc0) == 0xc0) {
1172 uint16_t ptr;
1173
1174 /* Pointer */
1175 r = dns_packet_read_uint8(p, &d, NULL);
1176 if (r < 0)
1177 goto fail;
1178
1179 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
1180 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier) {
1181 r = -EBADMSG;
1182 goto fail;
1183 }
1184
1185 if (after_rindex == 0)
1186 after_rindex = p->rindex;
1187
1188 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1189 jump_barrier = ptr;
1190 p->rindex = ptr;
1191 } else {
1192 r = -EBADMSG;
1193 goto fail;
1194 }
1195 }
1196
1197 if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
1198 r = -ENOMEM;
1199 goto fail;
1200 }
1201
1202 ret[n] = 0;
1203
1204 if (after_rindex != 0)
1205 p->rindex= after_rindex;
1206
1207 *_ret = ret;
1208 ret = NULL;
1209
1210 if (start)
1211 *start = saved_rindex;
1212
1213 return 0;
1214
1215 fail:
1216 dns_packet_rewind(p, saved_rindex);
1217 return r;
1218 }
1219
1220 static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *start) {
1221 uint8_t window;
1222 uint8_t length;
1223 const uint8_t *bitmap;
1224 uint8_t bit = 0;
1225 unsigned i;
1226 bool found = false;
1227 size_t saved_rindex;
1228 int r;
1229
1230 assert(p);
1231 assert(types);
1232
1233 saved_rindex = p->rindex;
1234
1235 r = bitmap_ensure_allocated(types);
1236 if (r < 0)
1237 goto fail;
1238
1239 r = dns_packet_read_uint8(p, &window, NULL);
1240 if (r < 0)
1241 goto fail;
1242
1243 r = dns_packet_read_uint8(p, &length, NULL);
1244 if (r < 0)
1245 goto fail;
1246
1247 if (length == 0 || length > 32)
1248 return -EBADMSG;
1249
1250 r = dns_packet_read(p, length, (const void **)&bitmap, NULL);
1251 if (r < 0)
1252 goto fail;
1253
1254 for (i = 0; i < length; i++) {
1255 uint8_t bitmask = 1 << 7;
1256
1257 if (!bitmap[i]) {
1258 found = false;
1259 bit += 8;
1260 continue;
1261 }
1262
1263 found = true;
1264
1265 while (bitmask) {
1266 if (bitmap[i] & bitmask) {
1267 uint16_t n;
1268
1269 n = (uint16_t) window << 8 | (uint16_t) bit;
1270
1271 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1272 if (dns_type_is_pseudo(n))
1273 continue;
1274
1275 r = bitmap_set(*types, n);
1276 if (r < 0)
1277 goto fail;
1278 }
1279
1280 bit ++;
1281 bitmask >>= 1;
1282 }
1283 }
1284
1285 if (!found)
1286 return -EBADMSG;
1287
1288 if (start)
1289 *start = saved_rindex;
1290
1291 return 0;
1292 fail:
1293 dns_packet_rewind(p, saved_rindex);
1294 return r;
1295 }
1296
1297 static int dns_packet_read_type_windows(DnsPacket *p, Bitmap **types, size_t size, size_t *start) {
1298 size_t saved_rindex;
1299 int r;
1300
1301 saved_rindex = p->rindex;
1302
1303 while (p->rindex < saved_rindex + size) {
1304 r = dns_packet_read_type_window(p, types, NULL);
1305 if (r < 0)
1306 goto fail;
1307
1308 /* don't read past end of current RR */
1309 if (p->rindex > saved_rindex + size) {
1310 r = -EBADMSG;
1311 goto fail;
1312 }
1313 }
1314
1315 if (p->rindex != saved_rindex + size) {
1316 r = -EBADMSG;
1317 goto fail;
1318 }
1319
1320 if (start)
1321 *start = saved_rindex;
1322
1323 return 0;
1324 fail:
1325 dns_packet_rewind(p, saved_rindex);
1326 return r;
1327 }
1328
1329 int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
1330 _cleanup_free_ char *name = NULL;
1331 uint16_t class, type;
1332 DnsResourceKey *key;
1333 size_t saved_rindex;
1334 int r;
1335
1336 assert(p);
1337 assert(ret);
1338
1339 saved_rindex = p->rindex;
1340
1341 r = dns_packet_read_name(p, &name, true, NULL);
1342 if (r < 0)
1343 goto fail;
1344
1345 r = dns_packet_read_uint16(p, &type, NULL);
1346 if (r < 0)
1347 goto fail;
1348
1349 r = dns_packet_read_uint16(p, &class, NULL);
1350 if (r < 0)
1351 goto fail;
1352
1353 key = dns_resource_key_new_consume(class, type, name);
1354 if (!key) {
1355 r = -ENOMEM;
1356 goto fail;
1357 }
1358
1359 name = NULL;
1360 *ret = key;
1361
1362 if (start)
1363 *start = saved_rindex;
1364
1365 return 0;
1366 fail:
1367 dns_packet_rewind(p, saved_rindex);
1368 return r;
1369 }
1370
1371 static bool loc_size_ok(uint8_t size) {
1372 uint8_t m = size >> 4, e = size & 0xF;
1373
1374 return m <= 9 && e <= 9 && (m > 0 || e == 0);
1375 }
1376
1377 static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
1378 assert(rr);
1379
1380 if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
1381 return -EBADMSG;
1382
1383 rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
1384 rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
1385 return 0;
1386 }
1387
1388 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
1389 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1390 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1391 size_t saved_rindex, offset;
1392 uint16_t rdlength;
1393 int r;
1394
1395 assert(p);
1396 assert(ret);
1397
1398 saved_rindex = p->rindex;
1399
1400 r = dns_packet_read_key(p, &key, NULL);
1401 if (r < 0)
1402 goto fail;
1403
1404 if (key->class == DNS_CLASS_ANY ||
1405 key->type == DNS_TYPE_ANY) {
1406 r = -EBADMSG;
1407 goto fail;
1408 }
1409
1410 rr = dns_resource_record_new(key);
1411 if (!rr) {
1412 r = -ENOMEM;
1413 goto fail;
1414 }
1415
1416 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1417 if (r < 0)
1418 goto fail;
1419
1420 r = dns_packet_read_uint16(p, &rdlength, NULL);
1421 if (r < 0)
1422 goto fail;
1423
1424 if (p->rindex + rdlength > p->size) {
1425 r = -EBADMSG;
1426 goto fail;
1427 }
1428
1429 offset = p->rindex;
1430
1431 switch (rr->key->type) {
1432
1433 case DNS_TYPE_SRV:
1434 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1435 if (r < 0)
1436 goto fail;
1437 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1438 if (r < 0)
1439 goto fail;
1440 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1441 if (r < 0)
1442 goto fail;
1443 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
1444 break;
1445
1446 case DNS_TYPE_PTR:
1447 case DNS_TYPE_NS:
1448 case DNS_TYPE_CNAME:
1449 case DNS_TYPE_DNAME:
1450 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
1451 break;
1452
1453 case DNS_TYPE_HINFO:
1454 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1455 if (r < 0)
1456 goto fail;
1457
1458 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1459 break;
1460
1461 case DNS_TYPE_SPF: /* exactly the same as TXT */
1462 case DNS_TYPE_TXT:
1463 if (rdlength <= 0) {
1464 DnsTxtItem *i;
1465 /* RFC 6763, section 6.1 suggests to treat
1466 * empty TXT RRs as equivalent to a TXT record
1467 * with a single empty string. */
1468
1469 i = malloc0(offsetof(DnsTxtItem, data) + 1); /* for safety reasons we add an extra NUL byte */
1470 if (!i)
1471 return -ENOMEM;
1472
1473 rr->txt.items = i;
1474 } else {
1475 DnsTxtItem *last = NULL;
1476
1477 while (p->rindex < offset + rdlength) {
1478 DnsTxtItem *i;
1479 const void *data;
1480 size_t sz;
1481
1482 r = dns_packet_read_raw_string(p, &data, &sz, NULL);
1483 if (r < 0)
1484 return r;
1485
1486 i = malloc0(offsetof(DnsTxtItem, data) + sz + 1); /* extra NUL byte at the end */
1487 if (!i)
1488 return -ENOMEM;
1489
1490 memcpy(i->data, data, sz);
1491 i->length = sz;
1492
1493 LIST_INSERT_AFTER(items, rr->txt.items, last, i);
1494 last = i;
1495 }
1496 }
1497
1498 r = 0;
1499 break;
1500
1501 case DNS_TYPE_A:
1502 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1503 break;
1504
1505 case DNS_TYPE_AAAA:
1506 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1507 break;
1508
1509 case DNS_TYPE_SOA:
1510 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
1511 if (r < 0)
1512 goto fail;
1513
1514 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
1515 if (r < 0)
1516 goto fail;
1517
1518 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1519 if (r < 0)
1520 goto fail;
1521
1522 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1523 if (r < 0)
1524 goto fail;
1525
1526 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1527 if (r < 0)
1528 goto fail;
1529
1530 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1531 if (r < 0)
1532 goto fail;
1533
1534 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1535 break;
1536
1537 case DNS_TYPE_MX:
1538 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1539 if (r < 0)
1540 goto fail;
1541
1542 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
1543 break;
1544
1545 case DNS_TYPE_LOC: {
1546 uint8_t t;
1547 size_t pos;
1548
1549 r = dns_packet_read_uint8(p, &t, &pos);
1550 if (r < 0)
1551 goto fail;
1552
1553 if (t == 0) {
1554 rr->loc.version = t;
1555
1556 r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1557 if (r < 0)
1558 goto fail;
1559
1560 if (!loc_size_ok(rr->loc.size)) {
1561 r = -EBADMSG;
1562 goto fail;
1563 }
1564
1565 r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1566 if (r < 0)
1567 goto fail;
1568
1569 if (!loc_size_ok(rr->loc.horiz_pre)) {
1570 r = -EBADMSG;
1571 goto fail;
1572 }
1573
1574 r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1575 if (r < 0)
1576 goto fail;
1577
1578 if (!loc_size_ok(rr->loc.vert_pre)) {
1579 r = -EBADMSG;
1580 goto fail;
1581 }
1582
1583 r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1584 if (r < 0)
1585 goto fail;
1586
1587 r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1588 if (r < 0)
1589 goto fail;
1590
1591 r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1592 if (r < 0)
1593 goto fail;
1594
1595 break;
1596 } else {
1597 dns_packet_rewind(p, pos);
1598 rr->unparseable = true;
1599 goto unparseable;
1600 }
1601 }
1602
1603 case DNS_TYPE_DS:
1604 r = dns_packet_read_uint16(p, &rr->ds.key_tag, NULL);
1605 if (r < 0)
1606 goto fail;
1607
1608 r = dns_packet_read_uint8(p, &rr->ds.algorithm, NULL);
1609 if (r < 0)
1610 goto fail;
1611
1612 r = dns_packet_read_uint8(p, &rr->ds.digest_type, NULL);
1613 if (r < 0)
1614 goto fail;
1615
1616 r = dns_packet_read_memdup(p, rdlength - 4,
1617 &rr->ds.digest, &rr->ds.digest_size,
1618 NULL);
1619 if (r < 0)
1620 goto fail;
1621
1622 if (rr->ds.digest_size <= 0) {
1623 /* the accepted size depends on the algorithm, but for now
1624 just ensure that the value is greater than zero */
1625 r = -EBADMSG;
1626 goto fail;
1627 }
1628
1629 break;
1630 case DNS_TYPE_SSHFP:
1631 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1632 if (r < 0)
1633 goto fail;
1634
1635 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1636 if (r < 0)
1637 goto fail;
1638
1639 r = dns_packet_read_memdup(p, rdlength - 2,
1640 &rr->sshfp.fingerprint, &rr->sshfp.fingerprint_size,
1641 NULL);
1642
1643 if (rr->sshfp.fingerprint_size <= 0) {
1644 /* the accepted size depends on the algorithm, but for now
1645 just ensure that the value is greater than zero */
1646 r = -EBADMSG;
1647 goto fail;
1648 }
1649
1650 break;
1651
1652 case DNS_TYPE_DNSKEY: {
1653 uint16_t flags;
1654 uint8_t proto;
1655
1656 r = dns_packet_read_uint16(p, &flags, NULL);
1657 if (r < 0)
1658 goto fail;
1659
1660 r = dnskey_parse_flags(rr, flags);
1661 if (r < 0)
1662 goto fail;
1663
1664 r = dns_packet_read_uint8(p, &proto, NULL);
1665 if (r < 0)
1666 goto fail;
1667
1668 /* protocol is required to be always 3 */
1669 if (proto != 3) {
1670 r = -EBADMSG;
1671 goto fail;
1672 }
1673
1674 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1675 if (r < 0)
1676 goto fail;
1677
1678 r = dns_packet_read_memdup(p, rdlength - 4,
1679 &rr->dnskey.key, &rr->dnskey.key_size,
1680 NULL);
1681
1682 if (rr->dnskey.key_size <= 0) {
1683 /* the accepted size depends on the algorithm, but for now
1684 just ensure that the value is greater than zero */
1685 r = -EBADMSG;
1686 goto fail;
1687 }
1688
1689 break;
1690 }
1691
1692 case DNS_TYPE_RRSIG:
1693 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1694 if (r < 0)
1695 goto fail;
1696
1697 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1698 if (r < 0)
1699 goto fail;
1700
1701 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1702 if (r < 0)
1703 goto fail;
1704
1705 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1706 if (r < 0)
1707 goto fail;
1708
1709 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1710 if (r < 0)
1711 goto fail;
1712
1713 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1714 if (r < 0)
1715 goto fail;
1716
1717 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1718 if (r < 0)
1719 goto fail;
1720
1721 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1722 if (r < 0)
1723 goto fail;
1724
1725 r = dns_packet_read_memdup(p, offset + rdlength - p->rindex,
1726 &rr->rrsig.signature, &rr->rrsig.signature_size,
1727 NULL);
1728
1729 if (rr->rrsig.signature_size <= 0) {
1730 /* the accepted size depends on the algorithm, but for now
1731 just ensure that the value is greater than zero */
1732 r = -EBADMSG;
1733 goto fail;
1734 }
1735
1736 break;
1737
1738 case DNS_TYPE_NSEC:
1739 r = dns_packet_read_name(p, &rr->nsec.next_domain_name, false, NULL);
1740 if (r < 0)
1741 goto fail;
1742
1743 r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL);
1744 if (r < 0)
1745 goto fail;
1746
1747 /* The types bitmap must contain at least the NSEC record itself, so an empty bitmap means
1748 something went wrong */
1749 if (bitmap_isclear(rr->nsec.types)) {
1750 r = -EBADMSG;
1751 goto fail;
1752 }
1753
1754 break;
1755
1756 case DNS_TYPE_NSEC3: {
1757 uint8_t size;
1758
1759 r = dns_packet_read_uint8(p, &rr->nsec3.algorithm, NULL);
1760 if (r < 0)
1761 goto fail;
1762
1763 r = dns_packet_read_uint8(p, &rr->nsec3.flags, NULL);
1764 if (r < 0)
1765 goto fail;
1766
1767 r = dns_packet_read_uint16(p, &rr->nsec3.iterations, NULL);
1768 if (r < 0)
1769 goto fail;
1770
1771 /* this may be zero */
1772 r = dns_packet_read_uint8(p, &size, NULL);
1773 if (r < 0)
1774 goto fail;
1775
1776 r = dns_packet_read_memdup(p, size, &rr->nsec3.salt, &rr->nsec3.salt_size, NULL);
1777 if (r < 0)
1778 goto fail;
1779
1780 r = dns_packet_read_uint8(p, &size, NULL);
1781 if (r < 0)
1782 goto fail;
1783
1784 if (size <= 0) {
1785 r = -EBADMSG;
1786 goto fail;
1787 }
1788
1789 r = dns_packet_read_memdup(p, size, &rr->nsec3.next_hashed_name, &rr->nsec3.next_hashed_name_size, NULL);
1790 if (r < 0)
1791 goto fail;
1792
1793 r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL);
1794 if (r < 0)
1795 goto fail;
1796
1797 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
1798
1799 break;
1800 }
1801 default:
1802 unparseable:
1803 r = dns_packet_read_memdup(p, rdlength, &rr->generic.data, &rr->generic.size, NULL);
1804 if (r < 0)
1805 goto fail;
1806 break;
1807 }
1808 if (r < 0)
1809 goto fail;
1810 if (p->rindex != offset + rdlength) {
1811 r = -EBADMSG;
1812 goto fail;
1813 }
1814
1815 *ret = rr;
1816 rr = NULL;
1817
1818 if (start)
1819 *start = saved_rindex;
1820
1821 return 0;
1822 fail:
1823 dns_packet_rewind(p, saved_rindex);
1824 return r;
1825 }
1826
1827 int dns_packet_extract(DnsPacket *p) {
1828 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1829 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1830 size_t saved_rindex;
1831 unsigned n, i;
1832 int r;
1833
1834 if (p->extracted)
1835 return 0;
1836
1837 saved_rindex = p->rindex;
1838 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1839
1840 n = DNS_PACKET_QDCOUNT(p);
1841 if (n > 0) {
1842 question = dns_question_new(n);
1843 if (!question) {
1844 r = -ENOMEM;
1845 goto finish;
1846 }
1847
1848 for (i = 0; i < n; i++) {
1849 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1850
1851 r = dns_packet_read_key(p, &key, NULL);
1852 if (r < 0)
1853 goto finish;
1854
1855 r = dns_question_add(question, key);
1856 if (r < 0)
1857 goto finish;
1858 }
1859 }
1860
1861 n = DNS_PACKET_RRCOUNT(p);
1862 if (n > 0) {
1863 answer = dns_answer_new(n);
1864 if (!answer) {
1865 r = -ENOMEM;
1866 goto finish;
1867 }
1868
1869 for (i = 0; i < n; i++) {
1870 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1871
1872 r = dns_packet_read_rr(p, &rr, NULL);
1873 if (r < 0)
1874 goto finish;
1875
1876 r = dns_answer_add(answer, rr, p->ifindex);
1877 if (r < 0)
1878 goto finish;
1879 }
1880 }
1881
1882 p->question = question;
1883 question = NULL;
1884
1885 p->answer = answer;
1886 answer = NULL;
1887
1888 p->extracted = true;
1889
1890 r = 0;
1891
1892 finish:
1893 p->rindex = saved_rindex;
1894 return r;
1895 }
1896
1897 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
1898 [DNS_RCODE_SUCCESS] = "SUCCESS",
1899 [DNS_RCODE_FORMERR] = "FORMERR",
1900 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
1901 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
1902 [DNS_RCODE_NOTIMP] = "NOTIMP",
1903 [DNS_RCODE_REFUSED] = "REFUSED",
1904 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
1905 [DNS_RCODE_YXRRSET] = "YRRSET",
1906 [DNS_RCODE_NXRRSET] = "NXRRSET",
1907 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
1908 [DNS_RCODE_NOTZONE] = "NOTZONE",
1909 [DNS_RCODE_BADVERS] = "BADVERS",
1910 [DNS_RCODE_BADKEY] = "BADKEY",
1911 [DNS_RCODE_BADTIME] = "BADTIME",
1912 [DNS_RCODE_BADMODE] = "BADMODE",
1913 [DNS_RCODE_BADNAME] = "BADNAME",
1914 [DNS_RCODE_BADALG] = "BADALG",
1915 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
1916 };
1917 DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1918
1919 static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
1920 [DNS_PROTOCOL_DNS] = "dns",
1921 [DNS_PROTOCOL_MDNS] = "mdns",
1922 [DNS_PROTOCOL_LLMNR] = "llmnr",
1923 };
1924 DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
1925
1926 static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
1927 [DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
1928 [DNSSEC_ALGORITHM_DH] = "DH",
1929 [DNSSEC_ALGORITHM_DSA] = "DSA",
1930 [DNSSEC_ALGORITHM_ECC] = "ECC",
1931 [DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
1932 [DNSSEC_ALGORITHM_DSA_NSEC3_SHA1] = "DSA-NSEC3-SHA1",
1933 [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1] = "RSASHA1-NSEC3-SHA1",
1934 [DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
1935 [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
1936 [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
1937 };
1938 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);