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