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