]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-packet.c
dns-domain: add code for verifying validity of DNS-SD service names and types
[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_label(DnsPacket *p, const char *d, size_t l, size_t *start) {
374 void *w;
375 int r;
376
377 assert(p);
378 assert(d);
379
380 if (l > DNS_LABEL_MAX)
381 return -E2BIG;
382
383 r = dns_packet_extend(p, 1 + l, &w, start);
384 if (r < 0)
385 return r;
386
387 ((uint8_t*) w)[0] = (uint8_t) l;
388 memcpy(((uint8_t*) w) + 1, d, l);
389
390 return 0;
391 }
392
393 int dns_packet_append_name(
394 DnsPacket *p,
395 const char *name,
396 bool allow_compression,
397 size_t *start) {
398
399 size_t saved_size;
400 int r;
401
402 assert(p);
403 assert(name);
404
405 if (p->refuse_compression)
406 allow_compression = false;
407
408 saved_size = p->size;
409
410 while (*name) {
411 _cleanup_free_ char *s = NULL;
412 char label[DNS_LABEL_MAX];
413 size_t n = 0;
414 int k;
415
416 if (allow_compression)
417 n = PTR_TO_SIZE(hashmap_get(p->names, name));
418 if (n > 0) {
419 assert(n < p->size);
420
421 if (n < 0x4000) {
422 r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
423 if (r < 0)
424 goto fail;
425
426 goto done;
427 }
428 }
429
430 s = strdup(name);
431 if (!s) {
432 r = -ENOMEM;
433 goto fail;
434 }
435
436 r = dns_label_unescape(&name, label, sizeof(label));
437 if (r < 0)
438 goto fail;
439
440 if (p->protocol == DNS_PROTOCOL_DNS)
441 k = dns_label_apply_idna(label, r, label, sizeof(label));
442 else
443 k = dns_label_undo_idna(label, r, label, sizeof(label));
444 if (k < 0) {
445 r = k;
446 goto fail;
447 }
448 if (k > 0)
449 r = k;
450
451 r = dns_packet_append_label(p, label, r, &n);
452 if (r < 0)
453 goto fail;
454
455 if (allow_compression) {
456 r = hashmap_ensure_allocated(&p->names, &dns_name_hash_ops);
457 if (r < 0)
458 goto fail;
459
460 r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
461 if (r < 0)
462 goto fail;
463
464 s = NULL;
465 }
466 }
467
468 r = dns_packet_append_uint8(p, 0, NULL);
469 if (r < 0)
470 return r;
471
472 done:
473 if (start)
474 *start = saved_size;
475
476 return 0;
477
478 fail:
479 dns_packet_truncate(p, saved_size);
480 return r;
481 }
482
483 int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
484 size_t saved_size;
485 int r;
486
487 assert(p);
488 assert(k);
489
490 saved_size = p->size;
491
492 r = dns_packet_append_name(p, DNS_RESOURCE_KEY_NAME(k), true, NULL);
493 if (r < 0)
494 goto fail;
495
496 r = dns_packet_append_uint16(p, k->type, NULL);
497 if (r < 0)
498 goto fail;
499
500 r = dns_packet_append_uint16(p, k->class, NULL);
501 if (r < 0)
502 goto fail;
503
504 if (start)
505 *start = saved_size;
506
507 return 0;
508
509 fail:
510 dns_packet_truncate(p, saved_size);
511 return r;
512 }
513
514 static int dns_packet_append_type_window(DnsPacket *p, uint8_t window, uint8_t length, uint8_t *types, size_t *start) {
515 size_t saved_size;
516 int r;
517
518 assert(p);
519 assert(types);
520 assert(length > 0);
521
522 saved_size = p->size;
523
524 r = dns_packet_append_uint8(p, window, NULL);
525 if (r < 0)
526 goto fail;
527
528 r = dns_packet_append_uint8(p, length, NULL);
529 if (r < 0)
530 goto fail;
531
532 r = dns_packet_append_blob(p, types, length, NULL);
533 if (r < 0)
534 goto fail;
535
536 if (start)
537 *start = saved_size;
538
539 return 0;
540 fail:
541 dns_packet_truncate(p, saved_size);
542 return r;
543 }
544
545 static int dns_packet_append_types(DnsPacket *p, Bitmap *types, size_t *start) {
546 Iterator i;
547 uint8_t window = 0;
548 uint8_t entry = 0;
549 uint8_t bitmaps[32] = {};
550 unsigned n;
551 size_t saved_size;
552 int r;
553
554 assert(p);
555 assert(types);
556
557 saved_size = p->size;
558
559 BITMAP_FOREACH(n, types, i) {
560 assert(n <= 0xffff);
561
562 if ((n >> 8) != window && bitmaps[entry / 8] != 0) {
563 r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
564 if (r < 0)
565 goto fail;
566
567 zero(bitmaps);
568 }
569
570 window = n >> 8;
571
572 entry = n & 255;
573
574 bitmaps[entry / 8] |= 1 << (7 - (entry % 8));
575 }
576
577 r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
578 if (r < 0)
579 goto fail;
580
581 if (start)
582 *start = saved_size;
583
584 return 0;
585 fail:
586 dns_packet_truncate(p, saved_size);
587 return r;
588 }
589
590 int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start) {
591 size_t saved_size, rdlength_offset, end, rdlength;
592 int r;
593
594 assert(p);
595 assert(rr);
596
597 saved_size = p->size;
598
599 r = dns_packet_append_key(p, rr->key, NULL);
600 if (r < 0)
601 goto fail;
602
603 r = dns_packet_append_uint32(p, rr->ttl, NULL);
604 if (r < 0)
605 goto fail;
606
607 /* Initially we write 0 here */
608 r = dns_packet_append_uint16(p, 0, &rdlength_offset);
609 if (r < 0)
610 goto fail;
611
612 switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
613
614 case DNS_TYPE_SRV:
615 r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
616 if (r < 0)
617 goto fail;
618
619 r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
620 if (r < 0)
621 goto fail;
622
623 r = dns_packet_append_uint16(p, rr->srv.port, NULL);
624 if (r < 0)
625 goto fail;
626
627 r = dns_packet_append_name(p, rr->srv.name, true, NULL);
628 break;
629
630 case DNS_TYPE_PTR:
631 case DNS_TYPE_NS:
632 case DNS_TYPE_CNAME:
633 case DNS_TYPE_DNAME:
634 r = dns_packet_append_name(p, rr->ptr.name, true, NULL);
635 break;
636
637 case DNS_TYPE_HINFO:
638 r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
639 if (r < 0)
640 goto fail;
641
642 r = dns_packet_append_string(p, rr->hinfo.os, NULL);
643 break;
644
645 case DNS_TYPE_SPF: /* exactly the same as TXT */
646 case DNS_TYPE_TXT: {
647 char **s;
648
649 if (strv_isempty(rr->txt.strings)) {
650 /* RFC 6763, section 6.1 suggests to generate
651 * single empty string for an empty array. */
652
653 r = dns_packet_append_string(p, "", NULL);
654 if (r < 0)
655 goto fail;
656 } else {
657 STRV_FOREACH(s, rr->txt.strings) {
658 r = dns_packet_append_string(p, *s, NULL);
659 if (r < 0)
660 goto fail;
661 }
662 }
663
664 r = 0;
665 break;
666 }
667
668 case DNS_TYPE_A:
669 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
670 break;
671
672 case DNS_TYPE_AAAA:
673 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
674 break;
675
676 case DNS_TYPE_SOA:
677 r = dns_packet_append_name(p, rr->soa.mname, true, NULL);
678 if (r < 0)
679 goto fail;
680
681 r = dns_packet_append_name(p, rr->soa.rname, true, NULL);
682 if (r < 0)
683 goto fail;
684
685 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
686 if (r < 0)
687 goto fail;
688
689 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
690 if (r < 0)
691 goto fail;
692
693 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
694 if (r < 0)
695 goto fail;
696
697 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
698 if (r < 0)
699 goto fail;
700
701 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
702 break;
703
704 case DNS_TYPE_MX:
705 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
706 if (r < 0)
707 goto fail;
708
709 r = dns_packet_append_name(p, rr->mx.exchange, true, NULL);
710 break;
711
712 case DNS_TYPE_LOC:
713 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
714 if (r < 0)
715 goto fail;
716
717 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
718 if (r < 0)
719 goto fail;
720
721 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
722 if (r < 0)
723 goto fail;
724
725 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
726 if (r < 0)
727 goto fail;
728
729 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
730 if (r < 0)
731 goto fail;
732
733 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
734 if (r < 0)
735 goto fail;
736
737 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
738 break;
739
740 case DNS_TYPE_DS:
741 r = dns_packet_append_uint16(p, rr->ds.key_tag, NULL);
742 if (r < 0)
743 goto fail;
744
745 r = dns_packet_append_uint8(p, rr->ds.algorithm, NULL);
746 if (r < 0)
747 goto fail;
748
749 r = dns_packet_append_uint8(p, rr->ds.digest_type, NULL);
750 if (r < 0)
751 goto fail;
752
753 r = dns_packet_append_blob(p, rr->ds.digest, rr->ds.digest_size, NULL);
754 break;
755
756 case DNS_TYPE_SSHFP:
757 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
758 if (r < 0)
759 goto fail;
760
761 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
762 if (r < 0)
763 goto fail;
764
765 r = dns_packet_append_blob(p, rr->sshfp.fingerprint, rr->sshfp.fingerprint_size, NULL);
766 break;
767
768 case DNS_TYPE_DNSKEY:
769 r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
770 if (r < 0)
771 goto fail;
772
773 r = dns_packet_append_uint8(p, 3u, NULL);
774 if (r < 0)
775 goto fail;
776
777 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
778 if (r < 0)
779 goto fail;
780
781 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
782 break;
783
784 case DNS_TYPE_RRSIG:
785 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
786 if (r < 0)
787 goto fail;
788
789 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
790 if (r < 0)
791 goto fail;
792
793 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
794 if (r < 0)
795 goto fail;
796
797 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
798 if (r < 0)
799 goto fail;
800
801 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
802 if (r < 0)
803 goto fail;
804
805 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
806 if (r < 0)
807 goto fail;
808
809 r = dns_packet_append_uint16(p, rr->rrsig.key_tag, NULL);
810 if (r < 0)
811 goto fail;
812
813 r = dns_packet_append_name(p, rr->rrsig.signer, false, NULL);
814 if (r < 0)
815 goto fail;
816
817 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
818 break;
819
820 case DNS_TYPE_NSEC:
821 r = dns_packet_append_name(p, rr->nsec.next_domain_name, false, NULL);
822 if (r < 0)
823 goto fail;
824
825 r = dns_packet_append_types(p, rr->nsec.types, NULL);
826 if (r < 0)
827 goto fail;
828
829 break;
830 case DNS_TYPE_NSEC3:
831 r = dns_packet_append_uint8(p, rr->nsec3.algorithm, NULL);
832 if (r < 0)
833 goto fail;
834
835 r = dns_packet_append_uint8(p, rr->nsec3.flags, NULL);
836 if (r < 0)
837 goto fail;
838
839 r = dns_packet_append_uint16(p, rr->nsec3.iterations, NULL);
840 if (r < 0)
841 goto fail;
842
843 r = dns_packet_append_uint8(p, rr->nsec3.salt_size, NULL);
844 if (r < 0)
845 goto fail;
846
847 r = dns_packet_append_blob(p, rr->nsec3.salt, rr->nsec3.salt_size, NULL);
848 if (r < 0)
849 goto fail;
850
851 r = dns_packet_append_uint8(p, rr->nsec3.next_hashed_name_size, NULL);
852 if (r < 0)
853 goto fail;
854
855 r = dns_packet_append_blob(p, rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, NULL);
856 if (r < 0)
857 goto fail;
858
859 r = dns_packet_append_types(p, rr->nsec3.types, NULL);
860 if (r < 0)
861 goto fail;
862
863 break;
864 case _DNS_TYPE_INVALID: /* unparseable */
865 default:
866
867 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
868 break;
869 }
870 if (r < 0)
871 goto fail;
872
873 /* Let's calculate the actual data size and update the field */
874 rdlength = p->size - rdlength_offset - sizeof(uint16_t);
875 if (rdlength > 0xFFFF) {
876 r = ENOSPC;
877 goto fail;
878 }
879
880 end = p->size;
881 p->size = rdlength_offset;
882 r = dns_packet_append_uint16(p, rdlength, NULL);
883 if (r < 0)
884 goto fail;
885 p->size = end;
886
887 if (start)
888 *start = saved_size;
889
890 return 0;
891
892 fail:
893 dns_packet_truncate(p, saved_size);
894 return r;
895 }
896
897
898 int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
899 assert(p);
900
901 if (p->rindex + sz > p->size)
902 return -EMSGSIZE;
903
904 if (ret)
905 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
906
907 if (start)
908 *start = p->rindex;
909
910 p->rindex += sz;
911 return 0;
912 }
913
914 void dns_packet_rewind(DnsPacket *p, size_t idx) {
915 assert(p);
916 assert(idx <= p->size);
917 assert(idx >= DNS_PACKET_HEADER_SIZE);
918
919 p->rindex = idx;
920 }
921
922 int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
923 const void *q;
924 int r;
925
926 assert(p);
927 assert(d);
928
929 r = dns_packet_read(p, sz, &q, start);
930 if (r < 0)
931 return r;
932
933 memcpy(d, q, sz);
934 return 0;
935 }
936
937 static int dns_packet_read_memdup(
938 DnsPacket *p, size_t size,
939 void **ret, size_t *ret_size,
940 size_t *ret_start) {
941
942 const void *src;
943 size_t start;
944 int r;
945
946 assert(p);
947 assert(ret);
948
949 r = dns_packet_read(p, size, &src, &start);
950 if (r < 0)
951 return r;
952
953 if (size <= 0)
954 *ret = NULL;
955 else {
956 void *copy;
957
958 copy = memdup(src, size);
959 if (!copy)
960 return -ENOMEM;
961
962 *ret = copy;
963 }
964
965 if (ret_size)
966 *ret_size = size;
967 if (ret_start)
968 *ret_start = start;
969
970 return 0;
971 }
972
973 int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
974 const void *d;
975 int r;
976
977 assert(p);
978
979 r = dns_packet_read(p, sizeof(uint8_t), &d, start);
980 if (r < 0)
981 return r;
982
983 *ret = ((uint8_t*) d)[0];
984 return 0;
985 }
986
987 int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
988 const void *d;
989 int r;
990
991 assert(p);
992
993 r = dns_packet_read(p, sizeof(uint16_t), &d, start);
994 if (r < 0)
995 return r;
996
997 *ret = unaligned_read_be16(d);
998
999 return 0;
1000 }
1001
1002 int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
1003 const void *d;
1004 int r;
1005
1006 assert(p);
1007
1008 r = dns_packet_read(p, sizeof(uint32_t), &d, start);
1009 if (r < 0)
1010 return r;
1011
1012 *ret = unaligned_read_be32(d);
1013
1014 return 0;
1015 }
1016
1017 int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
1018 size_t saved_rindex;
1019 const void *d;
1020 char *t;
1021 uint8_t c;
1022 int r;
1023
1024 assert(p);
1025
1026 saved_rindex = p->rindex;
1027
1028 r = dns_packet_read_uint8(p, &c, NULL);
1029 if (r < 0)
1030 goto fail;
1031
1032 r = dns_packet_read(p, c, &d, NULL);
1033 if (r < 0)
1034 goto fail;
1035
1036 if (memchr(d, 0, c)) {
1037 r = -EBADMSG;
1038 goto fail;
1039 }
1040
1041 t = strndup(d, c);
1042 if (!t) {
1043 r = -ENOMEM;
1044 goto fail;
1045 }
1046
1047 if (!utf8_is_valid(t)) {
1048 free(t);
1049 r = -EBADMSG;
1050 goto fail;
1051 }
1052
1053 *ret = t;
1054
1055 if (start)
1056 *start = saved_rindex;
1057
1058 return 0;
1059
1060 fail:
1061 dns_packet_rewind(p, saved_rindex);
1062 return r;
1063 }
1064
1065 int dns_packet_read_name(
1066 DnsPacket *p,
1067 char **_ret,
1068 bool allow_compression,
1069 size_t *start) {
1070
1071 size_t saved_rindex, after_rindex = 0, jump_barrier;
1072 _cleanup_free_ char *ret = NULL;
1073 size_t n = 0, allocated = 0;
1074 bool first = true;
1075 int r;
1076
1077 assert(p);
1078 assert(_ret);
1079
1080 if (p->refuse_compression)
1081 allow_compression = false;
1082
1083 saved_rindex = p->rindex;
1084 jump_barrier = p->rindex;
1085
1086 for (;;) {
1087 uint8_t c, d;
1088
1089 r = dns_packet_read_uint8(p, &c, NULL);
1090 if (r < 0)
1091 goto fail;
1092
1093 if (c == 0)
1094 /* End of name */
1095 break;
1096 else if (c <= 63) {
1097 _cleanup_free_ char *t = NULL;
1098 const char *label;
1099
1100 /* Literal label */
1101 r = dns_packet_read(p, c, (const void**) &label, NULL);
1102 if (r < 0)
1103 goto fail;
1104
1105 r = dns_label_escape(label, c, &t);
1106 if (r < 0)
1107 goto fail;
1108
1109 if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) {
1110 r = -ENOMEM;
1111 goto fail;
1112 }
1113
1114 if (!first)
1115 ret[n++] = '.';
1116 else
1117 first = false;
1118
1119 memcpy(ret + n, t, r);
1120 n += r;
1121 continue;
1122 } else if (allow_compression && (c & 0xc0) == 0xc0) {
1123 uint16_t ptr;
1124
1125 /* Pointer */
1126 r = dns_packet_read_uint8(p, &d, NULL);
1127 if (r < 0)
1128 goto fail;
1129
1130 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
1131 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier) {
1132 r = -EBADMSG;
1133 goto fail;
1134 }
1135
1136 if (after_rindex == 0)
1137 after_rindex = p->rindex;
1138
1139 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1140 jump_barrier = ptr;
1141 p->rindex = ptr;
1142 } else {
1143 r = -EBADMSG;
1144 goto fail;
1145 }
1146 }
1147
1148 if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
1149 r = -ENOMEM;
1150 goto fail;
1151 }
1152
1153 ret[n] = 0;
1154
1155 if (after_rindex != 0)
1156 p->rindex= after_rindex;
1157
1158 *_ret = ret;
1159 ret = NULL;
1160
1161 if (start)
1162 *start = saved_rindex;
1163
1164 return 0;
1165
1166 fail:
1167 dns_packet_rewind(p, saved_rindex);
1168 return r;
1169 }
1170
1171 static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *start) {
1172 uint8_t window;
1173 uint8_t length;
1174 const uint8_t *bitmap;
1175 uint8_t bit = 0;
1176 unsigned i;
1177 bool found = false;
1178 size_t saved_rindex;
1179 int r;
1180
1181 assert(p);
1182 assert(types);
1183
1184 saved_rindex = p->rindex;
1185
1186 r = bitmap_ensure_allocated(types);
1187 if (r < 0)
1188 goto fail;
1189
1190 r = dns_packet_read_uint8(p, &window, NULL);
1191 if (r < 0)
1192 goto fail;
1193
1194 r = dns_packet_read_uint8(p, &length, NULL);
1195 if (r < 0)
1196 goto fail;
1197
1198 if (length == 0 || length > 32)
1199 return -EBADMSG;
1200
1201 r = dns_packet_read(p, length, (const void **)&bitmap, NULL);
1202 if (r < 0)
1203 goto fail;
1204
1205 for (i = 0; i < length; i++) {
1206 uint8_t bitmask = 1 << 7;
1207
1208 if (!bitmap[i]) {
1209 found = false;
1210 bit += 8;
1211 continue;
1212 }
1213
1214 found = true;
1215
1216 while (bitmask) {
1217 if (bitmap[i] & bitmask) {
1218 uint16_t n;
1219
1220 n = (uint16_t) window << 8 | (uint16_t) bit;
1221
1222 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1223 if (dns_type_is_pseudo(n))
1224 continue;
1225
1226 r = bitmap_set(*types, n);
1227 if (r < 0)
1228 goto fail;
1229 }
1230
1231 bit ++;
1232 bitmask >>= 1;
1233 }
1234 }
1235
1236 if (!found)
1237 return -EBADMSG;
1238
1239 if (start)
1240 *start = saved_rindex;
1241
1242 return 0;
1243 fail:
1244 dns_packet_rewind(p, saved_rindex);
1245 return r;
1246 }
1247
1248 static int dns_packet_read_type_windows(DnsPacket *p, Bitmap **types, size_t size, size_t *start) {
1249 size_t saved_rindex;
1250 int r;
1251
1252 saved_rindex = p->rindex;
1253
1254 while (p->rindex < saved_rindex + size) {
1255 r = dns_packet_read_type_window(p, types, NULL);
1256 if (r < 0)
1257 goto fail;
1258
1259 /* don't read past end of current RR */
1260 if (p->rindex > saved_rindex + size) {
1261 r = -EBADMSG;
1262 goto fail;
1263 }
1264 }
1265
1266 if (p->rindex != saved_rindex + size) {
1267 r = -EBADMSG;
1268 goto fail;
1269 }
1270
1271 if (start)
1272 *start = saved_rindex;
1273
1274 return 0;
1275 fail:
1276 dns_packet_rewind(p, saved_rindex);
1277 return r;
1278 }
1279
1280 int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
1281 _cleanup_free_ char *name = NULL;
1282 uint16_t class, type;
1283 DnsResourceKey *key;
1284 size_t saved_rindex;
1285 int r;
1286
1287 assert(p);
1288 assert(ret);
1289
1290 saved_rindex = p->rindex;
1291
1292 r = dns_packet_read_name(p, &name, true, NULL);
1293 if (r < 0)
1294 goto fail;
1295
1296 r = dns_packet_read_uint16(p, &type, NULL);
1297 if (r < 0)
1298 goto fail;
1299
1300 r = dns_packet_read_uint16(p, &class, NULL);
1301 if (r < 0)
1302 goto fail;
1303
1304 key = dns_resource_key_new_consume(class, type, name);
1305 if (!key) {
1306 r = -ENOMEM;
1307 goto fail;
1308 }
1309
1310 name = NULL;
1311 *ret = key;
1312
1313 if (start)
1314 *start = saved_rindex;
1315
1316 return 0;
1317 fail:
1318 dns_packet_rewind(p, saved_rindex);
1319 return r;
1320 }
1321
1322 static bool loc_size_ok(uint8_t size) {
1323 uint8_t m = size >> 4, e = size & 0xF;
1324
1325 return m <= 9 && e <= 9 && (m > 0 || e == 0);
1326 }
1327
1328 static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
1329 assert(rr);
1330
1331 if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
1332 return -EBADMSG;
1333
1334 rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
1335 rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
1336 return 0;
1337 }
1338
1339 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
1340 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1341 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1342 size_t saved_rindex, offset;
1343 uint16_t rdlength;
1344 int r;
1345
1346 assert(p);
1347 assert(ret);
1348
1349 saved_rindex = p->rindex;
1350
1351 r = dns_packet_read_key(p, &key, NULL);
1352 if (r < 0)
1353 goto fail;
1354
1355 if (key->class == DNS_CLASS_ANY ||
1356 key->type == DNS_TYPE_ANY) {
1357 r = -EBADMSG;
1358 goto fail;
1359 }
1360
1361 rr = dns_resource_record_new(key);
1362 if (!rr) {
1363 r = -ENOMEM;
1364 goto fail;
1365 }
1366
1367 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1368 if (r < 0)
1369 goto fail;
1370
1371 r = dns_packet_read_uint16(p, &rdlength, NULL);
1372 if (r < 0)
1373 goto fail;
1374
1375 if (p->rindex + rdlength > p->size) {
1376 r = -EBADMSG;
1377 goto fail;
1378 }
1379
1380 offset = p->rindex;
1381
1382 switch (rr->key->type) {
1383
1384 case DNS_TYPE_SRV:
1385 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1386 if (r < 0)
1387 goto fail;
1388 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1389 if (r < 0)
1390 goto fail;
1391 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1392 if (r < 0)
1393 goto fail;
1394 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
1395 break;
1396
1397 case DNS_TYPE_PTR:
1398 case DNS_TYPE_NS:
1399 case DNS_TYPE_CNAME:
1400 case DNS_TYPE_DNAME:
1401 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
1402 break;
1403
1404 case DNS_TYPE_HINFO:
1405 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1406 if (r < 0)
1407 goto fail;
1408
1409 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1410 break;
1411
1412 case DNS_TYPE_SPF: /* exactly the same as TXT */
1413 case DNS_TYPE_TXT:
1414 if (rdlength <= 0) {
1415 /* RFC 6763, section 6.1 suggests to treat
1416 * empty TXT RRs as equivalent to a TXT record
1417 * with a single empty string. */
1418
1419 r = strv_extend(&rr->txt.strings, "");
1420 if (r < 0)
1421 goto fail;
1422 } else {
1423 while (p->rindex < offset + rdlength) {
1424 char *s;
1425
1426 r = dns_packet_read_string(p, &s, NULL);
1427 if (r < 0)
1428 goto fail;
1429
1430 r = strv_consume(&rr->txt.strings, s);
1431 if (r < 0)
1432 goto fail;
1433 }
1434 }
1435
1436 r = 0;
1437 break;
1438
1439 case DNS_TYPE_A:
1440 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1441 break;
1442
1443 case DNS_TYPE_AAAA:
1444 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1445 break;
1446
1447 case DNS_TYPE_SOA:
1448 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
1449 if (r < 0)
1450 goto fail;
1451
1452 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
1453 if (r < 0)
1454 goto fail;
1455
1456 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1457 if (r < 0)
1458 goto fail;
1459
1460 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1461 if (r < 0)
1462 goto fail;
1463
1464 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1465 if (r < 0)
1466 goto fail;
1467
1468 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1469 if (r < 0)
1470 goto fail;
1471
1472 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1473 break;
1474
1475 case DNS_TYPE_MX:
1476 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1477 if (r < 0)
1478 goto fail;
1479
1480 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
1481 break;
1482
1483 case DNS_TYPE_LOC: {
1484 uint8_t t;
1485 size_t pos;
1486
1487 r = dns_packet_read_uint8(p, &t, &pos);
1488 if (r < 0)
1489 goto fail;
1490
1491 if (t == 0) {
1492 rr->loc.version = t;
1493
1494 r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1495 if (r < 0)
1496 goto fail;
1497
1498 if (!loc_size_ok(rr->loc.size)) {
1499 r = -EBADMSG;
1500 goto fail;
1501 }
1502
1503 r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1504 if (r < 0)
1505 goto fail;
1506
1507 if (!loc_size_ok(rr->loc.horiz_pre)) {
1508 r = -EBADMSG;
1509 goto fail;
1510 }
1511
1512 r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1513 if (r < 0)
1514 goto fail;
1515
1516 if (!loc_size_ok(rr->loc.vert_pre)) {
1517 r = -EBADMSG;
1518 goto fail;
1519 }
1520
1521 r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1522 if (r < 0)
1523 goto fail;
1524
1525 r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1526 if (r < 0)
1527 goto fail;
1528
1529 r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1530 if (r < 0)
1531 goto fail;
1532
1533 break;
1534 } else {
1535 dns_packet_rewind(p, pos);
1536 rr->unparseable = true;
1537 goto unparseable;
1538 }
1539 }
1540
1541 case DNS_TYPE_DS:
1542 r = dns_packet_read_uint16(p, &rr->ds.key_tag, NULL);
1543 if (r < 0)
1544 goto fail;
1545
1546 r = dns_packet_read_uint8(p, &rr->ds.algorithm, NULL);
1547 if (r < 0)
1548 goto fail;
1549
1550 r = dns_packet_read_uint8(p, &rr->ds.digest_type, NULL);
1551 if (r < 0)
1552 goto fail;
1553
1554 r = dns_packet_read_memdup(p, rdlength - 4,
1555 &rr->ds.digest, &rr->ds.digest_size,
1556 NULL);
1557 if (r < 0)
1558 goto fail;
1559
1560 if (rr->ds.digest_size <= 0) {
1561 /* the accepted size depends on the algorithm, but for now
1562 just ensure that the value is greater than zero */
1563 r = -EBADMSG;
1564 goto fail;
1565 }
1566
1567 break;
1568 case DNS_TYPE_SSHFP:
1569 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1570 if (r < 0)
1571 goto fail;
1572
1573 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1574 if (r < 0)
1575 goto fail;
1576
1577 r = dns_packet_read_memdup(p, rdlength - 2,
1578 &rr->sshfp.fingerprint, &rr->sshfp.fingerprint_size,
1579 NULL);
1580
1581 if (rr->sshfp.fingerprint_size <= 0) {
1582 /* the accepted size depends on the algorithm, but for now
1583 just ensure that the value is greater than zero */
1584 r = -EBADMSG;
1585 goto fail;
1586 }
1587
1588 break;
1589
1590 case DNS_TYPE_DNSKEY: {
1591 uint16_t flags;
1592 uint8_t proto;
1593
1594 r = dns_packet_read_uint16(p, &flags, NULL);
1595 if (r < 0)
1596 goto fail;
1597
1598 r = dnskey_parse_flags(rr, flags);
1599 if (r < 0)
1600 goto fail;
1601
1602 r = dns_packet_read_uint8(p, &proto, NULL);
1603 if (r < 0)
1604 goto fail;
1605
1606 /* protocol is required to be always 3 */
1607 if (proto != 3) {
1608 r = -EBADMSG;
1609 goto fail;
1610 }
1611
1612 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1613 if (r < 0)
1614 goto fail;
1615
1616 r = dns_packet_read_memdup(p, rdlength - 4,
1617 &rr->dnskey.key, &rr->dnskey.key_size,
1618 NULL);
1619
1620 if (rr->dnskey.key_size <= 0) {
1621 /* the accepted size depends on the algorithm, but for now
1622 just ensure that the value is greater than zero */
1623 r = -EBADMSG;
1624 goto fail;
1625 }
1626
1627 break;
1628 }
1629
1630 case DNS_TYPE_RRSIG:
1631 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1632 if (r < 0)
1633 goto fail;
1634
1635 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1636 if (r < 0)
1637 goto fail;
1638
1639 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1640 if (r < 0)
1641 goto fail;
1642
1643 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1644 if (r < 0)
1645 goto fail;
1646
1647 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1648 if (r < 0)
1649 goto fail;
1650
1651 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1652 if (r < 0)
1653 goto fail;
1654
1655 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1656 if (r < 0)
1657 goto fail;
1658
1659 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1660 if (r < 0)
1661 goto fail;
1662
1663 r = dns_packet_read_memdup(p, offset + rdlength - p->rindex,
1664 &rr->rrsig.signature, &rr->rrsig.signature_size,
1665 NULL);
1666
1667 if (rr->rrsig.signature_size <= 0) {
1668 /* the accepted size depends on the algorithm, but for now
1669 just ensure that the value is greater than zero */
1670 r = -EBADMSG;
1671 goto fail;
1672 }
1673
1674 break;
1675
1676 case DNS_TYPE_NSEC:
1677 r = dns_packet_read_name(p, &rr->nsec.next_domain_name, false, NULL);
1678 if (r < 0)
1679 goto fail;
1680
1681 r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL);
1682 if (r < 0)
1683 goto fail;
1684
1685 /* The types bitmap must contain at least the NSEC record itself, so an empty bitmap means
1686 something went wrong */
1687 if (bitmap_isclear(rr->nsec.types)) {
1688 r = -EBADMSG;
1689 goto fail;
1690 }
1691
1692 break;
1693
1694 case DNS_TYPE_NSEC3: {
1695 uint8_t size;
1696
1697 r = dns_packet_read_uint8(p, &rr->nsec3.algorithm, NULL);
1698 if (r < 0)
1699 goto fail;
1700
1701 r = dns_packet_read_uint8(p, &rr->nsec3.flags, NULL);
1702 if (r < 0)
1703 goto fail;
1704
1705 r = dns_packet_read_uint16(p, &rr->nsec3.iterations, NULL);
1706 if (r < 0)
1707 goto fail;
1708
1709 /* this may be zero */
1710 r = dns_packet_read_uint8(p, &size, NULL);
1711 if (r < 0)
1712 goto fail;
1713
1714 r = dns_packet_read_memdup(p, size, &rr->nsec3.salt, &rr->nsec3.salt_size, NULL);
1715 if (r < 0)
1716 goto fail;
1717
1718 r = dns_packet_read_uint8(p, &size, NULL);
1719 if (r < 0)
1720 goto fail;
1721
1722 if (size <= 0) {
1723 r = -EBADMSG;
1724 goto fail;
1725 }
1726
1727 r = dns_packet_read_memdup(p, size, &rr->nsec3.next_hashed_name, &rr->nsec3.next_hashed_name_size, NULL);
1728 if (r < 0)
1729 goto fail;
1730
1731 r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL);
1732 if (r < 0)
1733 goto fail;
1734
1735 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
1736
1737 break;
1738 }
1739 default:
1740 unparseable:
1741 r = dns_packet_read_memdup(p, rdlength, &rr->generic.data, &rr->generic.size, NULL);
1742 if (r < 0)
1743 goto fail;
1744 break;
1745 }
1746 if (r < 0)
1747 goto fail;
1748 if (p->rindex != offset + rdlength) {
1749 r = -EBADMSG;
1750 goto fail;
1751 }
1752
1753 *ret = rr;
1754 rr = NULL;
1755
1756 if (start)
1757 *start = saved_rindex;
1758
1759 return 0;
1760 fail:
1761 dns_packet_rewind(p, saved_rindex);
1762 return r;
1763 }
1764
1765 int dns_packet_extract(DnsPacket *p) {
1766 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1767 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1768 size_t saved_rindex;
1769 unsigned n, i;
1770 int r;
1771
1772 if (p->extracted)
1773 return 0;
1774
1775 saved_rindex = p->rindex;
1776 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1777
1778 n = DNS_PACKET_QDCOUNT(p);
1779 if (n > 0) {
1780 question = dns_question_new(n);
1781 if (!question) {
1782 r = -ENOMEM;
1783 goto finish;
1784 }
1785
1786 for (i = 0; i < n; i++) {
1787 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1788
1789 r = dns_packet_read_key(p, &key, NULL);
1790 if (r < 0)
1791 goto finish;
1792
1793 r = dns_question_add(question, key);
1794 if (r < 0)
1795 goto finish;
1796 }
1797 }
1798
1799 n = DNS_PACKET_RRCOUNT(p);
1800 if (n > 0) {
1801 answer = dns_answer_new(n);
1802 if (!answer) {
1803 r = -ENOMEM;
1804 goto finish;
1805 }
1806
1807 for (i = 0; i < n; i++) {
1808 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1809
1810 r = dns_packet_read_rr(p, &rr, NULL);
1811 if (r < 0)
1812 goto finish;
1813
1814 r = dns_answer_add(answer, rr, p->ifindex);
1815 if (r < 0)
1816 goto finish;
1817 }
1818 }
1819
1820 p->question = question;
1821 question = NULL;
1822
1823 p->answer = answer;
1824 answer = NULL;
1825
1826 p->extracted = true;
1827
1828 r = 0;
1829
1830 finish:
1831 p->rindex = saved_rindex;
1832 return r;
1833 }
1834
1835 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
1836 [DNS_RCODE_SUCCESS] = "SUCCESS",
1837 [DNS_RCODE_FORMERR] = "FORMERR",
1838 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
1839 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
1840 [DNS_RCODE_NOTIMP] = "NOTIMP",
1841 [DNS_RCODE_REFUSED] = "REFUSED",
1842 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
1843 [DNS_RCODE_YXRRSET] = "YRRSET",
1844 [DNS_RCODE_NXRRSET] = "NXRRSET",
1845 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
1846 [DNS_RCODE_NOTZONE] = "NOTZONE",
1847 [DNS_RCODE_BADVERS] = "BADVERS",
1848 [DNS_RCODE_BADKEY] = "BADKEY",
1849 [DNS_RCODE_BADTIME] = "BADTIME",
1850 [DNS_RCODE_BADMODE] = "BADMODE",
1851 [DNS_RCODE_BADNAME] = "BADNAME",
1852 [DNS_RCODE_BADALG] = "BADALG",
1853 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
1854 };
1855 DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1856
1857 static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
1858 [DNS_PROTOCOL_DNS] = "dns",
1859 [DNS_PROTOCOL_MDNS] = "mdns",
1860 [DNS_PROTOCOL_LLMNR] = "llmnr",
1861 };
1862 DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
1863
1864 static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
1865 [DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
1866 [DNSSEC_ALGORITHM_DH] = "DH",
1867 [DNSSEC_ALGORITHM_DSA] = "DSA",
1868 [DNSSEC_ALGORITHM_ECC] = "ECC",
1869 [DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
1870 [DNSSEC_ALGORITHM_DSA_NSEC3_SHA1] = "DSA-NSEC3-SHA1",
1871 [DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1] = "RSASHA1-NSEC3-SHA1",
1872 [DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
1873 [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
1874 [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
1875 };
1876 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);