]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-packet.c
core: fix transaction destructiveness check once more
[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 "resolved-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 <= 0)
36 a = DNS_PACKET_SIZE_START;
37 else
38 a = mtu;
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 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
170 if (p->protocol == DNS_PROTOCOL_LLMNR &&
171 DNS_PACKET_QDCOUNT(p) != 1)
172 return -EBADMSG;
173
174 return 1;
175 }
176
177 int dns_packet_validate_query(DnsPacket *p) {
178 int r;
179
180 assert(p);
181
182 r = dns_packet_validate(p);
183 if (r < 0)
184 return r;
185
186 if (DNS_PACKET_QR(p) != 0)
187 return 0;
188
189 if (DNS_PACKET_OPCODE(p) != 0)
190 return -EBADMSG;
191
192 if (DNS_PACKET_TC(p))
193 return -EBADMSG;
194
195 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
196 if (p->protocol == DNS_PROTOCOL_LLMNR &&
197 DNS_PACKET_QDCOUNT(p) != 1)
198 return -EBADMSG;
199
200 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
201 if (DNS_PACKET_ANCOUNT(p) > 0)
202 return -EBADMSG;
203
204 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
205 if (DNS_PACKET_NSCOUNT(p) > 0)
206 return -EBADMSG;
207
208 return 1;
209 }
210
211 static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
212 assert(p);
213
214 if (p->size + add > p->allocated) {
215 size_t a;
216
217 a = PAGE_ALIGN((p->size + add) * 2);
218 if (a > DNS_PACKET_SIZE_MAX)
219 a = DNS_PACKET_SIZE_MAX;
220
221 if (p->size + add > a)
222 return -EMSGSIZE;
223
224 if (p->_data) {
225 void *d;
226
227 d = realloc(p->_data, a);
228 if (!d)
229 return -ENOMEM;
230
231 p->_data = d;
232 } else {
233 p->_data = malloc(a);
234 if (!p->_data)
235 return -ENOMEM;
236
237 memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
238 memzero((uint8_t*) p->_data + p->size, a - p->size);
239 }
240
241 p->allocated = a;
242 }
243
244 if (start)
245 *start = p->size;
246
247 if (ret)
248 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;
249
250 p->size += add;
251 return 0;
252 }
253
254 static void dns_packet_truncate(DnsPacket *p, size_t sz) {
255 Iterator i;
256 char *s;
257 void *n;
258
259 assert(p);
260
261 if (p->size <= sz)
262 return;
263
264 HASHMAP_FOREACH_KEY(s, n, p->names, i) {
265
266 if (PTR_TO_SIZE(n) < sz)
267 continue;
268
269 hashmap_remove(p->names, s);
270 free(s);
271 }
272
273 p->size = sz;
274 }
275
276 int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
277 void *q;
278 int r;
279
280 assert(p);
281
282 r = dns_packet_extend(p, l, &q, start);
283 if (r < 0)
284 return r;
285
286 memcpy(q, d, l);
287 return 0;
288 }
289
290 int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
291 void *d;
292 int r;
293
294 assert(p);
295
296 r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
297 if (r < 0)
298 return r;
299
300 ((uint8_t*) d)[0] = v;
301
302 return 0;
303 }
304
305 int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
306 void *d;
307 int r;
308
309 assert(p);
310
311 r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
312 if (r < 0)
313 return r;
314
315 unaligned_write_be16(d, v);
316
317 return 0;
318 }
319
320 int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start) {
321 void *d;
322 int r;
323
324 assert(p);
325
326 r = dns_packet_extend(p, sizeof(uint32_t), &d, start);
327 if (r < 0)
328 return r;
329
330 unaligned_write_be32(d, v);
331
332 return 0;
333 }
334
335 int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
336 void *d;
337 size_t l;
338 int r;
339
340 assert(p);
341 assert(s);
342
343 l = strlen(s);
344 if (l > 255)
345 return -E2BIG;
346
347 r = dns_packet_extend(p, 1 + l, &d, start);
348 if (r < 0)
349 return r;
350
351 ((uint8_t*) d)[0] = (uint8_t) l;
352 memcpy(((uint8_t*) d) + 1, s, l);
353
354 return 0;
355 }
356
357 int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start) {
358 void *w;
359 int r;
360
361 assert(p);
362 assert(d);
363
364 if (l > DNS_LABEL_MAX)
365 return -E2BIG;
366
367 r = dns_packet_extend(p, 1 + l, &w, start);
368 if (r < 0)
369 return r;
370
371 ((uint8_t*) w)[0] = (uint8_t) l;
372 memcpy(((uint8_t*) w) + 1, d, l);
373
374 return 0;
375 }
376
377 int dns_packet_append_name(DnsPacket *p, const char *name,
378 bool allow_compression, size_t *start) {
379 size_t saved_size;
380 int r;
381
382 assert(p);
383 assert(name);
384
385 saved_size = p->size;
386
387 while (*name) {
388 _cleanup_free_ char *s = NULL;
389 char label[DNS_LABEL_MAX];
390 size_t n = 0;
391 int k;
392
393 if (allow_compression)
394 n = PTR_TO_SIZE(hashmap_get(p->names, name));
395 if (n > 0) {
396 assert(n < p->size);
397
398 if (n < 0x4000) {
399 r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
400 if (r < 0)
401 goto fail;
402
403 goto done;
404 }
405 }
406
407 s = strdup(name);
408 if (!s) {
409 r = -ENOMEM;
410 goto fail;
411 }
412
413 r = dns_label_unescape(&name, label, sizeof(label));
414 if (r < 0)
415 goto fail;
416
417 if (p->protocol == DNS_PROTOCOL_DNS)
418 k = dns_label_apply_idna(label, r, label, sizeof(label));
419 else
420 k = dns_label_undo_idna(label, r, label, sizeof(label));
421 if (k < 0) {
422 r = k;
423 goto fail;
424 }
425 if (k > 0)
426 r = k;
427
428 r = dns_packet_append_label(p, label, r, &n);
429 if (r < 0)
430 goto fail;
431
432 if (allow_compression) {
433 r = hashmap_ensure_allocated(&p->names, &dns_name_hash_ops);
434 if (r < 0)
435 goto fail;
436
437 r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
438 if (r < 0)
439 goto fail;
440
441 s = NULL;
442 }
443 }
444
445 r = dns_packet_append_uint8(p, 0, NULL);
446 if (r < 0)
447 return r;
448
449 done:
450 if (start)
451 *start = saved_size;
452
453 return 0;
454
455 fail:
456 dns_packet_truncate(p, saved_size);
457 return r;
458 }
459
460 int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
461 size_t saved_size;
462 int r;
463
464 assert(p);
465 assert(k);
466
467 saved_size = p->size;
468
469 r = dns_packet_append_name(p, DNS_RESOURCE_KEY_NAME(k), true, NULL);
470 if (r < 0)
471 goto fail;
472
473 r = dns_packet_append_uint16(p, k->type, NULL);
474 if (r < 0)
475 goto fail;
476
477 r = dns_packet_append_uint16(p, k->class, NULL);
478 if (r < 0)
479 goto fail;
480
481 if (start)
482 *start = saved_size;
483
484 return 0;
485
486 fail:
487 dns_packet_truncate(p, saved_size);
488 return r;
489 }
490
491 int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start) {
492 size_t saved_size, rdlength_offset, end, rdlength;
493 int r;
494
495 assert(p);
496 assert(rr);
497
498 saved_size = p->size;
499
500 r = dns_packet_append_key(p, rr->key, NULL);
501 if (r < 0)
502 goto fail;
503
504 r = dns_packet_append_uint32(p, rr->ttl, NULL);
505 if (r < 0)
506 goto fail;
507
508 /* Initially we write 0 here */
509 r = dns_packet_append_uint16(p, 0, &rdlength_offset);
510 if (r < 0)
511 goto fail;
512
513 switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
514
515 case DNS_TYPE_SRV:
516 r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
517 if (r < 0)
518 goto fail;
519
520 r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
521 if (r < 0)
522 goto fail;
523
524 r = dns_packet_append_uint16(p, rr->srv.port, NULL);
525 if (r < 0)
526 goto fail;
527
528 r = dns_packet_append_name(p, rr->srv.name, true, NULL);
529 break;
530
531 case DNS_TYPE_PTR:
532 case DNS_TYPE_NS:
533 case DNS_TYPE_CNAME:
534 case DNS_TYPE_DNAME:
535 r = dns_packet_append_name(p, rr->ptr.name, true, NULL);
536 break;
537
538 case DNS_TYPE_HINFO:
539 r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
540 if (r < 0)
541 goto fail;
542
543 r = dns_packet_append_string(p, rr->hinfo.os, NULL);
544 break;
545
546 case DNS_TYPE_SPF: /* exactly the same as TXT */
547 case DNS_TYPE_TXT: {
548 char **s;
549
550 STRV_FOREACH(s, rr->txt.strings) {
551 r = dns_packet_append_string(p, *s, NULL);
552 if (r < 0)
553 goto fail;
554 }
555
556 r = 0;
557 break;
558 }
559
560 case DNS_TYPE_A:
561 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
562 break;
563
564 case DNS_TYPE_AAAA:
565 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
566 break;
567
568 case DNS_TYPE_SOA:
569 r = dns_packet_append_name(p, rr->soa.mname, true, NULL);
570 if (r < 0)
571 goto fail;
572
573 r = dns_packet_append_name(p, rr->soa.rname, true, NULL);
574 if (r < 0)
575 goto fail;
576
577 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
578 if (r < 0)
579 goto fail;
580
581 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
582 if (r < 0)
583 goto fail;
584
585 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
586 if (r < 0)
587 goto fail;
588
589 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
590 if (r < 0)
591 goto fail;
592
593 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
594 break;
595
596 case DNS_TYPE_MX:
597 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
598 if (r < 0)
599 goto fail;
600
601 r = dns_packet_append_name(p, rr->mx.exchange, true, NULL);
602 break;
603
604 case DNS_TYPE_LOC:
605 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
606 if (r < 0)
607 goto fail;
608
609 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
610 if (r < 0)
611 goto fail;
612
613 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
614 if (r < 0)
615 goto fail;
616
617 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
618 if (r < 0)
619 goto fail;
620
621 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
622 if (r < 0)
623 goto fail;
624
625 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
626 if (r < 0)
627 goto fail;
628
629 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
630 break;
631
632 case DNS_TYPE_SSHFP:
633 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
634 if (r < 0)
635 goto fail;
636
637 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
638 if (r < 0)
639 goto fail;
640
641 r = dns_packet_append_blob(p, rr->sshfp.key, rr->sshfp.key_size, NULL);
642 break;
643
644 case DNS_TYPE_DNSKEY:
645 r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
646 if (r < 0)
647 goto fail;
648
649 r = dns_packet_append_uint8(p, 3u, NULL);
650 if (r < 0)
651 goto fail;
652
653 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
654 if (r < 0)
655 goto fail;
656
657 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
658 break;
659
660 case DNS_TYPE_RRSIG:
661 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
662 if (r < 0)
663 goto fail;
664
665 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
666 if (r < 0)
667 goto fail;
668
669 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
670 if (r < 0)
671 goto fail;
672
673 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
674 if (r < 0)
675 goto fail;
676
677 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
678 if (r < 0)
679 goto fail;
680
681 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
682 if (r < 0)
683 goto fail;
684
685 r = dns_packet_append_uint8(p, rr->rrsig.key_tag, NULL);
686 if (r < 0)
687 goto fail;
688
689 r = dns_packet_append_name(p, rr->rrsig.signer, false, NULL);
690 if (r < 0)
691 goto fail;
692
693 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
694 break;
695
696 case _DNS_TYPE_INVALID: /* unparseable */
697 default:
698
699 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
700 break;
701 }
702 if (r < 0)
703 goto fail;
704
705 /* Let's calculate the actual data size and update the field */
706 rdlength = p->size - rdlength_offset - sizeof(uint16_t);
707 if (rdlength > 0xFFFF) {
708 r = ENOSPC;
709 goto fail;
710 }
711
712 end = p->size;
713 p->size = rdlength_offset;
714 r = dns_packet_append_uint16(p, rdlength, NULL);
715 if (r < 0)
716 goto fail;
717 p->size = end;
718
719 if (start)
720 *start = saved_size;
721
722 return 0;
723
724 fail:
725 dns_packet_truncate(p, saved_size);
726 return r;
727 }
728
729
730 int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
731 assert(p);
732
733 if (p->rindex + sz > p->size)
734 return -EMSGSIZE;
735
736 if (ret)
737 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
738
739 if (start)
740 *start = p->rindex;
741
742 p->rindex += sz;
743 return 0;
744 }
745
746 void dns_packet_rewind(DnsPacket *p, size_t idx) {
747 assert(p);
748 assert(idx <= p->size);
749 assert(idx >= DNS_PACKET_HEADER_SIZE);
750
751 p->rindex = idx;
752 }
753
754 int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
755 const void *q;
756 int r;
757
758 assert(p);
759 assert(d);
760
761 r = dns_packet_read(p, sz, &q, start);
762 if (r < 0)
763 return r;
764
765 memcpy(d, q, sz);
766 return 0;
767 }
768
769 int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
770 const void *d;
771 int r;
772
773 assert(p);
774
775 r = dns_packet_read(p, sizeof(uint8_t), &d, start);
776 if (r < 0)
777 return r;
778
779 *ret = ((uint8_t*) d)[0];
780 return 0;
781 }
782
783 int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
784 const void *d;
785 int r;
786
787 assert(p);
788
789 r = dns_packet_read(p, sizeof(uint16_t), &d, start);
790 if (r < 0)
791 return r;
792
793 *ret = unaligned_read_be16(d);
794
795 return 0;
796 }
797
798 int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
799 const void *d;
800 int r;
801
802 assert(p);
803
804 r = dns_packet_read(p, sizeof(uint32_t), &d, start);
805 if (r < 0)
806 return r;
807
808 *ret = unaligned_read_be32(d);
809
810 return 0;
811 }
812
813 int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
814 size_t saved_rindex;
815 const void *d;
816 char *t;
817 uint8_t c;
818 int r;
819
820 assert(p);
821
822 saved_rindex = p->rindex;
823
824 r = dns_packet_read_uint8(p, &c, NULL);
825 if (r < 0)
826 goto fail;
827
828 r = dns_packet_read(p, c, &d, NULL);
829 if (r < 0)
830 goto fail;
831
832 if (memchr(d, 0, c)) {
833 r = -EBADMSG;
834 goto fail;
835 }
836
837 t = strndup(d, c);
838 if (!t) {
839 r = -ENOMEM;
840 goto fail;
841 }
842
843 if (!utf8_is_valid(t)) {
844 free(t);
845 r = -EBADMSG;
846 goto fail;
847 }
848
849 *ret = t;
850
851 if (start)
852 *start = saved_rindex;
853
854 return 0;
855
856 fail:
857 dns_packet_rewind(p, saved_rindex);
858 return r;
859 }
860
861 int dns_packet_read_name(DnsPacket *p, char **_ret,
862 bool allow_compression, size_t *start) {
863 size_t saved_rindex, after_rindex = 0;
864 _cleanup_free_ char *ret = NULL;
865 size_t n = 0, allocated = 0;
866 bool first = true;
867 int r;
868
869 assert(p);
870 assert(_ret);
871
872 saved_rindex = p->rindex;
873
874 for (;;) {
875 uint8_t c, d;
876
877 r = dns_packet_read_uint8(p, &c, NULL);
878 if (r < 0)
879 goto fail;
880
881 if (c == 0)
882 /* End of name */
883 break;
884 else if (c <= 63) {
885 _cleanup_free_ char *t = NULL;
886 const char *label;
887
888 /* Literal label */
889 r = dns_packet_read(p, c, (const void**) &label, NULL);
890 if (r < 0)
891 goto fail;
892
893 r = dns_label_escape(label, c, &t);
894 if (r < 0)
895 goto fail;
896
897 if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) {
898 r = -ENOMEM;
899 goto fail;
900 }
901
902 if (!first)
903 ret[n++] = '.';
904 else
905 first = false;
906
907 memcpy(ret + n, t, r);
908 n += r;
909 continue;
910 } else if (allow_compression && (c & 0xc0) == 0xc0) {
911 uint16_t ptr;
912
913 /* Pointer */
914 r = dns_packet_read_uint8(p, &d, NULL);
915 if (r < 0)
916 goto fail;
917
918 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
919 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= saved_rindex) {
920 r = -EBADMSG;
921 goto fail;
922 }
923
924 if (after_rindex == 0)
925 after_rindex = p->rindex;
926
927 p->rindex = ptr;
928 } else
929 goto fail;
930 }
931
932 if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
933 r = -ENOMEM;
934 goto fail;
935 }
936
937 ret[n] = 0;
938
939 if (after_rindex != 0)
940 p->rindex= after_rindex;
941
942 *_ret = ret;
943 ret = NULL;
944
945 if (start)
946 *start = saved_rindex;
947
948 return 0;
949
950 fail:
951 dns_packet_rewind(p, saved_rindex);
952 return r;
953 }
954
955 int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
956 _cleanup_free_ char *name = NULL;
957 uint16_t class, type;
958 DnsResourceKey *key;
959 size_t saved_rindex;
960 int r;
961
962 assert(p);
963 assert(ret);
964
965 saved_rindex = p->rindex;
966
967 r = dns_packet_read_name(p, &name, true, NULL);
968 if (r < 0)
969 goto fail;
970
971 r = dns_packet_read_uint16(p, &type, NULL);
972 if (r < 0)
973 goto fail;
974
975 r = dns_packet_read_uint16(p, &class, NULL);
976 if (r < 0)
977 goto fail;
978
979 key = dns_resource_key_new_consume(class, type, name);
980 if (!key) {
981 r = -ENOMEM;
982 goto fail;
983 }
984
985 name = NULL;
986 *ret = key;
987
988 if (start)
989 *start = saved_rindex;
990
991 return 0;
992 fail:
993 dns_packet_rewind(p, saved_rindex);
994 return r;
995 }
996
997 static int dns_packet_read_public_key(DnsPacket *p, size_t length,
998 void **dp, size_t *lengthp,
999 size_t *start) {
1000 int r;
1001 const void *d;
1002 void *d2;
1003
1004 r = dns_packet_read(p, length, &d, NULL);
1005 if (r < 0)
1006 return r;
1007
1008 d2 = memdup(d, length);
1009 if (!d2)
1010 return -ENOMEM;
1011
1012 *dp = d2;
1013 *lengthp = length;
1014 return 0;
1015 }
1016
1017 static bool loc_size_ok(uint8_t size) {
1018 uint8_t m = size >> 4, e = size & 0xF;
1019
1020 return m <= 9 && e <= 9 && (m > 0 || e == 0);
1021 }
1022
1023 static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
1024 assert(rr);
1025
1026 if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
1027 return -EBADMSG;
1028
1029 rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
1030 rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
1031 return 0;
1032 }
1033
1034 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
1035 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1036 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1037 size_t saved_rindex, offset;
1038 uint16_t rdlength;
1039 const void *d;
1040 int r;
1041
1042 assert(p);
1043 assert(ret);
1044
1045 saved_rindex = p->rindex;
1046
1047 r = dns_packet_read_key(p, &key, NULL);
1048 if (r < 0)
1049 goto fail;
1050
1051 if (key->class == DNS_CLASS_ANY ||
1052 key->type == DNS_TYPE_ANY) {
1053 r = -EBADMSG;
1054 goto fail;
1055 }
1056
1057 rr = dns_resource_record_new(key);
1058 if (!rr) {
1059 r = -ENOMEM;
1060 goto fail;
1061 }
1062
1063 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1064 if (r < 0)
1065 goto fail;
1066
1067 r = dns_packet_read_uint16(p, &rdlength, NULL);
1068 if (r < 0)
1069 goto fail;
1070
1071 if (p->rindex + rdlength > p->size) {
1072 r = -EBADMSG;
1073 goto fail;
1074 }
1075
1076 offset = p->rindex;
1077
1078 switch (rr->key->type) {
1079
1080 case DNS_TYPE_SRV:
1081 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1082 if (r < 0)
1083 goto fail;
1084 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1085 if (r < 0)
1086 goto fail;
1087 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1088 if (r < 0)
1089 goto fail;
1090 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
1091 break;
1092
1093 case DNS_TYPE_PTR:
1094 case DNS_TYPE_NS:
1095 case DNS_TYPE_CNAME:
1096 case DNS_TYPE_DNAME:
1097 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
1098 break;
1099
1100 case DNS_TYPE_HINFO:
1101 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1102 if (r < 0)
1103 goto fail;
1104
1105 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1106 break;
1107
1108 case DNS_TYPE_SPF: /* exactly the same as TXT */
1109 case DNS_TYPE_TXT: {
1110 char *s;
1111
1112 while (p->rindex < offset + rdlength) {
1113 r = dns_packet_read_string(p, &s, NULL);
1114 if (r < 0)
1115 goto fail;
1116
1117 r = strv_consume(&rr->txt.strings, s);
1118 if (r < 0)
1119 goto fail;
1120 }
1121
1122 r = 0;
1123 break;
1124 }
1125
1126 case DNS_TYPE_A:
1127 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1128 break;
1129
1130 case DNS_TYPE_AAAA:
1131 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1132 break;
1133
1134 case DNS_TYPE_SOA:
1135 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
1136 if (r < 0)
1137 goto fail;
1138
1139 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
1140 if (r < 0)
1141 goto fail;
1142
1143 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1144 if (r < 0)
1145 goto fail;
1146
1147 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1148 if (r < 0)
1149 goto fail;
1150
1151 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1152 if (r < 0)
1153 goto fail;
1154
1155 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1156 if (r < 0)
1157 goto fail;
1158
1159 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1160 break;
1161
1162 case DNS_TYPE_MX:
1163 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1164 if (r < 0)
1165 goto fail;
1166
1167 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
1168 break;
1169
1170 case DNS_TYPE_LOC: {
1171 uint8_t t;
1172 size_t pos;
1173
1174 r = dns_packet_read_uint8(p, &t, &pos);
1175 if (r < 0)
1176 goto fail;
1177
1178 if (t == 0) {
1179 rr->loc.version = t;
1180
1181 r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1182 if (r < 0)
1183 goto fail;
1184
1185 if (!loc_size_ok(rr->loc.size)) {
1186 r = -EBADMSG;
1187 goto fail;
1188 }
1189
1190 r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1191 if (r < 0)
1192 goto fail;
1193
1194 if (!loc_size_ok(rr->loc.horiz_pre)) {
1195 r = -EBADMSG;
1196 goto fail;
1197 }
1198
1199 r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1200 if (r < 0)
1201 goto fail;
1202
1203 if (!loc_size_ok(rr->loc.vert_pre)) {
1204 r = -EBADMSG;
1205 goto fail;
1206 }
1207
1208 r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1209 if (r < 0)
1210 goto fail;
1211
1212 r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1213 if (r < 0)
1214 goto fail;
1215
1216 r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1217 if (r < 0)
1218 goto fail;
1219
1220 break;
1221 } else {
1222 dns_packet_rewind(p, pos);
1223 rr->unparseable = true;
1224 goto unparseable;
1225 }
1226 }
1227
1228 case DNS_TYPE_SSHFP:
1229 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1230 if (r < 0)
1231 goto fail;
1232
1233 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1234 if (r < 0)
1235 goto fail;
1236
1237 r = dns_packet_read_public_key(p, rdlength - 2,
1238 &rr->sshfp.key, &rr->sshfp.key_size,
1239 NULL);
1240 break;
1241
1242 case DNS_TYPE_DNSKEY: {
1243 uint16_t flags;
1244 uint8_t proto;
1245
1246 r = dns_packet_read_uint16(p, &flags, NULL);
1247 if (r < 0)
1248 goto fail;
1249
1250 r = dnskey_parse_flags(rr, flags);
1251 if (r < 0)
1252 goto fail;
1253
1254 r = dns_packet_read_uint8(p, &proto, NULL);
1255 if (r < 0)
1256 goto fail;
1257
1258 /* protocol is required to be always 3 */
1259 if (proto != 3) {
1260 r = -EBADMSG;
1261 goto fail;
1262 }
1263
1264 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1265 if (r < 0)
1266 goto fail;
1267
1268 r = dns_packet_read_public_key(p, rdlength - 4,
1269 &rr->dnskey.key, &rr->dnskey.key_size,
1270 NULL);
1271 break;
1272 }
1273
1274 case DNS_TYPE_RRSIG:
1275 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1276 if (r < 0)
1277 goto fail;
1278
1279 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1280 if (r < 0)
1281 goto fail;
1282
1283 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1284 if (r < 0)
1285 goto fail;
1286
1287 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1288 if (r < 0)
1289 goto fail;
1290
1291 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1292 if (r < 0)
1293 goto fail;
1294
1295 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1296 if (r < 0)
1297 goto fail;
1298
1299 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1300 if (r < 0)
1301 goto fail;
1302
1303 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1304 if (r < 0)
1305 goto fail;
1306
1307 r = dns_packet_read_public_key(p, offset + rdlength - p->rindex,
1308 &rr->rrsig.signature, &rr->rrsig.signature_size,
1309 NULL);
1310 break;
1311
1312 default:
1313 unparseable:
1314 r = dns_packet_read(p, rdlength, &d, NULL);
1315 if (r < 0)
1316 goto fail;
1317
1318 rr->generic.data = memdup(d, rdlength);
1319 if (!rr->generic.data) {
1320 r = -ENOMEM;
1321 goto fail;
1322 }
1323
1324 rr->generic.size = rdlength;
1325 break;
1326 }
1327 if (r < 0)
1328 goto fail;
1329 if (p->rindex != offset + rdlength) {
1330 r = -EBADMSG;
1331 goto fail;
1332 }
1333
1334 *ret = rr;
1335 rr = NULL;
1336
1337 if (start)
1338 *start = saved_rindex;
1339
1340 return 0;
1341 fail:
1342 dns_packet_rewind(p, saved_rindex);
1343 return r;
1344 }
1345
1346 int dns_packet_extract(DnsPacket *p) {
1347 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1348 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1349 size_t saved_rindex;
1350 unsigned n, i;
1351 int r;
1352
1353 if (p->extracted)
1354 return 0;
1355
1356 saved_rindex = p->rindex;
1357 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1358
1359 n = DNS_PACKET_QDCOUNT(p);
1360 if (n > 0) {
1361 question = dns_question_new(n);
1362 if (!question) {
1363 r = -ENOMEM;
1364 goto finish;
1365 }
1366
1367 for (i = 0; i < n; i++) {
1368 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1369
1370 r = dns_packet_read_key(p, &key, NULL);
1371 if (r < 0)
1372 goto finish;
1373
1374 r = dns_question_add(question, key);
1375 if (r < 0)
1376 goto finish;
1377 }
1378 }
1379
1380 n = DNS_PACKET_RRCOUNT(p);
1381 if (n > 0) {
1382 answer = dns_answer_new(n);
1383 if (!answer) {
1384 r = -ENOMEM;
1385 goto finish;
1386 }
1387
1388 for (i = 0; i < n; i++) {
1389 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1390
1391 r = dns_packet_read_rr(p, &rr, NULL);
1392 if (r < 0)
1393 goto finish;
1394
1395 r = dns_answer_add(answer, rr);
1396 if (r < 0)
1397 goto finish;
1398 }
1399 }
1400
1401 p->question = question;
1402 question = NULL;
1403
1404 p->answer = answer;
1405 answer = NULL;
1406
1407 p->extracted = true;
1408
1409 r = 0;
1410
1411 finish:
1412 p->rindex = saved_rindex;
1413 return r;
1414 }
1415
1416 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
1417 [DNS_RCODE_SUCCESS] = "SUCCESS",
1418 [DNS_RCODE_FORMERR] = "FORMERR",
1419 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
1420 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
1421 [DNS_RCODE_NOTIMP] = "NOTIMP",
1422 [DNS_RCODE_REFUSED] = "REFUSED",
1423 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
1424 [DNS_RCODE_YXRRSET] = "YRRSET",
1425 [DNS_RCODE_NXRRSET] = "NXRRSET",
1426 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
1427 [DNS_RCODE_NOTZONE] = "NOTZONE",
1428 [DNS_RCODE_BADVERS] = "BADVERS",
1429 [DNS_RCODE_BADKEY] = "BADKEY",
1430 [DNS_RCODE_BADTIME] = "BADTIME",
1431 [DNS_RCODE_BADMODE] = "BADMODE",
1432 [DNS_RCODE_BADNAME] = "BADNAME",
1433 [DNS_RCODE_BADALG] = "BADALG",
1434 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
1435 };
1436 DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1437
1438 static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
1439 [DNS_PROTOCOL_DNS] = "dns",
1440 [DNS_PROTOCOL_MDNS] = "mdns",
1441 [DNS_PROTOCOL_LLMNR] = "llmnr",
1442 };
1443 DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
1444
1445 static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
1446 [DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
1447 [DNSSEC_ALGORITHM_DH] = "DH",
1448 [DNSSEC_ALGORITHM_DSA] = "DSA",
1449 [DNSSEC_ALGORITHM_ECC] = "ECC",
1450 [DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
1451 [DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
1452 [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
1453 [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
1454 };
1455 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);