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