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