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