1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
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.
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.
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/>.
25 #include "resolved-dns-domain.h"
26 #include "resolved-dns-packet.h"
28 int dns_packet_new(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
35 a
= DNS_PACKET_SIZE_START
;
39 if (a
< DNS_PACKET_HEADER_SIZE
)
40 a
= DNS_PACKET_HEADER_SIZE
;
42 /* round up to next page size */
43 a
= PAGE_ALIGN(ALIGN(sizeof(DnsPacket
)) + a
) - ALIGN(sizeof(DnsPacket
));
45 /* make sure we never allocate more than useful */
46 if (a
> DNS_PACKET_SIZE_MAX
)
47 a
= DNS_PACKET_SIZE_MAX
;
49 p
= malloc0(ALIGN(sizeof(DnsPacket
)) + a
);
53 p
->size
= p
->rindex
= DNS_PACKET_HEADER_SIZE
;
55 p
->protocol
= protocol
;
63 int dns_packet_new_query(DnsPacket
**ret
, DnsProtocol protocol
, size_t mtu
) {
70 r
= dns_packet_new(&p
, protocol
, mtu
);
74 h
= DNS_PACKET_HEADER(p
);
76 if (protocol
== DNS_PROTOCOL_LLMNR
)
77 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
87 h
->flags
= htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
91 1 /* rd (ask for recursion) */,
101 DnsPacket
*dns_packet_ref(DnsPacket
*p
) {
106 assert(p
->n_ref
> 0);
111 static void dns_packet_free(DnsPacket
*p
) {
116 dns_question_unref(p
->question
);
117 dns_answer_unref(p
->answer
);
119 while ((s
= hashmap_steal_first_key(p
->names
)))
121 hashmap_free(p
->names
);
127 DnsPacket
*dns_packet_unref(DnsPacket
*p
) {
131 assert(p
->n_ref
> 0);
141 int dns_packet_validate(DnsPacket
*p
) {
144 if (p
->size
< DNS_PACKET_HEADER_SIZE
)
147 if (p
->size
> DNS_PACKET_SIZE_MAX
)
153 int dns_packet_validate_reply(DnsPacket
*p
) {
158 r
= dns_packet_validate(p
);
162 if (DNS_PACKET_QR(p
) != 1)
165 if (DNS_PACKET_OPCODE(p
) != 0)
168 /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
169 if (p
->protocol
== DNS_PROTOCOL_LLMNR
&&
170 DNS_PACKET_QDCOUNT(p
) != 1)
176 int dns_packet_validate_query(DnsPacket
*p
) {
181 r
= dns_packet_validate(p
);
185 if (DNS_PACKET_QR(p
) != 0)
188 if (DNS_PACKET_OPCODE(p
) != 0)
191 if (DNS_PACKET_TC(p
))
194 /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
195 if (p
->protocol
== DNS_PROTOCOL_LLMNR
&&
196 DNS_PACKET_QDCOUNT(p
) != 1)
199 /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
200 if (DNS_PACKET_ANCOUNT(p
) > 0)
203 /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
204 if (DNS_PACKET_NSCOUNT(p
) > 0)
210 static int dns_packet_extend(DnsPacket
*p
, size_t add
, void **ret
, size_t *start
) {
213 if (p
->size
+ add
> p
->allocated
) {
216 a
= PAGE_ALIGN((p
->size
+ add
) * 2);
217 if (a
> DNS_PACKET_SIZE_MAX
)
218 a
= DNS_PACKET_SIZE_MAX
;
220 if (p
->size
+ add
> a
)
226 d
= realloc(p
->_data
, a
);
232 p
->_data
= malloc(a
);
236 memcpy(p
->_data
, (uint8_t*) p
+ ALIGN(sizeof(DnsPacket
)), p
->size
);
237 memzero((uint8_t*) p
->_data
+ p
->size
, a
- p
->size
);
247 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->size
;
253 static void dns_packet_truncate(DnsPacket
*p
, size_t sz
) {
263 HASHMAP_FOREACH_KEY(s
, n
, p
->names
, i
) {
265 if (PTR_TO_SIZE(n
) < sz
)
268 hashmap_remove(p
->names
, s
);
275 int dns_packet_append_blob(DnsPacket
*p
, const void *d
, size_t l
, size_t *start
) {
281 r
= dns_packet_extend(p
, l
, &q
, start
);
289 int dns_packet_append_uint8(DnsPacket
*p
, uint8_t v
, size_t *start
) {
295 r
= dns_packet_extend(p
, sizeof(uint8_t), &d
, start
);
299 ((uint8_t*) d
)[0] = v
;
304 int dns_packet_append_uint16(DnsPacket
*p
, uint16_t v
, size_t *start
) {
310 r
= dns_packet_extend(p
, sizeof(uint16_t), &d
, start
);
314 ((uint8_t*) d
)[0] = (uint8_t) (v
>> 8);
315 ((uint8_t*) d
)[1] = (uint8_t) v
;
320 int dns_packet_append_uint32(DnsPacket
*p
, uint32_t v
, size_t *start
) {
326 r
= dns_packet_extend(p
, sizeof(uint32_t), &d
, start
);
330 ((uint8_t*) d
)[0] = (uint8_t) (v
>> 24);
331 ((uint8_t*) d
)[1] = (uint8_t) (v
>> 16);
332 ((uint8_t*) d
)[2] = (uint8_t) (v
>> 8);
333 ((uint8_t*) d
)[3] = (uint8_t) v
;
338 int dns_packet_append_string(DnsPacket
*p
, const char *s
, size_t *start
) {
350 r
= dns_packet_extend(p
, 1 + l
, &d
, start
);
354 ((uint8_t*) d
)[0] = (uint8_t) l
;
355 memcpy(((uint8_t*) d
) + 1, s
, l
);
360 int dns_packet_append_label(DnsPacket
*p
, const char *d
, size_t l
, size_t *start
) {
367 if (l
> DNS_LABEL_MAX
)
370 r
= dns_packet_extend(p
, 1 + l
, &w
, start
);
374 ((uint8_t*) w
)[0] = (uint8_t) l
;
375 memcpy(((uint8_t*) w
) + 1, d
, l
);
380 int dns_packet_append_name(DnsPacket
*p
, const char *name
, size_t *start
) {
387 saved_size
= p
->size
;
390 _cleanup_free_
char *s
= NULL
;
391 char label
[DNS_LABEL_MAX
];
394 n
= PTR_TO_SIZE(hashmap_get(p
->names
, name
));
399 r
= dns_packet_append_uint16(p
, 0xC000 | n
, NULL
);
413 r
= dns_label_unescape(&name
, label
, sizeof(label
));
417 r
= dns_packet_append_label(p
, label
, r
, &n
);
421 r
= hashmap_ensure_allocated(&p
->names
, dns_name_hash_func
, dns_name_compare_func
);
425 r
= hashmap_put(p
->names
, s
, SIZE_TO_PTR(n
));
432 r
= dns_packet_append_uint8(p
, 0, NULL
);
443 dns_packet_truncate(p
, saved_size
);
447 int dns_packet_append_key(DnsPacket
*p
, const DnsResourceKey
*k
, size_t *start
) {
454 saved_size
= p
->size
;
456 r
= dns_packet_append_name(p
, DNS_RESOURCE_KEY_NAME(k
), NULL
);
460 r
= dns_packet_append_uint16(p
, k
->type
, NULL
);
464 r
= dns_packet_append_uint16(p
, k
->class, NULL
);
474 dns_packet_truncate(p
, saved_size
);
478 int dns_packet_append_rr(DnsPacket
*p
, const DnsResourceRecord
*rr
, size_t *start
) {
479 size_t saved_size
, rdlength_offset
, end
, rdlength
;
485 saved_size
= p
->size
;
487 r
= dns_packet_append_key(p
, rr
->key
, NULL
);
491 r
= dns_packet_append_uint32(p
, rr
->ttl
, NULL
);
495 /* Initially we write 0 here */
496 r
= dns_packet_append_uint16(p
, 0, &rdlength_offset
);
500 switch (rr
->unparseable
? _DNS_TYPE_INVALID
: rr
->key
->type
) {
503 r
= dns_packet_append_uint16(p
, rr
->srv
.priority
, NULL
);
507 r
= dns_packet_append_uint16(p
, rr
->srv
.weight
, NULL
);
511 r
= dns_packet_append_uint16(p
, rr
->srv
.port
, NULL
);
515 r
= dns_packet_append_name(p
, rr
->srv
.name
, NULL
);
522 r
= dns_packet_append_name(p
, rr
->ptr
.name
, NULL
);
526 r
= dns_packet_append_string(p
, rr
->hinfo
.cpu
, NULL
);
530 r
= dns_packet_append_string(p
, rr
->hinfo
.os
, NULL
);
533 case DNS_TYPE_SPF
: /* exactly the same as TXT */
537 STRV_FOREACH(s
, rr
->txt
.strings
) {
538 r
= dns_packet_append_string(p
, *s
, NULL
);
548 r
= dns_packet_append_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
552 r
= dns_packet_append_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
556 r
= dns_packet_append_name(p
, rr
->soa
.mname
, NULL
);
560 r
= dns_packet_append_name(p
, rr
->soa
.rname
, NULL
);
564 r
= dns_packet_append_uint32(p
, rr
->soa
.serial
, NULL
);
568 r
= dns_packet_append_uint32(p
, rr
->soa
.refresh
, NULL
);
572 r
= dns_packet_append_uint32(p
, rr
->soa
.retry
, NULL
);
576 r
= dns_packet_append_uint32(p
, rr
->soa
.expire
, NULL
);
580 r
= dns_packet_append_uint32(p
, rr
->soa
.minimum
, NULL
);
584 r
= dns_packet_append_uint16(p
, rr
->mx
.priority
, NULL
);
588 r
= dns_packet_append_name(p
, rr
->mx
.exchange
, NULL
);
592 r
= dns_packet_append_uint8(p
, rr
->loc
.version
, NULL
);
596 r
= dns_packet_append_uint8(p
, rr
->loc
.size
, NULL
);
600 r
= dns_packet_append_uint8(p
, rr
->loc
.horiz_pre
, NULL
);
604 r
= dns_packet_append_uint8(p
, rr
->loc
.vert_pre
, NULL
);
608 r
= dns_packet_append_uint16(p
, rr
->loc
.latitude
, NULL
);
612 r
= dns_packet_append_uint16(p
, rr
->loc
.longitude
, NULL
);
616 r
= dns_packet_append_uint16(p
, rr
->loc
.altitude
, NULL
);
620 r
= dns_packet_append_uint8(p
, rr
->sshfp
.algorithm
, NULL
);
623 r
= dns_packet_append_uint8(p
, rr
->sshfp
.fptype
, NULL
);
627 r
= dns_packet_append_blob(p
, rr
->sshfp
.key
, rr
->sshfp
.key_size
, NULL
);
630 case _DNS_TYPE_INVALID
: /* unparseable */
633 r
= dns_packet_append_blob(p
, rr
->generic
.data
, rr
->generic
.size
, NULL
);
639 /* Let's calculate the actual data size and update the field */
640 rdlength
= p
->size
- rdlength_offset
- sizeof(uint16_t);
641 if (rdlength
> 0xFFFF) {
647 p
->size
= rdlength_offset
;
648 r
= dns_packet_append_uint16(p
, rdlength
, NULL
);
659 dns_packet_truncate(p
, saved_size
);
664 int dns_packet_read(DnsPacket
*p
, size_t sz
, const void **ret
, size_t *start
) {
667 if (p
->rindex
+ sz
> p
->size
)
671 *ret
= (uint8_t*) DNS_PACKET_DATA(p
) + p
->rindex
;
680 void dns_packet_rewind(DnsPacket
*p
, size_t idx
) {
682 assert(idx
<= p
->size
);
683 assert(idx
>= DNS_PACKET_HEADER_SIZE
);
688 int dns_packet_read_blob(DnsPacket
*p
, void *d
, size_t sz
, size_t *start
) {
695 r
= dns_packet_read(p
, sz
, &q
, start
);
703 int dns_packet_read_uint8(DnsPacket
*p
, uint8_t *ret
, size_t *start
) {
709 r
= dns_packet_read(p
, sizeof(uint8_t), &d
, start
);
713 *ret
= ((uint8_t*) d
)[0];
717 int dns_packet_read_uint16(DnsPacket
*p
, uint16_t *ret
, size_t *start
) {
723 r
= dns_packet_read(p
, sizeof(uint16_t), &d
, start
);
727 *ret
= (((uint16_t) ((uint8_t*) d
)[0]) << 8) |
728 ((uint16_t) ((uint8_t*) d
)[1]);
732 int dns_packet_read_uint32(DnsPacket
*p
, uint32_t *ret
, size_t *start
) {
738 r
= dns_packet_read(p
, sizeof(uint32_t), &d
, start
);
742 *ret
= (((uint32_t) ((uint8_t*) d
)[0]) << 24) |
743 (((uint32_t) ((uint8_t*) d
)[1]) << 16) |
744 (((uint32_t) ((uint8_t*) d
)[2]) << 8) |
745 ((uint32_t) ((uint8_t*) d
)[3]);
750 int dns_packet_read_string(DnsPacket
*p
, char **ret
, size_t *start
) {
759 saved_rindex
= p
->rindex
;
761 r
= dns_packet_read_uint8(p
, &c
, NULL
);
765 r
= dns_packet_read(p
, c
, &d
, NULL
);
769 if (memchr(d
, 0, c
)) {
780 if (!utf8_is_valid(t
)) {
789 *start
= saved_rindex
;
794 dns_packet_rewind(p
, saved_rindex
);
798 int dns_packet_read_name(DnsPacket
*p
, char **_ret
, size_t *start
) {
799 size_t saved_rindex
, after_rindex
= 0;
800 _cleanup_free_
char *ret
= NULL
;
801 size_t n
= 0, allocated
= 0;
808 saved_rindex
= p
->rindex
;
813 r
= dns_packet_read_uint8(p
, &c
, NULL
);
821 _cleanup_free_
char *t
= NULL
;
825 r
= dns_packet_read(p
, c
, (const void**) &label
, NULL
);
829 r
= dns_label_escape(label
, c
, &t
);
833 if (!GREEDY_REALLOC(ret
, allocated
, n
+ !first
+ strlen(t
) + 1)) {
843 memcpy(ret
+ n
, t
, r
);
846 } else if ((c
& 0xc0) == 0xc0) {
850 r
= dns_packet_read_uint8(p
, &d
, NULL
);
854 ptr
= (uint16_t) (c
& ~0xc0) << 8 | (uint16_t) d
;
855 if (ptr
< DNS_PACKET_HEADER_SIZE
|| ptr
>= saved_rindex
) {
860 if (after_rindex
== 0)
861 after_rindex
= p
->rindex
;
868 if (!GREEDY_REALLOC(ret
, allocated
, n
+ 1)) {
875 if (after_rindex
!= 0)
876 p
->rindex
= after_rindex
;
882 *start
= saved_rindex
;
887 dns_packet_rewind(p
, saved_rindex
);
891 int dns_packet_read_key(DnsPacket
*p
, DnsResourceKey
**ret
, size_t *start
) {
892 _cleanup_free_
char *name
= NULL
;
893 uint16_t class, type
;
901 saved_rindex
= p
->rindex
;
903 r
= dns_packet_read_name(p
, &name
, NULL
);
907 r
= dns_packet_read_uint16(p
, &type
, NULL
);
911 r
= dns_packet_read_uint16(p
, &class, NULL
);
915 key
= dns_resource_key_new_consume(class, type
, name
);
925 *start
= saved_rindex
;
929 dns_packet_rewind(p
, saved_rindex
);
933 int dns_packet_read_rr(DnsPacket
*p
, DnsResourceRecord
**ret
, size_t *start
) {
934 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
935 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
936 size_t saved_rindex
, offset
;
944 saved_rindex
= p
->rindex
;
946 r
= dns_packet_read_key(p
, &key
, NULL
);
950 if (key
->class == DNS_CLASS_ANY
||
951 key
->type
== DNS_TYPE_ANY
) {
956 rr
= dns_resource_record_new(key
);
962 r
= dns_packet_read_uint32(p
, &rr
->ttl
, NULL
);
966 r
= dns_packet_read_uint16(p
, &rdlength
, NULL
);
970 if (p
->rindex
+ rdlength
> p
->size
) {
977 switch (rr
->key
->type
) {
980 r
= dns_packet_read_uint16(p
, &rr
->srv
.priority
, NULL
);
983 r
= dns_packet_read_uint16(p
, &rr
->srv
.weight
, NULL
);
986 r
= dns_packet_read_uint16(p
, &rr
->srv
.port
, NULL
);
989 r
= dns_packet_read_name(p
, &rr
->srv
.name
, NULL
);
996 r
= dns_packet_read_name(p
, &rr
->ptr
.name
, NULL
);
1000 r
= dns_packet_read_string(p
, &rr
->hinfo
.cpu
, NULL
);
1004 r
= dns_packet_read_string(p
, &rr
->hinfo
.os
, NULL
);
1007 case DNS_TYPE_SPF
: /* exactly the same as TXT */
1008 case DNS_TYPE_TXT
: {
1011 while (p
->rindex
< offset
+ rdlength
) {
1012 r
= dns_packet_read_string(p
, &s
, NULL
);
1016 r
= strv_consume(&rr
->txt
.strings
, s
);
1026 r
= dns_packet_read_blob(p
, &rr
->a
.in_addr
, sizeof(struct in_addr
), NULL
);
1030 r
= dns_packet_read_blob(p
, &rr
->aaaa
.in6_addr
, sizeof(struct in6_addr
), NULL
);
1034 r
= dns_packet_read_name(p
, &rr
->soa
.mname
, NULL
);
1038 r
= dns_packet_read_name(p
, &rr
->soa
.rname
, NULL
);
1042 r
= dns_packet_read_uint32(p
, &rr
->soa
.serial
, NULL
);
1046 r
= dns_packet_read_uint32(p
, &rr
->soa
.refresh
, NULL
);
1050 r
= dns_packet_read_uint32(p
, &rr
->soa
.retry
, NULL
);
1054 r
= dns_packet_read_uint32(p
, &rr
->soa
.expire
, NULL
);
1058 r
= dns_packet_read_uint32(p
, &rr
->soa
.minimum
, NULL
);
1062 r
= dns_packet_read_uint16(p
, &rr
->mx
.priority
, NULL
);
1066 r
= dns_packet_read_name(p
, &rr
->mx
.exchange
, NULL
);
1069 case DNS_TYPE_LOC
: {
1073 r
= dns_packet_read_uint8(p
, &t
, &pos
);
1078 rr
->loc
.version
= t
;
1080 r
= dns_packet_read_uint8(p
, &rr
->loc
.size
, NULL
);
1084 r
= dns_packet_read_uint8(p
, &rr
->loc
.horiz_pre
, NULL
);
1088 r
= dns_packet_read_uint8(p
, &rr
->loc
.vert_pre
, NULL
);
1092 r
= dns_packet_read_uint32(p
, &rr
->loc
.latitude
, NULL
);
1096 r
= dns_packet_read_uint32(p
, &rr
->loc
.longitude
, NULL
);
1100 r
= dns_packet_read_uint32(p
, &rr
->loc
.altitude
, NULL
);
1106 dns_packet_rewind(p
, pos
);
1107 rr
->unparseable
= true;
1112 case DNS_TYPE_SSHFP
:
1114 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.algorithm
, NULL
);
1118 r
= dns_packet_read_uint8(p
, &rr
->sshfp
.fptype
, NULL
);
1122 r
= dns_packet_read(p
, rdlength
- 2, &d
, NULL
);
1126 rr
->sshfp
.key
= memdup(d
, rdlength
- 2);
1127 if (!rr
->sshfp
.key
) {
1132 rr
->sshfp
.key_size
= rdlength
- 2;
1136 r
= dns_packet_read(p
, rdlength
, &d
, NULL
);
1140 rr
->generic
.data
= memdup(d
, rdlength
);
1141 if (!rr
->generic
.data
) {
1146 rr
->generic
.size
= rdlength
;
1151 if (p
->rindex
!= offset
+ rdlength
) {
1160 *start
= saved_rindex
;
1164 dns_packet_rewind(p
, saved_rindex
);
1168 int dns_packet_extract(DnsPacket
*p
) {
1169 _cleanup_(dns_question_unrefp
) DnsQuestion
*question
= NULL
;
1170 _cleanup_(dns_answer_unrefp
) DnsAnswer
*answer
= NULL
;
1171 size_t saved_rindex
;
1175 saved_rindex
= p
->rindex
;
1176 dns_packet_rewind(p
, DNS_PACKET_HEADER_SIZE
);
1178 n
= DNS_PACKET_QDCOUNT(p
);
1180 question
= dns_question_new(n
);
1186 for (i
= 0; i
< n
; i
++) {
1187 _cleanup_(dns_resource_key_unrefp
) DnsResourceKey
*key
= NULL
;
1189 r
= dns_packet_read_key(p
, &key
, NULL
);
1193 r
= dns_question_add(question
, key
);
1199 n
= DNS_PACKET_RRCOUNT(p
);
1201 answer
= dns_answer_new(n
);
1207 for (i
= 0; i
< n
; i
++) {
1208 _cleanup_(dns_resource_record_unrefp
) DnsResourceRecord
*rr
= NULL
;
1210 r
= dns_packet_read_rr(p
, &rr
, NULL
);
1214 r
= dns_answer_add(answer
, rr
);
1220 p
->question
= question
;
1229 p
->rindex
= saved_rindex
;
1233 static const char* const dns_rcode_table
[_DNS_RCODE_MAX_DEFINED
] = {
1234 [DNS_RCODE_SUCCESS
] = "SUCCESS",
1235 [DNS_RCODE_FORMERR
] = "FORMERR",
1236 [DNS_RCODE_SERVFAIL
] = "SERVFAIL",
1237 [DNS_RCODE_NXDOMAIN
] = "NXDOMAIN",
1238 [DNS_RCODE_NOTIMP
] = "NOTIMP",
1239 [DNS_RCODE_REFUSED
] = "REFUSED",
1240 [DNS_RCODE_YXDOMAIN
] = "YXDOMAIN",
1241 [DNS_RCODE_YXRRSET
] = "YRRSET",
1242 [DNS_RCODE_NXRRSET
] = "NXRRSET",
1243 [DNS_RCODE_NOTAUTH
] = "NOTAUTH",
1244 [DNS_RCODE_NOTZONE
] = "NOTZONE",
1245 [DNS_RCODE_BADVERS
] = "BADVERS",
1246 [DNS_RCODE_BADKEY
] = "BADKEY",
1247 [DNS_RCODE_BADTIME
] = "BADTIME",
1248 [DNS_RCODE_BADMODE
] = "BADMODE",
1249 [DNS_RCODE_BADNAME
] = "BADNAME",
1250 [DNS_RCODE_BADALG
] = "BADALG",
1251 [DNS_RCODE_BADTRUNC
] = "BADTRUNC",
1253 DEFINE_STRING_TABLE_LOOKUP(dns_rcode
, int);
1255 static const char* const dns_protocol_table
[_DNS_PROTOCOL_MAX
] = {
1256 [DNS_PROTOCOL_DNS
] = "dns",
1257 [DNS_PROTOCOL_MDNS
] = "mdns",
1258 [DNS_PROTOCOL_LLMNR
] = "llmnr",
1260 DEFINE_STRING_TABLE_LOOKUP(dns_protocol
, DnsProtocol
);