]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-packet.c
barrier: fix race in test-code
[thirdparty/systemd.git] / src / resolve / resolved-dns-packet.c
CommitLineData
74b2466e
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22#include "utf8.h"
c73ce96b 23#include "util.h"
74b2466e
LP
24#include "resolved-dns-domain.h"
25#include "resolved-dns-packet.h"
26
1716f6dc 27int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
74b2466e
LP
28 DnsPacket *p;
29 size_t a;
30
31 assert(ret);
32
33 if (mtu <= 0)
34 a = DNS_PACKET_SIZE_START;
35 else
36 a = mtu;
37
38 if (a < DNS_PACKET_HEADER_SIZE)
39 a = DNS_PACKET_HEADER_SIZE;
40
c73ce96b
LP
41 /* round up to next page size */
42 a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
43
44 /* make sure we never allocate more than useful */
45 if (a > DNS_PACKET_SIZE_MAX)
46 a = DNS_PACKET_SIZE_MAX;
47
74b2466e
LP
48 p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
49 if (!p)
50 return -ENOMEM;
51
52 p->size = p->rindex = DNS_PACKET_HEADER_SIZE;
53 p->allocated = a;
1716f6dc 54 p->protocol = protocol;
74b2466e
LP
55 p->n_ref = 1;
56
57 *ret = p;
58
59 return 0;
60}
61
1716f6dc 62int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
74b2466e
LP
63 DnsPacket *p;
64 DnsPacketHeader *h;
65 int r;
66
67 assert(ret);
68
1716f6dc 69 r = dns_packet_new(&p, protocol, mtu);
74b2466e
LP
70 if (r < 0)
71 return r;
72
73 h = DNS_PACKET_HEADER(p);
1716f6dc
LP
74
75 if (protocol == DNS_PROTOCOL_DNS)
76 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0, 0, 0, 0, 1, 0, 0, 0, 0)); /* ask for recursion */
77 else
78 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0, 0, 0, 0, 0, 0, 0, 0, 0));
74b2466e
LP
79
80 *ret = p;
81 return 0;
82}
83
84DnsPacket *dns_packet_ref(DnsPacket *p) {
85
86 if (!p)
87 return NULL;
88
89 assert(p->n_ref > 0);
90 p->n_ref++;
91 return p;
92}
93
94static void dns_packet_free(DnsPacket *p) {
95 char *s;
96
97 assert(p);
98
faa133f3
LP
99 dns_question_unref(p->question);
100 dns_answer_unref(p->answer);
322345fd 101
74b2466e
LP
102 while ((s = hashmap_steal_first_key(p->names)))
103 free(s);
104 hashmap_free(p->names);
105
faa133f3 106 free(p->_data);
74b2466e
LP
107 free(p);
108}
109
110DnsPacket *dns_packet_unref(DnsPacket *p) {
111 if (!p)
112 return NULL;
113
114 assert(p->n_ref > 0);
115
116 if (p->n_ref == 1)
117 dns_packet_free(p);
118 else
119 p->n_ref--;
120
121 return NULL;
122}
123
124int dns_packet_validate(DnsPacket *p) {
125 assert(p);
126
127 if (p->size < DNS_PACKET_HEADER_SIZE)
128 return -EBADMSG;
129
c73ce96b
LP
130 if (p->size > DNS_PACKET_SIZE_MAX)
131 return -EBADMSG;
132
74b2466e
LP
133 return 0;
134}
135
136int dns_packet_validate_reply(DnsPacket *p) {
74b2466e
LP
137 int r;
138
139 assert(p);
140
141 r = dns_packet_validate(p);
142 if (r < 0)
143 return r;
144
3cb10d3a 145 if (DNS_PACKET_QR(p) == 0)
74b2466e
LP
146 return -EBADMSG;
147
3cb10d3a 148 if (DNS_PACKET_OPCODE(p) != 0)
74b2466e
LP
149 return -EBADMSG;
150
151 return 0;
152}
153
154static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
155 assert(p);
156
c73ce96b
LP
157 if (p->size + add > p->allocated) {
158 size_t a;
159
160 a = PAGE_ALIGN((p->size + add) * 2);
161 if (a > DNS_PACKET_SIZE_MAX)
162 a = DNS_PACKET_SIZE_MAX;
163
164 if (p->size + add > a)
165 return -EMSGSIZE;
166
faa133f3 167 if (p->_data) {
c73ce96b
LP
168 void *d;
169
faa133f3 170 d = realloc(p->_data, a);
c73ce96b
LP
171 if (!d)
172 return -ENOMEM;
173
faa133f3 174 p->_data = d;
c73ce96b 175 } else {
faa133f3
LP
176 p->_data = malloc(a);
177 if (!p->_data)
c73ce96b
LP
178 return -ENOMEM;
179
faa133f3
LP
180 memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
181 memzero((uint8_t*) p->_data + p->size, a - p->size);
c73ce96b
LP
182 }
183
184 p->allocated = a;
185 }
74b2466e
LP
186
187 if (start)
188 *start = p->size;
189
190 if (ret)
191 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;
192
193 p->size += add;
194 return 0;
195}
196
197static void dns_packet_truncate(DnsPacket *p, size_t sz) {
198 Iterator i;
199 char *s;
200 void *n;
201
202 assert(p);
203
204 if (p->size <= sz)
205 return;
206
207 HASHMAP_FOREACH_KEY(s, n, p->names, i) {
208
209 if (PTR_TO_SIZE(n) < sz)
210 continue;
211
212 hashmap_remove(p->names, s);
213 free(s);
214 }
215
216 p->size = sz;
217}
218
219int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
220 void *d;
221 int r;
222
223 assert(p);
224
225 r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
226 if (r < 0)
227 return r;
228
229 ((uint8_t*) d)[0] = v;
230
231 return 0;
232}
233
234int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
235 void *d;
236 int r;
237
238 assert(p);
239
240 r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
241 if (r < 0)
242 return r;
243
244 ((uint8_t*) d)[0] = (uint8_t) (v >> 8);
245 ((uint8_t*) d)[1] = (uint8_t) (v & 255);
246
247 return 0;
248}
249
250int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
251 void *d;
252 size_t l;
253 int r;
254
255 assert(p);
256 assert(s);
257
258 l = strlen(s);
259 if (l > 255)
260 return -E2BIG;
261
262 r = dns_packet_extend(p, 1 + l, &d, start);
263 if (r < 0)
264 return r;
265
266 ((uint8_t*) d)[0] = (uint8_t) l;
267 memcpy(((uint8_t*) d) + 1, s, l);
268
269 return 0;
270}
271
272int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start) {
273 void *w;
274 int r;
275
276 assert(p);
277 assert(d);
278
279 if (l > DNS_LABEL_MAX)
280 return -E2BIG;
281
282 r = dns_packet_extend(p, 1 + l, &w, start);
283 if (r < 0)
284 return r;
285
286 ((uint8_t*) w)[0] = (uint8_t) l;
287 memcpy(((uint8_t*) w) + 1, d, l);
288
289 return 0;
290}
291
292int dns_packet_append_name(DnsPacket *p, const char *name, size_t *start) {
293 size_t saved_size;
294 int r;
295
296 assert(p);
297 assert(name);
298
299 saved_size = p->size;
300
301 while (*name) {
302 _cleanup_free_ char *s = NULL;
303 char label[DNS_LABEL_MAX];
304 size_t n;
305
306 n = PTR_TO_SIZE(hashmap_get(p->names, name));
307 if (n > 0) {
308 assert(n < p->size);
309
310 if (n < 0x4000) {
311 r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
312 if (r < 0)
313 goto fail;
314
315 goto done;
316 }
317 }
318
319 s = strdup(name);
320 if (!s) {
321 r = -ENOMEM;
322 goto fail;
323 }
324
325 r = dns_label_unescape(&name, label, sizeof(label));
326 if (r < 0)
327 goto fail;
328
329 r = dns_packet_append_label(p, label, r, &n);
330 if (r < 0)
331 goto fail;
332
333 r = hashmap_ensure_allocated(&p->names, dns_name_hash_func, dns_name_compare_func);
334 if (r < 0)
335 goto fail;
336
337 r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
338 if (r < 0)
339 goto fail;
340
341 s = NULL;
342 }
343
344 r = dns_packet_append_uint8(p, 0, NULL);
345 if (r < 0)
346 return r;
347
348done:
349 if (start)
350 *start = saved_size;
351
352 return 0;
353
354fail:
355 dns_packet_truncate(p, saved_size);
356 return r;
357}
358
359int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
360 size_t saved_size;
361 int r;
362
363 assert(p);
364 assert(k);
365
366 saved_size = p->size;
367
faa133f3 368 r = dns_packet_append_name(p, DNS_RESOURCE_KEY_NAME(k), NULL);
74b2466e
LP
369 if (r < 0)
370 goto fail;
371
372 r = dns_packet_append_uint16(p, k->type, NULL);
373 if (r < 0)
374 goto fail;
375
376 r = dns_packet_append_uint16(p, k->class, NULL);
377 if (r < 0)
378 goto fail;
379
380 if (start)
381 *start = saved_size;
382
383 return 0;
384
385fail:
386 dns_packet_truncate(p, saved_size);
387 return r;
388}
389
390int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
391 assert(p);
392
393 if (p->rindex + sz > p->size)
394 return -EMSGSIZE;
395
396 if (ret)
397 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
398
399 if (start)
400 *start = p->rindex;
401
402 p->rindex += sz;
403 return 0;
404}
405
8ba9fd9c 406void dns_packet_rewind(DnsPacket *p, size_t idx) {
74b2466e
LP
407 assert(p);
408 assert(idx <= p->size);
409 assert(idx >= DNS_PACKET_HEADER_SIZE);
410
411 p->rindex = idx;
412}
413
414int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
415 const void *d;
416 int r;
417
418 assert(p);
419
420 r = dns_packet_read(p, sizeof(uint8_t), &d, start);
421 if (r < 0)
422 return r;
423
424 *ret = ((uint8_t*) d)[0];
425 return 0;
426}
427
428int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
429 const void *d;
430 int r;
431
432 assert(p);
433
434 r = dns_packet_read(p, sizeof(uint16_t), &d, start);
435 if (r < 0)
436 return r;
437
438 *ret = (((uint16_t) ((uint8_t*) d)[0]) << 8) |
439 ((uint16_t) ((uint8_t*) d)[1]);
440 return 0;
441}
442
443int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
444 const void *d;
445 int r;
446
447 assert(p);
448
449 r = dns_packet_read(p, sizeof(uint32_t), &d, start);
450 if (r < 0)
451 return r;
452
453 *ret = (((uint32_t) ((uint8_t*) d)[0]) << 24) |
454 (((uint32_t) ((uint8_t*) d)[1]) << 16) |
455 (((uint32_t) ((uint8_t*) d)[2]) << 8) |
456 ((uint32_t) ((uint8_t*) d)[3]);
457
458 return 0;
459}
460
461int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
462 size_t saved_rindex;
463 const void *d;
464 char *t;
465 uint8_t c;
466 int r;
467
468 assert(p);
469
470 saved_rindex = p->rindex;
471
472 r = dns_packet_read_uint8(p, &c, NULL);
473 if (r < 0)
474 goto fail;
475
476 r = dns_packet_read(p, c, &d, NULL);
477 if (r < 0)
478 goto fail;
479
480 if (memchr(d, 0, c)) {
481 r = -EBADMSG;
482 goto fail;
483 }
484
485 t = strndup(d, c);
486 if (!t) {
487 r = -ENOMEM;
488 goto fail;
489 }
490
491 if (!utf8_is_valid(t)) {
492 free(t);
493 r = -EBADMSG;
494 goto fail;
495 }
496
497 *ret = t;
498
499 if (start)
500 *start = saved_rindex;
501
502 return 0;
503
504fail:
505 dns_packet_rewind(p, saved_rindex);
506 return r;
507}
508
509int dns_packet_read_name(DnsPacket *p, char **_ret, size_t *start) {
510 size_t saved_rindex, after_rindex = 0;
511 _cleanup_free_ char *ret = NULL;
512 size_t n = 0, allocated = 0;
513 bool first = true;
514 int r;
515
516 assert(p);
517 assert(_ret);
518
519 saved_rindex = p->rindex;
520
521 for (;;) {
522 uint8_t c, d;
523
524 r = dns_packet_read_uint8(p, &c, NULL);
525 if (r < 0)
526 goto fail;
527
528 if (c == 0)
529 /* End of name */
530 break;
531 else if (c <= 63) {
532 _cleanup_free_ char *t = NULL;
533 const char *label;
534
535 /* Literal label */
536 r = dns_packet_read(p, c, (const void**) &label, NULL);
537 if (r < 0)
538 goto fail;
539
540 r = dns_label_escape(label, c, &t);
541 if (r < 0)
542 goto fail;
543
544 if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) {
545 r = -ENOMEM;
546 goto fail;
547 }
548
549 if (!first)
550 ret[n++] = '.';
551 else
552 first = false;
553
554 memcpy(ret + n, t, c);
555 n += r;
556 continue;
557 } else if ((c & 0xc0) == 0xc0) {
558 uint16_t ptr;
559
560 /* Pointer */
561 r = dns_packet_read_uint8(p, &d, NULL);
562 if (r < 0)
563 goto fail;
564
565 ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
566 if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= saved_rindex) {
567 r = -EBADMSG;
568 goto fail;
569 }
570
571 if (after_rindex == 0)
572 after_rindex = p->rindex;
573
574 p->rindex = ptr;
575 } else
576 goto fail;
577 }
578
579 if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
580 r = -ENOMEM;
581 goto fail;
582 }
583
584 ret[n] = 0;
585
586 if (after_rindex != 0)
587 p->rindex= after_rindex;
588
589 *_ret = ret;
590 ret = NULL;
591
592 if (start)
593 *start = saved_rindex;
594
595 return 0;
596
597fail:
598 dns_packet_rewind(p, saved_rindex);
599 return r;
600}
601
faa133f3
LP
602int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
603 _cleanup_free_ char *name = NULL;
604 uint16_t class, type;
605 DnsResourceKey *key;
74b2466e
LP
606 size_t saved_rindex;
607 int r;
608
609 assert(p);
610 assert(ret);
611
612 saved_rindex = p->rindex;
613
faa133f3 614 r = dns_packet_read_name(p, &name, NULL);
74b2466e
LP
615 if (r < 0)
616 goto fail;
617
faa133f3 618 r = dns_packet_read_uint16(p, &type, NULL);
74b2466e
LP
619 if (r < 0)
620 goto fail;
621
faa133f3 622 r = dns_packet_read_uint16(p, &class, NULL);
74b2466e
LP
623 if (r < 0)
624 goto fail;
625
faa133f3
LP
626 key = dns_resource_key_new_consume(class, type, name);
627 if (!key) {
628 r = -ENOMEM;
629 goto fail;
630 }
631
632 name = NULL;
633 *ret = key;
74b2466e
LP
634
635 if (start)
636 *start = saved_rindex;
637
638 return 0;
639fail:
640 dns_packet_rewind(p, saved_rindex);
641 return r;
642}
643
644int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
faa133f3
LP
645 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
646 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
74b2466e
LP
647 size_t saved_rindex, offset;
648 uint16_t rdlength;
649 const void *d;
650 int r;
651
652 assert(p);
653 assert(ret);
654
4e0296a9 655 saved_rindex = p->rindex;
74b2466e 656
faa133f3 657 r = dns_packet_read_key(p, &key, NULL);
74b2466e
LP
658 if (r < 0)
659 goto fail;
660
faa133f3
LP
661 rr = dns_resource_record_new(key);
662 if (!rr) {
663 r = -ENOMEM;
664 goto fail;
665 }
666
74b2466e
LP
667 r = dns_packet_read_uint32(p, &rr->ttl, NULL);
668 if (r < 0)
669 goto fail;
670
671 r = dns_packet_read_uint16(p, &rdlength, NULL);
672 if (r < 0)
673 goto fail;
674
675 if (p->rindex + rdlength > p->size) {
676 r = -EBADMSG;
677 goto fail;
678 }
679
680 offset = p->rindex;
681
faa133f3 682 switch (rr->key->type) {
74b2466e
LP
683
684 case DNS_TYPE_PTR:
685 case DNS_TYPE_NS:
686 case DNS_TYPE_CNAME:
687 r = dns_packet_read_name(p, &rr->ptr.name, NULL);
688 break;
689
690 case DNS_TYPE_HINFO:
691 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
692 if (r < 0)
693 goto fail;
694
695 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
696 break;
697
698 case DNS_TYPE_A:
699 r = dns_packet_read(p, sizeof(struct in_addr), &d, NULL);
700 if (r < 0)
701 goto fail;
702
703 memcpy(&rr->a.in_addr, d, sizeof(struct in_addr));
704 break;
705
706 case DNS_TYPE_AAAA:
707 r = dns_packet_read(p, sizeof(struct in6_addr), &d, NULL);
708 if (r < 0)
709 goto fail;
710
711 memcpy(&rr->aaaa.in6_addr, d, sizeof(struct in6_addr));
712 break;
713
7e8e0422
LP
714 case DNS_TYPE_SOA:
715 r = dns_packet_read_name(p, &rr->soa.mname, NULL);
716 if (r < 0)
717 goto fail;
718
719 r = dns_packet_read_name(p, &rr->soa.rname, NULL);
720 if (r < 0)
721 goto fail;
722
723 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
724 if (r < 0)
725 goto fail;
726
727 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
728 if (r < 0)
729 goto fail;
730
731 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
732 if (r < 0)
733 goto fail;
734
735 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
736 if (r < 0)
737 goto fail;
738
739 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
740 break;
741
74b2466e
LP
742 default:
743 r = dns_packet_read(p, rdlength, &d, NULL);
744 if (r < 0)
745 goto fail;
746
747 rr->generic.data = memdup(d, rdlength);
748 if (!rr->generic.data) {
749 r = -ENOMEM;
750 goto fail;
751 }
752
753 rr->generic.size = rdlength;
754 break;
755 }
756 if (r < 0)
757 goto fail;
758 if (p->rindex != offset + rdlength) {
759 r = -EBADMSG;
760 goto fail;
761 }
762
763 *ret = rr;
764 rr = NULL;
765
766 if (start)
767 *start = saved_rindex;
768
769 return 0;
770fail:
771 dns_packet_rewind(p, saved_rindex);
772 return r;
773}
774
faa133f3
LP
775int dns_packet_extract(DnsPacket *p) {
776 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
777 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
778 size_t saved_rindex;
779 unsigned n, i;
74b2466e
LP
780 int r;
781
faa133f3 782 saved_rindex = p->rindex;
322345fd
LP
783 dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
784
3cb10d3a 785 n = DNS_PACKET_QDCOUNT(p);
faa133f3
LP
786 if (n > 0) {
787 question = dns_question_new(n);
788 if (!question) {
789 r = -ENOMEM;
790 goto finish;
791 }
74b2466e 792
faa133f3
LP
793 for (i = 0; i < n; i++) {
794 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
74b2466e 795
faa133f3
LP
796 r = dns_packet_read_key(p, &key, NULL);
797 if (r < 0)
798 goto finish;
74b2466e 799
faa133f3
LP
800 r = dns_question_add(question, key);
801 if (r < 0)
802 goto finish;
803 }
804 }
322345fd 805
faa133f3
LP
806 n = DNS_PACKET_RRCOUNT(p);
807 if (n > 0) {
808 answer = dns_answer_new(n);
809 if (!answer) {
810 r = -ENOMEM;
811 goto finish;
812 }
322345fd 813
faa133f3
LP
814 for (i = 0; i < n; i++) {
815 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
322345fd 816
faa133f3
LP
817 r = dns_packet_read_rr(p, &rr, NULL);
818 if (r < 0)
819 goto finish;
322345fd 820
faa133f3
LP
821 r = dns_answer_add(answer, rr);
822 if (r < 0)
823 goto finish;
824 }
322345fd
LP
825 }
826
faa133f3
LP
827 p->question = question;
828 question = NULL;
322345fd 829
faa133f3
LP
830 p->answer = answer;
831 answer = NULL;
322345fd 832
faa133f3 833 r = 0;
322345fd
LP
834
835finish:
836 p->rindex = saved_rindex;
837 return r;
838}
839
74b2466e
LP
840static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
841 [DNS_RCODE_SUCCESS] = "SUCCESS",
842 [DNS_RCODE_FORMERR] = "FORMERR",
843 [DNS_RCODE_SERVFAIL] = "SERVFAIL",
844 [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
845 [DNS_RCODE_NOTIMP] = "NOTIMP",
846 [DNS_RCODE_REFUSED] = "REFUSED",
847 [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
848 [DNS_RCODE_YXRRSET] = "YRRSET",
849 [DNS_RCODE_NXRRSET] = "NXRRSET",
850 [DNS_RCODE_NOTAUTH] = "NOTAUTH",
851 [DNS_RCODE_NOTZONE] = "NOTZONE",
852 [DNS_RCODE_BADVERS] = "BADVERS",
853 [DNS_RCODE_BADKEY] = "BADKEY",
854 [DNS_RCODE_BADTIME] = "BADTIME",
855 [DNS_RCODE_BADMODE] = "BADMODE",
856 [DNS_RCODE_BADNAME] = "BADNAME",
857 [DNS_RCODE_BADALG] = "BADALG",
858 [DNS_RCODE_BADTRUNC] = "BADTRUNC",
859};
860DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1716f6dc
LP
861
862static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
863 [DNS_PROTOCOL_DNS] = "dns",
864 [DNS_PROTOCOL_MDNS] = "mdns",
865 [DNS_PROTOCOL_LLMNR] = "llmnr",
866};
867DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);