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