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