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