]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-packet.c
TODO
[thirdparty/systemd.git] / src / resolve / resolved-dns-packet.c
CommitLineData
74b2466e
LP
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
b5efdb8a 22#include "alloc-util.h"
4ad7f276 23#include "dns-domain.h"
74b2466e 24#include "resolved-dns-packet.h"
8b43440b
LP
25#include "string-table.h"
26#include "strv.h"
27#include "unaligned.h"
28#include "utf8.h"
29#include "util.h"
74b2466e 30
7586f4d1
TG
31#define EDNS0_OPT_DO (1<<15)
32
1716f6dc 33int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
74b2466e
LP
34 DnsPacket *p;
35 size_t a;
36
37 assert(ret);
38
a0166609 39 if (mtu <= UDP_PACKET_HEADER_SIZE)
74b2466e
LP
40 a = DNS_PACKET_SIZE_START;
41 else
a0166609 42 a = mtu - UDP_PACKET_HEADER_SIZE;
74b2466e
LP
43
44 if (a < DNS_PACKET_HEADER_SIZE)
45 a = DNS_PACKET_HEADER_SIZE;
46
c73ce96b
LP
47 /* round up to next page size */
48 a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
49
50 /* make sure we never allocate more than useful */
51 if (a > DNS_PACKET_SIZE_MAX)
52 a = DNS_PACKET_SIZE_MAX;
53
74b2466e
LP
54 p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
55 if (!p)
56 return -ENOMEM;
57
58 p->size = p->rindex = DNS_PACKET_HEADER_SIZE;
59 p->allocated = a;
1716f6dc 60 p->protocol = protocol;
74b2466e
LP
61 p->n_ref = 1;
62
63 *ret = p;
64
65 return 0;
66}
67
dbfbb6e7 68void dns_packet_set_flags(DnsPacket *p, bool dnssec_checking_disabled, bool truncated) {
74b2466e 69
dbfbb6e7 70 DnsPacketHeader *h;
74b2466e 71
dbfbb6e7 72 assert(p);
74b2466e
LP
73
74 h = DNS_PACKET_HEADER(p);
1716f6dc 75
dbfbb6e7
DM
76 switch(p->protocol) {
77 case DNS_PROTOCOL_LLMNR:
78 assert(!truncated);
79
069360a6
LP
80 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
81 0 /* opcode */,
82 0 /* c */,
dbfbb6e7 83 0/* tc */,
069360a6
LP
84 0 /* t */,
85 0 /* ra */,
86 0 /* ad */,
87 0 /* cd */,
88 0 /* rcode */));
dbfbb6e7
DM
89 break;
90
91 case DNS_PROTOCOL_MDNS:
92 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
93 0 /* opcode */,
94 0 /* aa */,
95 truncated /* tc */,
96 0 /* rd (ask for recursion) */,
97 0 /* ra */,
98 0 /* ad */,
99 0 /* cd */,
100 0 /* rcode */));
101 break;
102
103 default:
104 assert(!truncated);
105
069360a6
LP
106 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
107 0 /* opcode */,
108 0 /* aa */,
109 0 /* tc */,
110 1 /* rd (ask for recursion) */,
111 0 /* ra */,
112 0 /* ad */,
24710c48 113 dnssec_checking_disabled /* cd */,
069360a6 114 0 /* rcode */));
dbfbb6e7
DM
115 }
116}
117
118int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu, bool dnssec_checking_disabled) {
119 DnsPacket *p;
120 int r;
121
122 assert(ret);
123
124 r = dns_packet_new(&p, protocol, mtu);
125 if (r < 0)
126 return r;
127
128 /* Always set the TC bit to 0 initially.
129 * If there are multiple packets later, we'll update the bit shortly before sending.
130 */
131 dns_packet_set_flags(p, dnssec_checking_disabled, false);
74b2466e
LP
132
133 *ret = p;
134 return 0;
135}
136
137DnsPacket *dns_packet_ref(DnsPacket *p) {
138
139 if (!p)
140 return NULL;
141
a8812dd7
LP
142 assert(!p->on_stack);
143
74b2466e
LP
144 assert(p->n_ref > 0);
145 p->n_ref++;
146 return p;
147}
148
149static void dns_packet_free(DnsPacket *p) {
150 char *s;
151
152 assert(p);
153
faa133f3
LP
154 dns_question_unref(p->question);
155 dns_answer_unref(p->answer);
d75acfb0 156 dns_resource_record_unref(p->opt);
322345fd 157
74b2466e
LP
158 while ((s = hashmap_steal_first_key(p->names)))
159 free(s);
160 hashmap_free(p->names);
161
faa133f3 162 free(p->_data);
a8812dd7
LP
163
164 if (!p->on_stack)
165 free(p);
74b2466e
LP
166}
167
168DnsPacket *dns_packet_unref(DnsPacket *p) {
169 if (!p)
170 return NULL;
171
172 assert(p->n_ref > 0);
173
9c491563
DM
174 if (p->more)
175 dns_packet_unref(p->more);
176
74b2466e
LP
177 if (p->n_ref == 1)
178 dns_packet_free(p);
179 else
180 p->n_ref--;
181
182 return NULL;
183}
184
185int dns_packet_validate(DnsPacket *p) {
186 assert(p);
187
188 if (p->size < DNS_PACKET_HEADER_SIZE)
189 return -EBADMSG;
190
c73ce96b
LP
191 if (p->size > DNS_PACKET_SIZE_MAX)
192 return -EBADMSG;
193
623a4c97 194 return 1;
74b2466e
LP
195}
196
197int dns_packet_validate_reply(DnsPacket *p) {
74b2466e
LP
198 int r;
199
200 assert(p);
201
202 r = dns_packet_validate(p);
203 if (r < 0)
204 return r;
205
623a4c97
LP
206 if (DNS_PACKET_QR(p) != 1)
207 return 0;
208
209 if (DNS_PACKET_OPCODE(p) != 0)
74b2466e
LP
210 return -EBADMSG;
211
818ef443 212 switch (p->protocol) {
d75acfb0 213
818ef443
DM
214 case DNS_PROTOCOL_LLMNR:
215 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
216 if (DNS_PACKET_QDCOUNT(p) != 1)
217 return -EBADMSG;
218
219 break;
220
4e5bf5e1
DM
221 case DNS_PROTOCOL_MDNS:
222 /* RFC 6762, Section 18 */
223 if (DNS_PACKET_RCODE(p) != 0)
224 return -EBADMSG;
225
226 break;
227
818ef443
DM
228 default:
229 break;
230 }
ea917db9 231
623a4c97
LP
232 return 1;
233}
234
235int dns_packet_validate_query(DnsPacket *p) {
236 int r;
237
238 assert(p);
239
240 r = dns_packet_validate(p);
241 if (r < 0)
242 return r;
243
244 if (DNS_PACKET_QR(p) != 0)
245 return 0;
246
3cb10d3a 247 if (DNS_PACKET_OPCODE(p) != 0)
74b2466e
LP
248 return -EBADMSG;
249
623a4c97
LP
250 if (DNS_PACKET_TC(p))
251 return -EBADMSG;
252
818ef443 253 switch (p->protocol) {
d75acfb0 254
818ef443
DM
255 case DNS_PROTOCOL_LLMNR:
256 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
257 if (DNS_PACKET_QDCOUNT(p) != 1)
258 return -EBADMSG;
623a4c97 259
818ef443
DM
260 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
261 if (DNS_PACKET_ANCOUNT(p) > 0)
262 return -EBADMSG;
623a4c97 263
818ef443
DM
264 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
265 if (DNS_PACKET_NSCOUNT(p) > 0)
266 return -EBADMSG;
267
268 break;
269
4e5bf5e1
DM
270 case DNS_PROTOCOL_MDNS:
271 /* RFC 6762, Section 18 */
272 if (DNS_PACKET_AA(p) != 0 ||
273 DNS_PACKET_RD(p) != 0 ||
274 DNS_PACKET_RA(p) != 0 ||
275 DNS_PACKET_AD(p) != 0 ||
276 DNS_PACKET_CD(p) != 0 ||
277 DNS_PACKET_RCODE(p) != 0)
278 return -EBADMSG;
279
280 break;
281
818ef443
DM
282 default:
283 break;
284 }
623a4c97
LP
285
286 return 1;
74b2466e
LP
287}
288
289static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
290 assert(p);
291
c73ce96b
LP
292 if (p->size + add > p->allocated) {
293 size_t a;
294
295 a = PAGE_ALIGN((p->size + add) * 2);
296 if (a > DNS_PACKET_SIZE_MAX)
297 a = DNS_PACKET_SIZE_MAX;
298
299 if (p->size + add > a)
300 return -EMSGSIZE;
301
faa133f3 302 if (p->_data) {
c73ce96b
LP
303 void *d;
304
faa133f3 305 d = realloc(p->_data, a);
c73ce96b
LP
306 if (!d)
307 return -ENOMEM;
308
faa133f3 309 p->_data = d;
c73ce96b 310 } else {
faa133f3
LP
311 p->_data = malloc(a);
312 if (!p->_data)
c73ce96b
LP
313 return -ENOMEM;
314
faa133f3
LP
315 memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
316 memzero((uint8_t*) p->_data + p->size, a - p->size);
c73ce96b
LP
317 }
318
319 p->allocated = a;
320 }
74b2466e
LP
321
322 if (start)
323 *start = p->size;
324
325 if (ret)
326 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;
327
328 p->size += add;
329 return 0;
330}
331
9c5e12a4 332void dns_packet_truncate(DnsPacket *p, size_t sz) {
74b2466e
LP
333 Iterator i;
334 char *s;
335 void *n;
336
337 assert(p);
338
339 if (p->size <= sz)
340 return;
341
0e03ade5 342 HASHMAP_FOREACH_KEY(n, s, p->names, i) {
74b2466e
LP
343
344 if (PTR_TO_SIZE(n) < sz)
345 continue;
346
347 hashmap_remove(p->names, s);
348 free(s);
349 }
350
351 p->size = sz;
352}
353
623a4c97
LP
354int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
355 void *q;
356 int r;
357
358 assert(p);
359
360 r = dns_packet_extend(p, l, &q, start);
361 if (r < 0)
362 return r;
363
364 memcpy(q, d, l);
365 return 0;
366}
367
74b2466e
LP
368int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
369 void *d;
370 int r;
371
372 assert(p);
373
374 r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
375 if (r < 0)
376 return r;
377
378 ((uint8_t*) d)[0] = v;
379
380 return 0;
381}
382
383int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
384 void *d;
385 int r;
386
387 assert(p);
388
389 r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
390 if (r < 0)
391 return r;
392
725ca0e5 393 unaligned_write_be16(d, v);
623a4c97
LP
394
395 return 0;
396}
397
398int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start) {
399 void *d;
400 int r;
401
402 assert(p);
403
404 r = dns_packet_extend(p, sizeof(uint32_t), &d, start);
405 if (r < 0)
406 return r;
407
725ca0e5 408 unaligned_write_be32(d, v);
74b2466e
LP
409
410 return 0;
411}
412
413int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
74b2466e
LP
414 assert(p);
415 assert(s);
416
c38a52da 417 return dns_packet_append_raw_string(p, s, strlen(s), start);
74b2466e
LP
418}
419
2001c805
LP
420int dns_packet_append_raw_string(DnsPacket *p, const void *s, size_t size, size_t *start) {
421 void *d;
422 int r;
423
424 assert(p);
425 assert(s || size == 0);
426
427 if (size > 255)
428 return -E2BIG;
429
430 r = dns_packet_extend(p, 1 + size, &d, start);
431 if (r < 0)
432 return r;
433
434 ((uint8_t*) d)[0] = (uint8_t) size;
435
436 if (size > 0)
437 memcpy(((uint8_t*) d) + 1, s, size);
438
439 return 0;
440}
441
74b2466e 442int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start) {
a8812dd7 443 uint8_t *w;
74b2466e
LP
444 int r;
445
446 assert(p);
447 assert(d);
448
449 if (l > DNS_LABEL_MAX)
450 return -E2BIG;
451
a8812dd7 452 r = dns_packet_extend(p, 1 + l, (void**) &w, start);
74b2466e
LP
453 if (r < 0)
454 return r;
455
a8812dd7
LP
456 *(w++) = (uint8_t) l;
457
458 if (p->canonical_form) {
459 size_t i;
460
461 /* Generate in canonical form, as defined by DNSSEC
462 * RFC 4034, Section 6.2, i.e. all lower-case. */
463
464 for (i = 0; i < l; i++) {
465 if (d[i] >= 'A' && d[i] <= 'Z')
466 w[i] = (uint8_t) (d[i] - 'A' + 'a');
467 else
468 w[i] = (uint8_t) d[i];
469 }
470 } else
471 /* Otherwise, just copy the string unaltered. This is
472 * essential for DNS-SD, where the casing of labels
473 * matters and needs to be retained. */
474 memcpy(w, d, l);
74b2466e
LP
475
476 return 0;
477}
478
f6a5fec6
LP
479int dns_packet_append_name(
480 DnsPacket *p,
481 const char *name,
482 bool allow_compression,
483 size_t *start) {
484
74b2466e
LP
485 size_t saved_size;
486 int r;
487
488 assert(p);
489 assert(name);
490
f6a5fec6
LP
491 if (p->refuse_compression)
492 allow_compression = false;
493
74b2466e
LP
494 saved_size = p->size;
495
496 while (*name) {
497 _cleanup_free_ char *s = NULL;
498 char label[DNS_LABEL_MAX];
151226ab 499 size_t n = 0;
bdf10b5b 500 int k;
74b2466e 501
151226ab
ZJS
502 if (allow_compression)
503 n = PTR_TO_SIZE(hashmap_get(p->names, name));
74b2466e
LP
504 if (n > 0) {
505 assert(n < p->size);
506
507 if (n < 0x4000) {
508 r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
509 if (r < 0)
510 goto fail;
511
512 goto done;
513 }
514 }
515
516 s = strdup(name);
517 if (!s) {
518 r = -ENOMEM;
519 goto fail;
520 }
521
522 r = dns_label_unescape(&name, label, sizeof(label));
523 if (r < 0)
524 goto fail;
525
bdf10b5b
LP
526 if (p->protocol == DNS_PROTOCOL_DNS)
527 k = dns_label_apply_idna(label, r, label, sizeof(label));
528 else
529 k = dns_label_undo_idna(label, r, label, sizeof(label));
530 if (k < 0) {
531 r = k;
532 goto fail;
533 }
534 if (k > 0)
535 r = k;
536
74b2466e
LP
537 r = dns_packet_append_label(p, label, r, &n);
538 if (r < 0)
539 goto fail;
540
151226ab 541 if (allow_compression) {
d5099efc 542 r = hashmap_ensure_allocated(&p->names, &dns_name_hash_ops);
151226ab
ZJS
543 if (r < 0)
544 goto fail;
74b2466e 545
151226ab
ZJS
546 r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
547 if (r < 0)
548 goto fail;
74b2466e 549
151226ab
ZJS
550 s = NULL;
551 }
74b2466e
LP
552 }
553
554 r = dns_packet_append_uint8(p, 0, NULL);
555 if (r < 0)
556 return r;
557
558done:
559 if (start)
560 *start = saved_size;
561
562 return 0;
563
564fail:
565 dns_packet_truncate(p, saved_size);
566 return r;
567}
568
569int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
570 size_t saved_size;
571 int r;
572
573 assert(p);
574 assert(k);
575
576 saved_size = p->size;
577
151226ab 578 r = dns_packet_append_name(p, DNS_RESOURCE_KEY_NAME(k), true, NULL);
74b2466e
LP
579 if (r < 0)
580 goto fail;
581
582 r = dns_packet_append_uint16(p, k->type, NULL);
583 if (r < 0)
584 goto fail;
585
586 r = dns_packet_append_uint16(p, k->class, NULL);
587 if (r < 0)
588 goto fail;
589
590 if (start)
591 *start = saved_size;
592
593 return 0;
594
595fail:
596 dns_packet_truncate(p, saved_size);
597 return r;
598}
599
50f1e641
TG
600static int dns_packet_append_type_window(DnsPacket *p, uint8_t window, uint8_t length, uint8_t *types, size_t *start) {
601 size_t saved_size;
602 int r;
603
604 assert(p);
605 assert(types);
1792f223 606 assert(length > 0);
50f1e641 607
50f1e641
TG
608 saved_size = p->size;
609
1792f223
TG
610 r = dns_packet_append_uint8(p, window, NULL);
611 if (r < 0)
612 goto fail;
50f1e641 613
1792f223
TG
614 r = dns_packet_append_uint8(p, length, NULL);
615 if (r < 0)
616 goto fail;
6fa91901 617
1792f223
TG
618 r = dns_packet_append_blob(p, types, length, NULL);
619 if (r < 0)
620 goto fail;
50f1e641
TG
621
622 if (start)
623 *start = saved_size;
624
625 return 0;
626fail:
627 dns_packet_truncate(p, saved_size);
628 return r;
629}
630
631static int dns_packet_append_types(DnsPacket *p, Bitmap *types, size_t *start) {
cb57dd41 632 Iterator i;
50f1e641 633 uint8_t window = 0;
1792f223 634 uint8_t entry = 0;
50f1e641
TG
635 uint8_t bitmaps[32] = {};
636 unsigned n;
637 size_t saved_size;
638 int r;
639
640 assert(p);
641 assert(types);
642
643 saved_size = p->size;
644
cb57dd41 645 BITMAP_FOREACH(n, types, i) {
50f1e641
TG
646 assert(n <= 0xffff);
647
1792f223
TG
648 if ((n >> 8) != window && bitmaps[entry / 8] != 0) {
649 r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
50f1e641
TG
650 if (r < 0)
651 goto fail;
652
1792f223 653 zero(bitmaps);
50f1e641
TG
654 }
655
1792f223 656 window = n >> 8;
50f1e641
TG
657
658 entry = n & 255;
659
660 bitmaps[entry / 8] |= 1 << (7 - (entry % 8));
661 }
662
1792f223 663 r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
50f1e641
TG
664 if (r < 0)
665 goto fail;
666
667 if (start)
668 *start = saved_size;
669
670 return 0;
671fail:
672 dns_packet_truncate(p, saved_size);
673 return r;
674}
675
dc913c9a 676/* Append the OPT pseudo-RR described in RFC6891 */
7586f4d1 677int dns_packet_append_opt_rr(DnsPacket *p, uint16_t max_udp_size, bool edns0_do, size_t *start) {
dc913c9a
TG
678 size_t saved_size;
679 int r;
680
681 assert(p);
682 /* we must never advertise supported packet size smaller than the legacy max */
683 assert(max_udp_size >= DNS_PACKET_UNICAST_SIZE_MAX);
684
685 saved_size = p->size;
686
687 /* empty name */
688 r = dns_packet_append_uint8(p, 0, NULL);
689 if (r < 0)
690 return r;
691
692 /* type */
693 r = dns_packet_append_uint16(p, DNS_TYPE_OPT, NULL);
694 if (r < 0)
695 goto fail;
696
697 /* maximum udp packet that can be received */
698 r = dns_packet_append_uint16(p, max_udp_size, NULL);
699 if (r < 0)
700 goto fail;
701
702 /* extended RCODE and VERSION */
703 r = dns_packet_append_uint16(p, 0, NULL);
704 if (r < 0)
705 goto fail;
706
7586f4d1
TG
707 /* flags: DNSSEC OK (DO), see RFC3225 */
708 r = dns_packet_append_uint16(p, edns0_do ? EDNS0_OPT_DO : 0, NULL);
dc913c9a
TG
709 if (r < 0)
710 goto fail;
711
712 /* RDLENGTH */
713 r = dns_packet_append_uint16(p, 0, NULL);
714 if (r < 0)
715 goto fail;
716
717 if (start)
718 *start = saved_size;
719
720 return 0;
721
722fail:
723 dns_packet_truncate(p, saved_size);
724 return r;
725}
726
a8812dd7
LP
727int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start, size_t *rdata_start) {
728 size_t saved_size, rdlength_offset, end, rdlength, rds;
623a4c97
LP
729 int r;
730
731 assert(p);
732 assert(rr);
733
734 saved_size = p->size;
735
736 r = dns_packet_append_key(p, rr->key, NULL);
737 if (r < 0)
738 goto fail;
739
740 r = dns_packet_append_uint32(p, rr->ttl, NULL);
741 if (r < 0)
742 goto fail;
743
744 /* Initially we write 0 here */
745 r = dns_packet_append_uint16(p, 0, &rdlength_offset);
746 if (r < 0)
747 goto fail;
748
a8812dd7
LP
749 rds = p->size - saved_size;
750
0dae31d4 751 switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
623a4c97 752
9c92ce6d
LP
753 case DNS_TYPE_SRV:
754 r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
755 if (r < 0)
756 goto fail;
757
758 r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
759 if (r < 0)
760 goto fail;
761
762 r = dns_packet_append_uint16(p, rr->srv.port, NULL);
763 if (r < 0)
764 goto fail;
765
151226ab 766 r = dns_packet_append_name(p, rr->srv.name, true, NULL);
9c92ce6d
LP
767 break;
768
623a4c97
LP
769 case DNS_TYPE_PTR:
770 case DNS_TYPE_NS:
771 case DNS_TYPE_CNAME:
8ac4e9e1 772 case DNS_TYPE_DNAME:
151226ab 773 r = dns_packet_append_name(p, rr->ptr.name, true, NULL);
623a4c97
LP
774 break;
775
776 case DNS_TYPE_HINFO:
777 r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
778 if (r < 0)
779 goto fail;
780
781 r = dns_packet_append_string(p, rr->hinfo.os, NULL);
782 break;
783
9de3e329 784 case DNS_TYPE_SPF: /* exactly the same as TXT */
2001c805 785 case DNS_TYPE_TXT:
2e276efc 786
2001c805 787 if (!rr->txt.items) {
1ccda9b7
LP
788 /* RFC 6763, section 6.1 suggests to generate
789 * single empty string for an empty array. */
790
2001c805 791 r = dns_packet_append_raw_string(p, NULL, 0, NULL);
2e276efc
ZJS
792 if (r < 0)
793 goto fail;
1ccda9b7 794 } else {
2001c805
LP
795 DnsTxtItem *i;
796
797 LIST_FOREACH(items, i, rr->txt.items) {
798 r = dns_packet_append_raw_string(p, i->data, i->length, NULL);
1ccda9b7
LP
799 if (r < 0)
800 goto fail;
801 }
2e276efc
ZJS
802 }
803
6a6fc3df 804 r = 0;
2e276efc 805 break;
2e276efc 806
623a4c97
LP
807 case DNS_TYPE_A:
808 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
809 break;
810
811 case DNS_TYPE_AAAA:
812 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
813 break;
814
815 case DNS_TYPE_SOA:
151226ab 816 r = dns_packet_append_name(p, rr->soa.mname, true, NULL);
623a4c97
LP
817 if (r < 0)
818 goto fail;
819
151226ab 820 r = dns_packet_append_name(p, rr->soa.rname, true, NULL);
623a4c97
LP
821 if (r < 0)
822 goto fail;
823
824 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
825 if (r < 0)
826 goto fail;
827
828 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
829 if (r < 0)
830 goto fail;
831
832 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
833 if (r < 0)
834 goto fail;
835
836 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
837 if (r < 0)
838 goto fail;
839
840 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
841 break;
842
843 case DNS_TYPE_MX:
946c7094
ZJS
844 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
845 if (r < 0)
846 goto fail;
847
151226ab 848 r = dns_packet_append_name(p, rr->mx.exchange, true, NULL);
946c7094
ZJS
849 break;
850
0dae31d4
ZJS
851 case DNS_TYPE_LOC:
852 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
853 if (r < 0)
854 goto fail;
855
856 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
857 if (r < 0)
858 goto fail;
859
860 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
861 if (r < 0)
862 goto fail;
863
864 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
865 if (r < 0)
866 goto fail;
867
afbc4f26 868 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
0dae31d4
ZJS
869 if (r < 0)
870 goto fail;
871
afbc4f26 872 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
0dae31d4
ZJS
873 if (r < 0)
874 goto fail;
875
afbc4f26 876 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
0dae31d4
ZJS
877 break;
878
abf126a3
TG
879 case DNS_TYPE_DS:
880 r = dns_packet_append_uint16(p, rr->ds.key_tag, NULL);
881 if (r < 0)
882 goto fail;
883
884 r = dns_packet_append_uint8(p, rr->ds.algorithm, NULL);
885 if (r < 0)
886 goto fail;
887
888 r = dns_packet_append_uint8(p, rr->ds.digest_type, NULL);
889 if (r < 0)
890 goto fail;
891
892 r = dns_packet_append_blob(p, rr->ds.digest, rr->ds.digest_size, NULL);
893 break;
894
623a4c97 895 case DNS_TYPE_SSHFP:
42cc2eeb
LP
896 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
897 if (r < 0)
898 goto fail;
8db0d2f5 899
42cc2eeb
LP
900 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
901 if (r < 0)
902 goto fail;
903
549c1a25 904 r = dns_packet_append_blob(p, rr->sshfp.fingerprint, rr->sshfp.fingerprint_size, NULL);
42cc2eeb
LP
905 break;
906
8db0d2f5 907 case DNS_TYPE_DNSKEY:
f91dc240 908 r = dns_packet_append_uint16(p, rr->dnskey.flags, NULL);
8db0d2f5
ZJS
909 if (r < 0)
910 goto fail;
911
f91dc240 912 r = dns_packet_append_uint8(p, rr->dnskey.protocol, NULL);
8db0d2f5
ZJS
913 if (r < 0)
914 goto fail;
915
916 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
917 if (r < 0)
918 goto fail;
919
920 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
921 break;
922
151226ab
ZJS
923 case DNS_TYPE_RRSIG:
924 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
925 if (r < 0)
926 goto fail;
927
928 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
929 if (r < 0)
930 goto fail;
931
932 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
933 if (r < 0)
934 goto fail;
935
936 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
937 if (r < 0)
938 goto fail;
939
940 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
941 if (r < 0)
942 goto fail;
943
944 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
945 if (r < 0)
946 goto fail;
947
0b1b17d3 948 r = dns_packet_append_uint16(p, rr->rrsig.key_tag, NULL);
151226ab
ZJS
949 if (r < 0)
950 goto fail;
951
952 r = dns_packet_append_name(p, rr->rrsig.signer, false, NULL);
953 if (r < 0)
954 goto fail;
955
956 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
957 break;
958
50f1e641
TG
959 case DNS_TYPE_NSEC:
960 r = dns_packet_append_name(p, rr->nsec.next_domain_name, false, NULL);
961 if (r < 0)
962 goto fail;
963
964 r = dns_packet_append_types(p, rr->nsec.types, NULL);
965 if (r < 0)
966 goto fail;
967
5d45a880 968 break;
d75acfb0 969
5d45a880
TG
970 case DNS_TYPE_NSEC3:
971 r = dns_packet_append_uint8(p, rr->nsec3.algorithm, NULL);
972 if (r < 0)
973 goto fail;
974
975 r = dns_packet_append_uint8(p, rr->nsec3.flags, NULL);
976 if (r < 0)
977 goto fail;
978
979 r = dns_packet_append_uint16(p, rr->nsec3.iterations, NULL);
980 if (r < 0)
981 goto fail;
982
983 r = dns_packet_append_uint8(p, rr->nsec3.salt_size, NULL);
984 if (r < 0)
985 goto fail;
986
987 r = dns_packet_append_blob(p, rr->nsec3.salt, rr->nsec3.salt_size, NULL);
988 if (r < 0)
989 goto fail;
990
991 r = dns_packet_append_uint8(p, rr->nsec3.next_hashed_name_size, NULL);
992 if (r < 0)
993 goto fail;
994
995 r = dns_packet_append_blob(p, rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, NULL);
996 if (r < 0)
997 goto fail;
998
999 r = dns_packet_append_types(p, rr->nsec3.types, NULL);
1000 if (r < 0)
1001 goto fail;
1002
50f1e641 1003 break;
d75acfb0
LP
1004
1005 case DNS_TYPE_OPT:
0dae31d4 1006 case _DNS_TYPE_INVALID: /* unparseable */
623a4c97 1007 default:
0dae31d4 1008
623a4c97
LP
1009 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
1010 break;
1011 }
1012 if (r < 0)
1013 goto fail;
1014
1015 /* Let's calculate the actual data size and update the field */
1016 rdlength = p->size - rdlength_offset - sizeof(uint16_t);
1017 if (rdlength > 0xFFFF) {
1018 r = ENOSPC;
1019 goto fail;
1020 }
1021
1022 end = p->size;
1023 p->size = rdlength_offset;
1024 r = dns_packet_append_uint16(p, rdlength, NULL);
1025 if (r < 0)
1026 goto fail;
1027 p->size = end;
1028
351e6342
LP
1029 if (start)
1030 *start = saved_size;
1031
a8812dd7
LP
1032 if (rdata_start)
1033 *rdata_start = rds;
1034
623a4c97
LP
1035 return 0;
1036
1037fail:
1038 dns_packet_truncate(p, saved_size);
1039 return r;
1040}
1041
1042
74b2466e
LP
1043int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
1044 assert(p);
1045
1046 if (p->rindex + sz > p->size)
1047 return -EMSGSIZE;
1048
1049 if (ret)
1050 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
1051
1052 if (start)
1053 *start = p->rindex;
1054
1055 p->rindex += sz;
1056 return 0;
1057}
1058
8ba9fd9c 1059void dns_packet_rewind(DnsPacket *p, size_t idx) {
74b2466e
LP
1060 assert(p);
1061 assert(idx <= p->size);
1062 assert(idx >= DNS_PACKET_HEADER_SIZE);
1063
1064 p->rindex = idx;
1065}
1066
623a4c97
LP
1067int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
1068 const void *q;
1069 int r;
1070
1071 assert(p);
1072 assert(d);
1073
1074 r = dns_packet_read(p, sz, &q, start);
1075 if (r < 0)
1076 return r;
1077
1078 memcpy(d, q, sz);
1079 return 0;
1080}
1081
f5430a3e
LP
1082static int dns_packet_read_memdup(
1083 DnsPacket *p, size_t size,
1084 void **ret, size_t *ret_size,
1085 size_t *ret_start) {
1086
1087 const void *src;
1088 size_t start;
1089 int r;
1090
1091 assert(p);
1092 assert(ret);
1093
1094 r = dns_packet_read(p, size, &src, &start);
1095 if (r < 0)
1096 return r;
1097
1098 if (size <= 0)
1099 *ret = NULL;
1100 else {
1101 void *copy;
1102
1103 copy = memdup(src, size);
1104 if (!copy)
1105 return -ENOMEM;
1106
1107 *ret = copy;
1108 }
1109
1110 if (ret_size)
1111 *ret_size = size;
1112 if (ret_start)
1113 *ret_start = start;
1114
1115 return 0;
1116}
1117
74b2466e
LP
1118int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
1119 const void *d;
1120 int r;
1121
1122 assert(p);
1123
1124 r = dns_packet_read(p, sizeof(uint8_t), &d, start);
1125 if (r < 0)
1126 return r;
1127
1128 *ret = ((uint8_t*) d)[0];
1129 return 0;
1130}
1131
1132int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
1133 const void *d;
1134 int r;
1135
1136 assert(p);
1137
1138 r = dns_packet_read(p, sizeof(uint16_t), &d, start);
1139 if (r < 0)
1140 return r;
1141
725ca0e5
TG
1142 *ret = unaligned_read_be16(d);
1143
74b2466e
LP
1144 return 0;
1145}
1146
1147int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
1148 const void *d;
1149 int r;
1150
1151 assert(p);
1152
1153 r = dns_packet_read(p, sizeof(uint32_t), &d, start);
1154 if (r < 0)
1155 return r;
1156
725ca0e5 1157 *ret = unaligned_read_be32(d);
74b2466e
LP
1158
1159 return 0;
1160}
1161
1162int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
1163 size_t saved_rindex;
1164 const void *d;
1165 char *t;
1166 uint8_t c;
1167 int r;
1168
1169 assert(p);
1170
1171 saved_rindex = p->rindex;
1172
1173 r = dns_packet_read_uint8(p, &c, NULL);
1174 if (r < 0)
1175 goto fail;
1176
1177 r = dns_packet_read(p, c, &d, NULL);
1178 if (r < 0)
1179 goto fail;
1180
1181 if (memchr(d, 0, c)) {
1182 r = -EBADMSG;
1183 goto fail;
1184 }
1185
1186 t = strndup(d, c);
1187 if (!t) {
1188 r = -ENOMEM;
1189 goto fail;
1190 }
1191
1192 if (!utf8_is_valid(t)) {
1193 free(t);
1194 r = -EBADMSG;
1195 goto fail;
1196 }
1197
1198 *ret = t;
1199
1200 if (start)
1201 *start = saved_rindex;
1202
1203 return 0;
1204
1205fail:
1206 dns_packet_rewind(p, saved_rindex);
1207 return r;
1208}
1209
2001c805
LP
1210int dns_packet_read_raw_string(DnsPacket *p, const void **ret, size_t *size, size_t *start) {
1211 size_t saved_rindex;
1212 uint8_t c;
1213 int r;
1214
1215 assert(p);
1216
1217 saved_rindex = p->rindex;
1218
1219 r = dns_packet_read_uint8(p, &c, NULL);
1220 if (r < 0)
1221 goto fail;
1222
1223 r = dns_packet_read(p, c, ret, NULL);
1224 if (r < 0)
1225 goto fail;
1226
1227 if (size)
1228 *size = c;
1229 if (start)
1230 *start = saved_rindex;
1231
1232 return 0;
1233
1234fail:
1235 dns_packet_rewind(p, saved_rindex);
1236 return r;
1237}
1238
f6a5fec6
LP
1239int dns_packet_read_name(
1240 DnsPacket *p,
1241 char **_ret,
1242 bool allow_compression,
1243 size_t *start) {
1244
c75dbf9b 1245 size_t saved_rindex, after_rindex = 0, jump_barrier;
74b2466e
LP
1246 _cleanup_free_ char *ret = NULL;
1247 size_t n = 0, allocated = 0;
1248 bool first = true;
1249 int r;
1250
1251 assert(p);
1252 assert(_ret);
1253
f6a5fec6
LP
1254 if (p->refuse_compression)
1255 allow_compression = false;
1256
74b2466e 1257 saved_rindex = p->rindex;
c75dbf9b 1258 jump_barrier = p->rindex;
74b2466e
LP
1259
1260 for (;;) {
1261 uint8_t c, d;
1262
1263 r = dns_packet_read_uint8(p, &c, NULL);
1264 if (r < 0)
1265 goto fail;
1266
1267 if (c == 0)
1268 /* End of name */
1269 break;
1270 else if (c <= 63) {
74b2466e
LP
1271 const char *label;
1272
1273 /* Literal label */
1274 r = dns_packet_read(p, c, (const void**) &label, NULL);
1275 if (r < 0)
1276 goto fail;
1277
422baca0 1278 if (!GREEDY_REALLOC(ret, allocated, n + !first + DNS_LABEL_ESCAPED_MAX)) {
74b2466e
LP
1279 r = -ENOMEM;
1280 goto fail;
1281 }
1282
422baca0 1283 if (first)
74b2466e 1284 first = false;
422baca0
LP
1285 else
1286 ret[n++] = '.';
1287
1288 r = dns_label_escape(label, c, ret + n, DNS_LABEL_ESCAPED_MAX);
1289 if (r < 0)
1290 goto fail;
74b2466e 1291
74b2466e
LP
1292 n += r;
1293 continue;
151226ab 1294 } else if (allow_compression && (c & 0xc0) == 0xc0) {
74b2466e
LP
1295 uint16_t ptr;
1296
1297 /* Pointer */
1298 r = dns_packet_read_uint8(p, &d, NULL);
1299 if (r < 0)
1300 goto fail;
1301
1302 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
c75dbf9b 1303 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier) {
74b2466e
LP
1304 r = -EBADMSG;
1305 goto fail;
1306 }
1307
1308 if (after_rindex == 0)
1309 after_rindex = p->rindex;
1310
f131770b 1311 /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
c75dbf9b 1312 jump_barrier = ptr;
74b2466e 1313 p->rindex = ptr;
59aa5821
SP
1314 } else {
1315 r = -EBADMSG;
74b2466e 1316 goto fail;
59aa5821 1317 }
74b2466e
LP
1318 }
1319
1320 if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
1321 r = -ENOMEM;
1322 goto fail;
1323 }
1324
1325 ret[n] = 0;
1326
1327 if (after_rindex != 0)
1328 p->rindex= after_rindex;
1329
1330 *_ret = ret;
1331 ret = NULL;
1332
1333 if (start)
1334 *start = saved_rindex;
1335
1336 return 0;
1337
1338fail:
1339 dns_packet_rewind(p, saved_rindex);
1340 return r;
1341}
1342
50f1e641
TG
1343static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *start) {
1344 uint8_t window;
1345 uint8_t length;
1346 const uint8_t *bitmap;
2ad613ad 1347 uint8_t bit = 0;
50f1e641
TG
1348 unsigned i;
1349 bool found = false;
1350 size_t saved_rindex;
1351 int r;
1352
1353 assert(p);
1354 assert(types);
1355
1356 saved_rindex = p->rindex;
1357
1358 r = bitmap_ensure_allocated(types);
1359 if (r < 0)
1360 goto fail;
1361
1362 r = dns_packet_read_uint8(p, &window, NULL);
1363 if (r < 0)
1364 goto fail;
1365
1366 r = dns_packet_read_uint8(p, &length, NULL);
1367 if (r < 0)
1368 goto fail;
1369
1370 if (length == 0 || length > 32)
1371 return -EBADMSG;
1372
1373 r = dns_packet_read(p, length, (const void **)&bitmap, NULL);
1374 if (r < 0)
1375 goto fail;
1376
1377 for (i = 0; i < length; i++) {
1378 uint8_t bitmask = 1 << 7;
50f1e641
TG
1379
1380 if (!bitmap[i]) {
1381 found = false;
2ad613ad 1382 bit += 8;
50f1e641
TG
1383 continue;
1384 }
1385
1386 found = true;
1387
1388 while (bitmask) {
1389 if (bitmap[i] & bitmask) {
1390 uint16_t n;
1391
50f1e641
TG
1392 n = (uint16_t) window << 8 | (uint16_t) bit;
1393
8e6edc49
TG
1394 /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1395 if (dns_type_is_pseudo(n))
1396 continue;
1397
50f1e641
TG
1398 r = bitmap_set(*types, n);
1399 if (r < 0)
1400 goto fail;
1401 }
1402
1403 bit ++;
1404 bitmask >>= 1;
1405 }
1406 }
1407
1408 if (!found)
1409 return -EBADMSG;
1410
1411 if (start)
1412 *start = saved_rindex;
1413
1414 return 0;
1415fail:
1416 dns_packet_rewind(p, saved_rindex);
1417 return r;
1418}
1419
89492aaf
TG
1420static int dns_packet_read_type_windows(DnsPacket *p, Bitmap **types, size_t size, size_t *start) {
1421 size_t saved_rindex;
1422 int r;
1423
1424 saved_rindex = p->rindex;
1425
1426 while (p->rindex < saved_rindex + size) {
1427 r = dns_packet_read_type_window(p, types, NULL);
1428 if (r < 0)
1429 goto fail;
1430
1431 /* don't read past end of current RR */
1432 if (p->rindex > saved_rindex + size) {
1433 r = -EBADMSG;
1434 goto fail;
1435 }
1436 }
1437
1438 if (p->rindex != saved_rindex + size) {
1439 r = -EBADMSG;
1440 goto fail;
1441 }
1442
1443 if (start)
1444 *start = saved_rindex;
1445
1446 return 0;
1447fail:
1448 dns_packet_rewind(p, saved_rindex);
1449 return r;
1450}
1451
faa133f3
LP
1452int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
1453 _cleanup_free_ char *name = NULL;
23502de3 1454 bool cache_flush = false;
faa133f3
LP
1455 uint16_t class, type;
1456 DnsResourceKey *key;
74b2466e
LP
1457 size_t saved_rindex;
1458 int r;
1459
1460 assert(p);
1461 assert(ret);
1462
1463 saved_rindex = p->rindex;
1464
151226ab 1465 r = dns_packet_read_name(p, &name, true, NULL);
74b2466e
LP
1466 if (r < 0)
1467 goto fail;
1468
faa133f3 1469 r = dns_packet_read_uint16(p, &type, NULL);
74b2466e
LP
1470 if (r < 0)
1471 goto fail;
1472
faa133f3 1473 r = dns_packet_read_uint16(p, &class, NULL);
74b2466e
LP
1474 if (r < 0)
1475 goto fail;
1476
23502de3
DM
1477 if (p->protocol == DNS_PROTOCOL_MDNS) {
1478 /* See RFC6762, Section 10.2 */
1479
1480 if (class & MDNS_RR_CACHE_FLUSH) {
1481 class &= ~MDNS_RR_CACHE_FLUSH;
1482 cache_flush = true;
1483 }
1484 }
1485
faa133f3
LP
1486 key = dns_resource_key_new_consume(class, type, name);
1487 if (!key) {
1488 r = -ENOMEM;
1489 goto fail;
1490 }
1491
23502de3
DM
1492 key->cache_flush = cache_flush;
1493
faa133f3
LP
1494 name = NULL;
1495 *ret = key;
74b2466e
LP
1496
1497 if (start)
1498 *start = saved_rindex;
1499
1500 return 0;
1501fail:
1502 dns_packet_rewind(p, saved_rindex);
1503 return r;
1504}
1505
afbc4f26
ZJS
1506static bool loc_size_ok(uint8_t size) {
1507 uint8_t m = size >> 4, e = size & 0xF;
1508
1509 return m <= 9 && e <= 9 && (m > 0 || e == 0);
1510}
1511
74b2466e 1512int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
faa133f3
LP
1513 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1514 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
74b2466e
LP
1515 size_t saved_rindex, offset;
1516 uint16_t rdlength;
74b2466e
LP
1517 int r;
1518
1519 assert(p);
1520 assert(ret);
1521
4e0296a9 1522 saved_rindex = p->rindex;
74b2466e 1523
faa133f3 1524 r = dns_packet_read_key(p, &key, NULL);
74b2466e
LP
1525 if (r < 0)
1526 goto fail;
1527
0e2bcd6a 1528 if (key->class == DNS_CLASS_ANY ||
8b5b5649
LP
1529 key->type == DNS_TYPE_ANY ||
1530 key->type == DNS_TYPE_AXFR ||
1531 key->type == DNS_TYPE_IXFR) {
0e2bcd6a
LP
1532 r = -EBADMSG;
1533 goto fail;
1534 }
1535
faa133f3
LP
1536 rr = dns_resource_record_new(key);
1537 if (!rr) {
1538 r = -ENOMEM;
1539 goto fail;
1540 }
1541
74b2466e
LP
1542 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1543 if (r < 0)
1544 goto fail;
1545
1546 r = dns_packet_read_uint16(p, &rdlength, NULL);
1547 if (r < 0)
1548 goto fail;
1549
1550 if (p->rindex + rdlength > p->size) {
1551 r = -EBADMSG;
1552 goto fail;
1553 }
1554
1555 offset = p->rindex;
1556
faa133f3 1557 switch (rr->key->type) {
74b2466e 1558
9c92ce6d
LP
1559 case DNS_TYPE_SRV:
1560 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1561 if (r < 0)
1562 goto fail;
1563 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1564 if (r < 0)
1565 goto fail;
1566 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1567 if (r < 0)
1568 goto fail;
151226ab 1569 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
9c92ce6d
LP
1570 break;
1571
74b2466e
LP
1572 case DNS_TYPE_PTR:
1573 case DNS_TYPE_NS:
1574 case DNS_TYPE_CNAME:
8ac4e9e1 1575 case DNS_TYPE_DNAME:
151226ab 1576 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
74b2466e
LP
1577 break;
1578
1579 case DNS_TYPE_HINFO:
1580 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1581 if (r < 0)
1582 goto fail;
1583
1584 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1585 break;
1586
9de3e329 1587 case DNS_TYPE_SPF: /* exactly the same as TXT */
1ccda9b7
LP
1588 case DNS_TYPE_TXT:
1589 if (rdlength <= 0) {
2001c805 1590 DnsTxtItem *i;
1ccda9b7
LP
1591 /* RFC 6763, section 6.1 suggests to treat
1592 * empty TXT RRs as equivalent to a TXT record
1593 * with a single empty string. */
0e3434ae 1594
2001c805
LP
1595 i = malloc0(offsetof(DnsTxtItem, data) + 1); /* for safety reasons we add an extra NUL byte */
1596 if (!i)
1597 return -ENOMEM;
1598
1599 rr->txt.items = i;
1ccda9b7 1600 } else {
2001c805
LP
1601 DnsTxtItem *last = NULL;
1602
1ccda9b7 1603 while (p->rindex < offset + rdlength) {
2001c805
LP
1604 DnsTxtItem *i;
1605 const void *data;
1606 size_t sz;
2e276efc 1607
2001c805 1608 r = dns_packet_read_raw_string(p, &data, &sz, NULL);
1ccda9b7 1609 if (r < 0)
2001c805 1610 return r;
1ccda9b7 1611
2001c805
LP
1612 i = malloc0(offsetof(DnsTxtItem, data) + sz + 1); /* extra NUL byte at the end */
1613 if (!i)
1614 return -ENOMEM;
1615
1616 memcpy(i->data, data, sz);
1617 i->length = sz;
1618
1619 LIST_INSERT_AFTER(items, rr->txt.items, last, i);
1620 last = i;
1ccda9b7 1621 }
6a6fc3df
LP
1622 }
1623
1624 r = 0;
2e276efc 1625 break;
2e276efc 1626
74b2466e 1627 case DNS_TYPE_A:
623a4c97 1628 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
74b2466e
LP
1629 break;
1630
1631 case DNS_TYPE_AAAA:
623a4c97 1632 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
74b2466e
LP
1633 break;
1634
7e8e0422 1635 case DNS_TYPE_SOA:
151226ab 1636 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
7e8e0422
LP
1637 if (r < 0)
1638 goto fail;
1639
151226ab 1640 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
7e8e0422
LP
1641 if (r < 0)
1642 goto fail;
1643
1644 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1645 if (r < 0)
1646 goto fail;
1647
1648 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1649 if (r < 0)
1650 goto fail;
1651
1652 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1653 if (r < 0)
1654 goto fail;
1655
1656 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1657 if (r < 0)
1658 goto fail;
1659
1660 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1661 break;
1662
623a4c97 1663 case DNS_TYPE_MX:
946c7094
ZJS
1664 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1665 if (r < 0)
1666 goto fail;
1667
151226ab 1668 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
946c7094
ZJS
1669 break;
1670
0dae31d4
ZJS
1671 case DNS_TYPE_LOC: {
1672 uint8_t t;
1673 size_t pos;
1674
1675 r = dns_packet_read_uint8(p, &t, &pos);
1676 if (r < 0)
1677 goto fail;
1678
1679 if (t == 0) {
1680 rr->loc.version = t;
1681
1682 r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1683 if (r < 0)
1684 goto fail;
1685
afbc4f26
ZJS
1686 if (!loc_size_ok(rr->loc.size)) {
1687 r = -EBADMSG;
1688 goto fail;
1689 }
1690
0dae31d4
ZJS
1691 r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1692 if (r < 0)
1693 goto fail;
1694
afbc4f26
ZJS
1695 if (!loc_size_ok(rr->loc.horiz_pre)) {
1696 r = -EBADMSG;
1697 goto fail;
1698 }
1699
0dae31d4
ZJS
1700 r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1701 if (r < 0)
1702 goto fail;
1703
afbc4f26
ZJS
1704 if (!loc_size_ok(rr->loc.vert_pre)) {
1705 r = -EBADMSG;
1706 goto fail;
1707 }
1708
0dae31d4
ZJS
1709 r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1710 if (r < 0)
1711 goto fail;
1712
1713 r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1714 if (r < 0)
1715 goto fail;
1716
1717 r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1718 if (r < 0)
1719 goto fail;
1720
1721 break;
1722 } else {
1723 dns_packet_rewind(p, pos);
1724 rr->unparseable = true;
afbc4f26 1725 goto unparseable;
0dae31d4
ZJS
1726 }
1727 }
1728
abf126a3
TG
1729 case DNS_TYPE_DS:
1730 r = dns_packet_read_uint16(p, &rr->ds.key_tag, NULL);
1731 if (r < 0)
1732 goto fail;
1733
1734 r = dns_packet_read_uint8(p, &rr->ds.algorithm, NULL);
1735 if (r < 0)
1736 goto fail;
1737
1738 r = dns_packet_read_uint8(p, &rr->ds.digest_type, NULL);
1739 if (r < 0)
1740 goto fail;
1741
f5430a3e
LP
1742 r = dns_packet_read_memdup(p, rdlength - 4,
1743 &rr->ds.digest, &rr->ds.digest_size,
1744 NULL);
abf126a3
TG
1745 if (r < 0)
1746 goto fail;
1747
f1d178cc
TG
1748 if (rr->ds.digest_size <= 0) {
1749 /* the accepted size depends on the algorithm, but for now
1750 just ensure that the value is greater than zero */
1751 r = -EBADMSG;
1752 goto fail;
1753 }
1754
abf126a3 1755 break;
d75acfb0 1756
623a4c97 1757 case DNS_TYPE_SSHFP:
42cc2eeb
LP
1758 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1759 if (r < 0)
1760 goto fail;
1761
1762 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1763 if (r < 0)
1764 goto fail;
1765
f5430a3e 1766 r = dns_packet_read_memdup(p, rdlength - 2,
549c1a25 1767 &rr->sshfp.fingerprint, &rr->sshfp.fingerprint_size,
f5430a3e 1768 NULL);
f1d178cc 1769
549c1a25 1770 if (rr->sshfp.fingerprint_size <= 0) {
f1d178cc
TG
1771 /* the accepted size depends on the algorithm, but for now
1772 just ensure that the value is greater than zero */
1773 r = -EBADMSG;
1774 goto fail;
1775 }
1776
8db0d2f5
ZJS
1777 break;
1778
f91dc240
LP
1779 case DNS_TYPE_DNSKEY:
1780 r = dns_packet_read_uint16(p, &rr->dnskey.flags, NULL);
8db0d2f5
ZJS
1781 if (r < 0)
1782 goto fail;
1783
f91dc240 1784 r = dns_packet_read_uint8(p, &rr->dnskey.protocol, NULL);
8db0d2f5
ZJS
1785 if (r < 0)
1786 goto fail;
1787
8db0d2f5
ZJS
1788 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1789 if (r < 0)
1790 goto fail;
1791
f5430a3e
LP
1792 r = dns_packet_read_memdup(p, rdlength - 4,
1793 &rr->dnskey.key, &rr->dnskey.key_size,
1794 NULL);
f1d178cc
TG
1795
1796 if (rr->dnskey.key_size <= 0) {
1797 /* the accepted size depends on the algorithm, but for now
1798 just ensure that the value is greater than zero */
1799 r = -EBADMSG;
1800 goto fail;
1801 }
1802
42cc2eeb
LP
1803 break;
1804
151226ab
ZJS
1805 case DNS_TYPE_RRSIG:
1806 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1807 if (r < 0)
1808 goto fail;
1809
1810 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1811 if (r < 0)
1812 goto fail;
1813
1814 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1815 if (r < 0)
1816 goto fail;
1817
1818 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1819 if (r < 0)
1820 goto fail;
1821
1822 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1823 if (r < 0)
1824 goto fail;
1825
1826 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1827 if (r < 0)
1828 goto fail;
1829
1830 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1831 if (r < 0)
1832 goto fail;
1833
1834 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1835 if (r < 0)
1836 goto fail;
1837
f5430a3e
LP
1838 r = dns_packet_read_memdup(p, offset + rdlength - p->rindex,
1839 &rr->rrsig.signature, &rr->rrsig.signature_size,
1840 NULL);
f1d178cc
TG
1841
1842 if (rr->rrsig.signature_size <= 0) {
1843 /* the accepted size depends on the algorithm, but for now
1844 just ensure that the value is greater than zero */
1845 r = -EBADMSG;
1846 goto fail;
1847 }
1848
151226ab
ZJS
1849 break;
1850
d84e543d
DM
1851 case DNS_TYPE_NSEC: {
1852
1853 /*
1854 * RFC6762, section 18.14 explicly states mDNS should use name compression.
1855 * This contradicts RFC3845, section 2.1.1
1856 */
1857
1858 bool allow_compressed = p->protocol == DNS_PROTOCOL_MDNS;
1859
1860 r = dns_packet_read_name(p, &rr->nsec.next_domain_name, allow_compressed, NULL);
50f1e641
TG
1861 if (r < 0)
1862 goto fail;
1863
89492aaf
TG
1864 r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL);
1865 if (r < 0)
1866 goto fail;
1867
09eaf68c
TG
1868 /* We accept empty NSEC bitmaps. The bit indicating the presence of the NSEC record itself
1869 * is redundant and in e.g., RFC4956 this fact is used to define a use for NSEC records
1870 * without the NSEC bit set. */
50f1e641
TG
1871
1872 break;
d84e543d 1873 }
5d45a880
TG
1874 case DNS_TYPE_NSEC3: {
1875 uint8_t size;
1876
1877 r = dns_packet_read_uint8(p, &rr->nsec3.algorithm, NULL);
1878 if (r < 0)
1879 goto fail;
1880
1881 r = dns_packet_read_uint8(p, &rr->nsec3.flags, NULL);
1882 if (r < 0)
1883 goto fail;
1884
1885 r = dns_packet_read_uint16(p, &rr->nsec3.iterations, NULL);
1886 if (r < 0)
1887 goto fail;
1888
f1d178cc 1889 /* this may be zero */
5d45a880
TG
1890 r = dns_packet_read_uint8(p, &size, NULL);
1891 if (r < 0)
1892 goto fail;
1893
f5430a3e 1894 r = dns_packet_read_memdup(p, size, &rr->nsec3.salt, &rr->nsec3.salt_size, NULL);
5d45a880
TG
1895 if (r < 0)
1896 goto fail;
1897
5d45a880
TG
1898 r = dns_packet_read_uint8(p, &size, NULL);
1899 if (r < 0)
1900 goto fail;
1901
f1d178cc
TG
1902 if (size <= 0) {
1903 r = -EBADMSG;
1904 goto fail;
1905 }
1906
f5430a3e 1907 r = dns_packet_read_memdup(p, size, &rr->nsec3.next_hashed_name, &rr->nsec3.next_hashed_name_size, NULL);
5d45a880
TG
1908 if (r < 0)
1909 goto fail;
1910
6b9308d1 1911 r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL);
5d45a880
TG
1912 if (r < 0)
1913 goto fail;
1914
0bbd72b2
TG
1915 /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
1916
5d45a880
TG
1917 break;
1918 }
d75acfb0
LP
1919
1920 case DNS_TYPE_OPT: /* we only care about the header of OPT for now. */
74b2466e 1921 default:
afbc4f26 1922 unparseable:
f5430a3e 1923 r = dns_packet_read_memdup(p, rdlength, &rr->generic.data, &rr->generic.size, NULL);
74b2466e
LP
1924 if (r < 0)
1925 goto fail;
74b2466e
LP
1926 break;
1927 }
1928 if (r < 0)
1929 goto fail;
1930 if (p->rindex != offset + rdlength) {
1931 r = -EBADMSG;
1932 goto fail;
1933 }
1934
1935 *ret = rr;
1936 rr = NULL;
1937
1938 if (start)
1939 *start = saved_rindex;
1940
1941 return 0;
1942fail:
1943 dns_packet_rewind(p, saved_rindex);
1944 return r;
1945}
1946
faa133f3
LP
1947int dns_packet_extract(DnsPacket *p) {
1948 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1949 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1950 size_t saved_rindex;
1951 unsigned n, i;
74b2466e
LP
1952 int r;
1953
a4076574
LP
1954 if (p->extracted)
1955 return 0;
1956
faa133f3 1957 saved_rindex = p->rindex;
322345fd
LP
1958 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1959
3cb10d3a 1960 n = DNS_PACKET_QDCOUNT(p);
faa133f3
LP
1961 if (n > 0) {
1962 question = dns_question_new(n);
1963 if (!question) {
1964 r = -ENOMEM;
1965 goto finish;
1966 }
74b2466e 1967
faa133f3
LP
1968 for (i = 0; i < n; i++) {
1969 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
74b2466e 1970
faa133f3
LP
1971 r = dns_packet_read_key(p, &key, NULL);
1972 if (r < 0)
1973 goto finish;
74b2466e 1974
faa133f3
LP
1975 r = dns_question_add(question, key);
1976 if (r < 0)
1977 goto finish;
1978 }
1979 }
322345fd 1980
faa133f3
LP
1981 n = DNS_PACKET_RRCOUNT(p);
1982 if (n > 0) {
1983 answer = dns_answer_new(n);
1984 if (!answer) {
1985 r = -ENOMEM;
1986 goto finish;
1987 }
322345fd 1988
faa133f3
LP
1989 for (i = 0; i < n; i++) {
1990 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
322345fd 1991
faa133f3
LP
1992 r = dns_packet_read_rr(p, &rr, NULL);
1993 if (r < 0)
1994 goto finish;
322345fd 1995
d75acfb0
LP
1996 if (rr->key->type == DNS_TYPE_OPT) {
1997 if (p->opt)
1998 return -EBADMSG;
1999
2000 p->opt = dns_resource_record_ref(rr);
2001 } else {
2002 r = dns_answer_add(answer, rr, p->ifindex);
2003 if (r < 0)
2004 goto finish;
2005 }
faa133f3 2006 }
322345fd
LP
2007 }
2008
faa133f3
LP
2009 p->question = question;
2010 question = NULL;
322345fd 2011
faa133f3
LP
2012 p->answer = answer;
2013 answer = NULL;
322345fd 2014
a4076574
LP
2015 p->extracted = true;
2016
faa133f3 2017 r = 0;
322345fd
LP
2018
2019finish:
2020 p->rindex = saved_rindex;
2021 return r;
2022}
2023
8af5b883
LP
2024int dns_packet_is_reply_for(DnsPacket *p, const DnsResourceKey *key) {
2025 int r;
2026
2027 assert(p);
2028 assert(key);
2029
2030 /* Checks if the specified packet is a reply for the specified
2031 * key and the specified key is the only one in the question
2032 * section. */
2033
2034 if (DNS_PACKET_QR(p) != 1)
2035 return 0;
2036
2037 /* Let's unpack the packet, if that hasn't happened yet. */
2038 r = dns_packet_extract(p);
2039 if (r < 0)
2040 return r;
2041
2042 if (p->question->n_keys != 1)
2043 return 0;
2044
2045 return dns_resource_key_equal(p->question->keys[0], key);
2046}
2047
74b2466e
LP
2048static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
2049 [DNS_RCODE_SUCCESS] = "SUCCESS",
2050 [DNS_RCODE_FORMERR] = "FORMERR",
2051 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
2052 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
2053 [DNS_RCODE_NOTIMP] = "NOTIMP",
2054 [DNS_RCODE_REFUSED] = "REFUSED",
2055 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
2056 [DNS_RCODE_YXRRSET] = "YRRSET",
2057 [DNS_RCODE_NXRRSET] = "NXRRSET",
2058 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
2059 [DNS_RCODE_NOTZONE] = "NOTZONE",
2060 [DNS_RCODE_BADVERS] = "BADVERS",
2061 [DNS_RCODE_BADKEY] = "BADKEY",
2062 [DNS_RCODE_BADTIME] = "BADTIME",
2063 [DNS_RCODE_BADMODE] = "BADMODE",
2064 [DNS_RCODE_BADNAME] = "BADNAME",
2065 [DNS_RCODE_BADALG] = "BADALG",
2066 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
2067};
2068DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1716f6dc
LP
2069
2070static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
2071 [DNS_PROTOCOL_DNS] = "dns",
2072 [DNS_PROTOCOL_MDNS] = "mdns",
2073 [DNS_PROTOCOL_LLMNR] = "llmnr",
2074};
2075DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);