]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-packet.c
Merge pull request #152 from zonque/buildsys
[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 <= 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 if (strv_isempty(rr->txt.strings)) {
551 /* RFC 6763, section 6.1 suggests to generate
552 * single empty string for an empty array. */
553
554 r = dns_packet_append_string(p, "", NULL);
555 if (r < 0)
556 goto fail;
557 } else {
558 STRV_FOREACH(s, rr->txt.strings) {
559 r = dns_packet_append_string(p, *s, NULL);
560 if (r < 0)
561 goto fail;
562 }
563 }
564
565 r = 0;
566 break;
567 }
568
569 case DNS_TYPE_A:
570 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
571 break;
572
573 case DNS_TYPE_AAAA:
574 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
575 break;
576
577 case DNS_TYPE_SOA:
578 r = dns_packet_append_name(p, rr->soa.mname, true, NULL);
579 if (r < 0)
580 goto fail;
581
582 r = dns_packet_append_name(p, rr->soa.rname, true, NULL);
583 if (r < 0)
584 goto fail;
585
586 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
587 if (r < 0)
588 goto fail;
589
590 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
591 if (r < 0)
592 goto fail;
593
594 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
595 if (r < 0)
596 goto fail;
597
598 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
599 if (r < 0)
600 goto fail;
601
602 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
603 break;
604
605 case DNS_TYPE_MX:
606 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
607 if (r < 0)
608 goto fail;
609
610 r = dns_packet_append_name(p, rr->mx.exchange, true, NULL);
611 break;
612
613 case DNS_TYPE_LOC:
614 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
615 if (r < 0)
616 goto fail;
617
618 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
619 if (r < 0)
620 goto fail;
621
622 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
623 if (r < 0)
624 goto fail;
625
626 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
627 if (r < 0)
628 goto fail;
629
630 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
631 if (r < 0)
632 goto fail;
633
634 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
635 if (r < 0)
636 goto fail;
637
638 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
639 break;
640
641 case DNS_TYPE_SSHFP:
642 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
643 if (r < 0)
644 goto fail;
645
646 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
647 if (r < 0)
648 goto fail;
649
650 r = dns_packet_append_blob(p, rr->sshfp.key, rr->sshfp.key_size, NULL);
651 break;
652
653 case DNS_TYPE_DNSKEY:
654 r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
655 if (r < 0)
656 goto fail;
657
658 r = dns_packet_append_uint8(p, 3u, NULL);
659 if (r < 0)
660 goto fail;
661
662 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
663 if (r < 0)
664 goto fail;
665
666 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
667 break;
668
669 case DNS_TYPE_RRSIG:
670 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
671 if (r < 0)
672 goto fail;
673
674 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
675 if (r < 0)
676 goto fail;
677
678 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
679 if (r < 0)
680 goto fail;
681
682 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
683 if (r < 0)
684 goto fail;
685
686 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
687 if (r < 0)
688 goto fail;
689
690 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
691 if (r < 0)
692 goto fail;
693
694 r = dns_packet_append_uint8(p, rr->rrsig.key_tag, NULL);
695 if (r < 0)
696 goto fail;
697
698 r = dns_packet_append_name(p, rr->rrsig.signer, false, NULL);
699 if (r < 0)
700 goto fail;
701
702 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
703 break;
704
705 case _DNS_TYPE_INVALID: /* unparseable */
706 default:
707
708 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
709 break;
710 }
711 if (r < 0)
712 goto fail;
713
714 /* Let's calculate the actual data size and update the field */
715 rdlength = p->size - rdlength_offset - sizeof(uint16_t);
716 if (rdlength > 0xFFFF) {
717 r = ENOSPC;
718 goto fail;
719 }
720
721 end = p->size;
722 p->size = rdlength_offset;
723 r = dns_packet_append_uint16(p, rdlength, NULL);
724 if (r < 0)
725 goto fail;
726 p->size = end;
727
728 if (start)
729 *start = saved_size;
730
731 return 0;
732
733 fail:
734 dns_packet_truncate(p, saved_size);
735 return r;
736 }
737
738
739 int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
740 assert(p);
741
742 if (p->rindex + sz > p->size)
743 return -EMSGSIZE;
744
745 if (ret)
746 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
747
748 if (start)
749 *start = p->rindex;
750
751 p->rindex += sz;
752 return 0;
753 }
754
755 void dns_packet_rewind(DnsPacket *p, size_t idx) {
756 assert(p);
757 assert(idx <= p->size);
758 assert(idx >= DNS_PACKET_HEADER_SIZE);
759
760 p->rindex = idx;
761 }
762
763 int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
764 const void *q;
765 int r;
766
767 assert(p);
768 assert(d);
769
770 r = dns_packet_read(p, sz, &q, start);
771 if (r < 0)
772 return r;
773
774 memcpy(d, q, sz);
775 return 0;
776 }
777
778 int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
779 const void *d;
780 int r;
781
782 assert(p);
783
784 r = dns_packet_read(p, sizeof(uint8_t), &d, start);
785 if (r < 0)
786 return r;
787
788 *ret = ((uint8_t*) d)[0];
789 return 0;
790 }
791
792 int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
793 const void *d;
794 int r;
795
796 assert(p);
797
798 r = dns_packet_read(p, sizeof(uint16_t), &d, start);
799 if (r < 0)
800 return r;
801
802 *ret = unaligned_read_be16(d);
803
804 return 0;
805 }
806
807 int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
808 const void *d;
809 int r;
810
811 assert(p);
812
813 r = dns_packet_read(p, sizeof(uint32_t), &d, start);
814 if (r < 0)
815 return r;
816
817 *ret = unaligned_read_be32(d);
818
819 return 0;
820 }
821
822 int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
823 size_t saved_rindex;
824 const void *d;
825 char *t;
826 uint8_t c;
827 int r;
828
829 assert(p);
830
831 saved_rindex = p->rindex;
832
833 r = dns_packet_read_uint8(p, &c, NULL);
834 if (r < 0)
835 goto fail;
836
837 r = dns_packet_read(p, c, &d, NULL);
838 if (r < 0)
839 goto fail;
840
841 if (memchr(d, 0, c)) {
842 r = -EBADMSG;
843 goto fail;
844 }
845
846 t = strndup(d, c);
847 if (!t) {
848 r = -ENOMEM;
849 goto fail;
850 }
851
852 if (!utf8_is_valid(t)) {
853 free(t);
854 r = -EBADMSG;
855 goto fail;
856 }
857
858 *ret = t;
859
860 if (start)
861 *start = saved_rindex;
862
863 return 0;
864
865 fail:
866 dns_packet_rewind(p, saved_rindex);
867 return r;
868 }
869
870 int dns_packet_read_name(DnsPacket *p, char **_ret,
871 bool allow_compression, size_t *start) {
872 size_t saved_rindex, after_rindex = 0, jump_barrier;
873 _cleanup_free_ char *ret = NULL;
874 size_t n = 0, allocated = 0;
875 bool first = true;
876 int r;
877
878 assert(p);
879 assert(_ret);
880
881 saved_rindex = p->rindex;
882 jump_barrier = p->rindex;
883
884 for (;;) {
885 uint8_t c, d;
886
887 r = dns_packet_read_uint8(p, &c, NULL);
888 if (r < 0)
889 goto fail;
890
891 if (c == 0)
892 /* End of name */
893 break;
894 else if (c <= 63) {
895 _cleanup_free_ char *t = NULL;
896 const char *label;
897
898 /* Literal label */
899 r = dns_packet_read(p, c, (const void**) &label, NULL);
900 if (r < 0)
901 goto fail;
902
903 r = dns_label_escape(label, c, &t);
904 if (r < 0)
905 goto fail;
906
907 if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) {
908 r = -ENOMEM;
909 goto fail;
910 }
911
912 if (!first)
913 ret[n++] = '.';
914 else
915 first = false;
916
917 memcpy(ret + n, t, r);
918 n += r;
919 continue;
920 } else if (allow_compression && (c & 0xc0) == 0xc0) {
921 uint16_t ptr;
922
923 /* Pointer */
924 r = dns_packet_read_uint8(p, &d, NULL);
925 if (r < 0)
926 goto fail;
927
928 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
929 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier) {
930 r = -EBADMSG;
931 goto fail;
932 }
933
934 if (after_rindex == 0)
935 after_rindex = p->rindex;
936
937 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
938 jump_barrier = ptr;
939 p->rindex = ptr;
940 } else {
941 r = -EBADMSG;
942 goto fail;
943 }
944 }
945
946 if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
947 r = -ENOMEM;
948 goto fail;
949 }
950
951 ret[n] = 0;
952
953 if (after_rindex != 0)
954 p->rindex= after_rindex;
955
956 *_ret = ret;
957 ret = NULL;
958
959 if (start)
960 *start = saved_rindex;
961
962 return 0;
963
964 fail:
965 dns_packet_rewind(p, saved_rindex);
966 return r;
967 }
968
969 int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
970 _cleanup_free_ char *name = NULL;
971 uint16_t class, type;
972 DnsResourceKey *key;
973 size_t saved_rindex;
974 int r;
975
976 assert(p);
977 assert(ret);
978
979 saved_rindex = p->rindex;
980
981 r = dns_packet_read_name(p, &name, true, NULL);
982 if (r < 0)
983 goto fail;
984
985 r = dns_packet_read_uint16(p, &type, NULL);
986 if (r < 0)
987 goto fail;
988
989 r = dns_packet_read_uint16(p, &class, NULL);
990 if (r < 0)
991 goto fail;
992
993 key = dns_resource_key_new_consume(class, type, name);
994 if (!key) {
995 r = -ENOMEM;
996 goto fail;
997 }
998
999 name = NULL;
1000 *ret = key;
1001
1002 if (start)
1003 *start = saved_rindex;
1004
1005 return 0;
1006 fail:
1007 dns_packet_rewind(p, saved_rindex);
1008 return r;
1009 }
1010
1011 static int dns_packet_read_public_key(DnsPacket *p, size_t length,
1012 void **dp, size_t *lengthp,
1013 size_t *start) {
1014 int r;
1015 const void *d;
1016 void *d2;
1017
1018 r = dns_packet_read(p, length, &d, NULL);
1019 if (r < 0)
1020 return r;
1021
1022 d2 = memdup(d, length);
1023 if (!d2)
1024 return -ENOMEM;
1025
1026 *dp = d2;
1027 *lengthp = length;
1028 return 0;
1029 }
1030
1031 static bool loc_size_ok(uint8_t size) {
1032 uint8_t m = size >> 4, e = size & 0xF;
1033
1034 return m <= 9 && e <= 9 && (m > 0 || e == 0);
1035 }
1036
1037 static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
1038 assert(rr);
1039
1040 if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
1041 return -EBADMSG;
1042
1043 rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
1044 rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
1045 return 0;
1046 }
1047
1048 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
1049 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1050 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1051 size_t saved_rindex, offset;
1052 uint16_t rdlength;
1053 const void *d;
1054 int r;
1055
1056 assert(p);
1057 assert(ret);
1058
1059 saved_rindex = p->rindex;
1060
1061 r = dns_packet_read_key(p, &key, NULL);
1062 if (r < 0)
1063 goto fail;
1064
1065 if (key->class == DNS_CLASS_ANY ||
1066 key->type == DNS_TYPE_ANY) {
1067 r = -EBADMSG;
1068 goto fail;
1069 }
1070
1071 rr = dns_resource_record_new(key);
1072 if (!rr) {
1073 r = -ENOMEM;
1074 goto fail;
1075 }
1076
1077 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1078 if (r < 0)
1079 goto fail;
1080
1081 r = dns_packet_read_uint16(p, &rdlength, NULL);
1082 if (r < 0)
1083 goto fail;
1084
1085 if (p->rindex + rdlength > p->size) {
1086 r = -EBADMSG;
1087 goto fail;
1088 }
1089
1090 offset = p->rindex;
1091
1092 switch (rr->key->type) {
1093
1094 case DNS_TYPE_SRV:
1095 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1096 if (r < 0)
1097 goto fail;
1098 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1099 if (r < 0)
1100 goto fail;
1101 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1102 if (r < 0)
1103 goto fail;
1104 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
1105 break;
1106
1107 case DNS_TYPE_PTR:
1108 case DNS_TYPE_NS:
1109 case DNS_TYPE_CNAME:
1110 case DNS_TYPE_DNAME:
1111 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
1112 break;
1113
1114 case DNS_TYPE_HINFO:
1115 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1116 if (r < 0)
1117 goto fail;
1118
1119 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1120 break;
1121
1122 case DNS_TYPE_SPF: /* exactly the same as TXT */
1123 case DNS_TYPE_TXT:
1124 if (rdlength <= 0) {
1125 /* RFC 6763, section 6.1 suggests to treat
1126 * empty TXT RRs as equivalent to a TXT record
1127 * with a single empty string. */
1128
1129 r = strv_extend(&rr->txt.strings, "");
1130 if (r < 0)
1131 goto fail;
1132 } else {
1133 while (p->rindex < offset + rdlength) {
1134 char *s;
1135
1136 r = dns_packet_read_string(p, &s, NULL);
1137 if (r < 0)
1138 goto fail;
1139
1140 r = strv_consume(&rr->txt.strings, s);
1141 if (r < 0)
1142 goto fail;
1143 }
1144 }
1145
1146 r = 0;
1147 break;
1148
1149 case DNS_TYPE_A:
1150 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1151 break;
1152
1153 case DNS_TYPE_AAAA:
1154 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1155 break;
1156
1157 case DNS_TYPE_SOA:
1158 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
1159 if (r < 0)
1160 goto fail;
1161
1162 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
1163 if (r < 0)
1164 goto fail;
1165
1166 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1167 if (r < 0)
1168 goto fail;
1169
1170 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1171 if (r < 0)
1172 goto fail;
1173
1174 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1175 if (r < 0)
1176 goto fail;
1177
1178 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1179 if (r < 0)
1180 goto fail;
1181
1182 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1183 break;
1184
1185 case DNS_TYPE_MX:
1186 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1187 if (r < 0)
1188 goto fail;
1189
1190 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
1191 break;
1192
1193 case DNS_TYPE_LOC: {
1194 uint8_t t;
1195 size_t pos;
1196
1197 r = dns_packet_read_uint8(p, &t, &pos);
1198 if (r < 0)
1199 goto fail;
1200
1201 if (t == 0) {
1202 rr->loc.version = t;
1203
1204 r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1205 if (r < 0)
1206 goto fail;
1207
1208 if (!loc_size_ok(rr->loc.size)) {
1209 r = -EBADMSG;
1210 goto fail;
1211 }
1212
1213 r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1214 if (r < 0)
1215 goto fail;
1216
1217 if (!loc_size_ok(rr->loc.horiz_pre)) {
1218 r = -EBADMSG;
1219 goto fail;
1220 }
1221
1222 r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1223 if (r < 0)
1224 goto fail;
1225
1226 if (!loc_size_ok(rr->loc.vert_pre)) {
1227 r = -EBADMSG;
1228 goto fail;
1229 }
1230
1231 r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1232 if (r < 0)
1233 goto fail;
1234
1235 r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1236 if (r < 0)
1237 goto fail;
1238
1239 r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1240 if (r < 0)
1241 goto fail;
1242
1243 break;
1244 } else {
1245 dns_packet_rewind(p, pos);
1246 rr->unparseable = true;
1247 goto unparseable;
1248 }
1249 }
1250
1251 case DNS_TYPE_SSHFP:
1252 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1253 if (r < 0)
1254 goto fail;
1255
1256 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1257 if (r < 0)
1258 goto fail;
1259
1260 r = dns_packet_read_public_key(p, rdlength - 2,
1261 &rr->sshfp.key, &rr->sshfp.key_size,
1262 NULL);
1263 break;
1264
1265 case DNS_TYPE_DNSKEY: {
1266 uint16_t flags;
1267 uint8_t proto;
1268
1269 r = dns_packet_read_uint16(p, &flags, NULL);
1270 if (r < 0)
1271 goto fail;
1272
1273 r = dnskey_parse_flags(rr, flags);
1274 if (r < 0)
1275 goto fail;
1276
1277 r = dns_packet_read_uint8(p, &proto, NULL);
1278 if (r < 0)
1279 goto fail;
1280
1281 /* protocol is required to be always 3 */
1282 if (proto != 3) {
1283 r = -EBADMSG;
1284 goto fail;
1285 }
1286
1287 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1288 if (r < 0)
1289 goto fail;
1290
1291 r = dns_packet_read_public_key(p, rdlength - 4,
1292 &rr->dnskey.key, &rr->dnskey.key_size,
1293 NULL);
1294 break;
1295 }
1296
1297 case DNS_TYPE_RRSIG:
1298 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1299 if (r < 0)
1300 goto fail;
1301
1302 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1303 if (r < 0)
1304 goto fail;
1305
1306 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1307 if (r < 0)
1308 goto fail;
1309
1310 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1311 if (r < 0)
1312 goto fail;
1313
1314 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1315 if (r < 0)
1316 goto fail;
1317
1318 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1319 if (r < 0)
1320 goto fail;
1321
1322 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1323 if (r < 0)
1324 goto fail;
1325
1326 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1327 if (r < 0)
1328 goto fail;
1329
1330 r = dns_packet_read_public_key(p, offset + rdlength - p->rindex,
1331 &rr->rrsig.signature, &rr->rrsig.signature_size,
1332 NULL);
1333 break;
1334
1335 default:
1336 unparseable:
1337 r = dns_packet_read(p, rdlength, &d, NULL);
1338 if (r < 0)
1339 goto fail;
1340
1341 rr->generic.data = memdup(d, rdlength);
1342 if (!rr->generic.data) {
1343 r = -ENOMEM;
1344 goto fail;
1345 }
1346
1347 rr->generic.size = rdlength;
1348 break;
1349 }
1350 if (r < 0)
1351 goto fail;
1352 if (p->rindex != offset + rdlength) {
1353 r = -EBADMSG;
1354 goto fail;
1355 }
1356
1357 *ret = rr;
1358 rr = NULL;
1359
1360 if (start)
1361 *start = saved_rindex;
1362
1363 return 0;
1364 fail:
1365 dns_packet_rewind(p, saved_rindex);
1366 return r;
1367 }
1368
1369 int dns_packet_extract(DnsPacket *p) {
1370 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1371 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1372 size_t saved_rindex;
1373 unsigned n, i;
1374 int r;
1375
1376 if (p->extracted)
1377 return 0;
1378
1379 saved_rindex = p->rindex;
1380 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1381
1382 n = DNS_PACKET_QDCOUNT(p);
1383 if (n > 0) {
1384 question = dns_question_new(n);
1385 if (!question) {
1386 r = -ENOMEM;
1387 goto finish;
1388 }
1389
1390 for (i = 0; i < n; i++) {
1391 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1392
1393 r = dns_packet_read_key(p, &key, NULL);
1394 if (r < 0)
1395 goto finish;
1396
1397 r = dns_question_add(question, key);
1398 if (r < 0)
1399 goto finish;
1400 }
1401 }
1402
1403 n = DNS_PACKET_RRCOUNT(p);
1404 if (n > 0) {
1405 answer = dns_answer_new(n);
1406 if (!answer) {
1407 r = -ENOMEM;
1408 goto finish;
1409 }
1410
1411 for (i = 0; i < n; i++) {
1412 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1413
1414 r = dns_packet_read_rr(p, &rr, NULL);
1415 if (r < 0)
1416 goto finish;
1417
1418 r = dns_answer_add(answer, rr);
1419 if (r < 0)
1420 goto finish;
1421 }
1422 }
1423
1424 p->question = question;
1425 question = NULL;
1426
1427 p->answer = answer;
1428 answer = NULL;
1429
1430 p->extracted = true;
1431
1432 r = 0;
1433
1434 finish:
1435 p->rindex = saved_rindex;
1436 return r;
1437 }
1438
1439 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
1440 [DNS_RCODE_SUCCESS] = "SUCCESS",
1441 [DNS_RCODE_FORMERR] = "FORMERR",
1442 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
1443 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
1444 [DNS_RCODE_NOTIMP] = "NOTIMP",
1445 [DNS_RCODE_REFUSED] = "REFUSED",
1446 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
1447 [DNS_RCODE_YXRRSET] = "YRRSET",
1448 [DNS_RCODE_NXRRSET] = "NXRRSET",
1449 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
1450 [DNS_RCODE_NOTZONE] = "NOTZONE",
1451 [DNS_RCODE_BADVERS] = "BADVERS",
1452 [DNS_RCODE_BADKEY] = "BADKEY",
1453 [DNS_RCODE_BADTIME] = "BADTIME",
1454 [DNS_RCODE_BADMODE] = "BADMODE",
1455 [DNS_RCODE_BADNAME] = "BADNAME",
1456 [DNS_RCODE_BADALG] = "BADALG",
1457 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
1458 };
1459 DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1460
1461 static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
1462 [DNS_PROTOCOL_DNS] = "dns",
1463 [DNS_PROTOCOL_MDNS] = "mdns",
1464 [DNS_PROTOCOL_LLMNR] = "llmnr",
1465 };
1466 DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
1467
1468 static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
1469 [DNSSEC_ALGORITHM_RSAMD5] = "RSAMD5",
1470 [DNSSEC_ALGORITHM_DH] = "DH",
1471 [DNSSEC_ALGORITHM_DSA] = "DSA",
1472 [DNSSEC_ALGORITHM_ECC] = "ECC",
1473 [DNSSEC_ALGORITHM_RSASHA1] = "RSASHA1",
1474 [DNSSEC_ALGORITHM_INDIRECT] = "INDIRECT",
1475 [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
1476 [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
1477 };
1478 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);