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