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