xref: /openbsd-src/usr.sbin/nsd/dns.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /*
2  * dns.c -- DNS definitions.
3  *
4  * Copyright (c) 2001-2011, NLnet Labs. All rights reserved.
5  *
6  * See LICENSE for the license.
7  *
8  */
9 
10 #include <config.h>
11 
12 #include <sys/types.h>
13 #include <sys/socket.h>
14 #include <netinet/in.h>
15 #include <arpa/inet.h>
16 #include <ctype.h>
17 #include <netdb.h>
18 #include <string.h>
19 #ifdef HAVE_STRINGS_H
20 #include <strings.h>
21 #endif
22 
23 #include "dns.h"
24 #include "zonec.h"
25 #include "zparser.h"
26 
27 /* Taken from RFC 1035, section 3.2.4.  */
28 static lookup_table_type dns_rrclasses[] = {
29 	{ CLASS_IN, "IN" },	/* the Internet */
30 	{ CLASS_CS, "CS" },	/* the CSNET class (Obsolete) */
31 	{ CLASS_CH, "CH" },	/* the CHAOS class */
32 	{ CLASS_HS, "HS" },	/* Hesiod */
33 	{ 0, NULL }
34 };
35 
36 static rrtype_descriptor_type rrtype_descriptors[(RRTYPE_DESCRIPTORS_LENGTH+1)] = {
37 	/* 0 */
38 	{ 0, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
39 	/* 1 */
40 	{ TYPE_A, "A", T_A, 1, 1,
41 	  { RDATA_WF_A }, { RDATA_ZF_A } },
42 	/* 2 */
43 	{ TYPE_NS, "NS", T_NS, 1, 1,
44 	  { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
45 	/* 3 */
46 	{ TYPE_MD, "MD", T_MD, 1, 1,
47 	  { RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
48 	/* 4 */
49 	{ TYPE_MF, "MF", T_MF, 1, 1,
50 	  { RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
51 	/* 5 */
52 	{ TYPE_CNAME, "CNAME", T_CNAME, 1, 1,
53 	  { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
54 	/* 6 */
55 	{ TYPE_SOA, "SOA", T_SOA, 7, 7,
56 	  { RDATA_WF_COMPRESSED_DNAME, RDATA_WF_COMPRESSED_DNAME, RDATA_WF_LONG,
57 	    RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_LONG },
58 	  { RDATA_ZF_DNAME, RDATA_ZF_DNAME, RDATA_ZF_PERIOD, RDATA_ZF_PERIOD,
59 	    RDATA_ZF_PERIOD, RDATA_ZF_PERIOD, RDATA_ZF_PERIOD } },
60 	/* 7 */
61 	{ TYPE_MB, "MB", T_MB, 1, 1,
62 	  { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
63 	/* 8 */
64 	{ TYPE_MG, "MG", T_MG, 1, 1,
65 	  { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
66 	/* 9 */
67 	{ TYPE_MR, "MR", T_MR, 1, 1,
68 	  { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
69 	/* 10 */
70 	{ TYPE_NULL, "NULL", T_UTYPE, 1, 1,
71 	  { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
72 	/* 11 */
73 	{ TYPE_WKS, "WKS", T_WKS, 2, 2,
74 	  { RDATA_WF_A, RDATA_WF_BINARY },
75 	  { RDATA_ZF_A, RDATA_ZF_SERVICES } },
76 	/* 12 */
77 	{ TYPE_PTR, "PTR", T_PTR, 1, 1,
78 	  { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
79 	/* 13 */
80 	{ TYPE_HINFO, "HINFO", T_HINFO, 2, 2,
81 	  { RDATA_WF_TEXT, RDATA_WF_TEXT }, { RDATA_ZF_TEXT, RDATA_ZF_TEXT } },
82 	/* 14 */
83 	{ TYPE_MINFO, "MINFO", T_MINFO, 2, 2,
84 	  { RDATA_WF_COMPRESSED_DNAME, RDATA_WF_COMPRESSED_DNAME },
85 	  { RDATA_ZF_DNAME, RDATA_ZF_DNAME } },
86 	/* 15 */
87 	{ TYPE_MX, "MX", T_MX, 2, 2,
88 	  { RDATA_WF_SHORT, RDATA_WF_COMPRESSED_DNAME },
89 	  { RDATA_ZF_SHORT, RDATA_ZF_DNAME } },
90 	/* 16 */
91 	{ TYPE_TXT, "TXT", T_TXT, 1, 1,
92 	  { RDATA_WF_TEXTS },
93 	  { RDATA_ZF_TEXTS } },
94 	/* 17 */
95 	{ TYPE_RP, "RP", T_RP, 2, 2,
96 	  { RDATA_WF_COMPRESSED_DNAME, RDATA_WF_COMPRESSED_DNAME },
97 	  { RDATA_ZF_DNAME, RDATA_ZF_DNAME } },
98 	/* 18 */
99 	{ TYPE_AFSDB, "AFSDB", T_AFSDB, 2, 2,
100 	  { RDATA_WF_SHORT, RDATA_WF_COMPRESSED_DNAME },
101 	  { RDATA_ZF_SHORT, RDATA_ZF_DNAME } },
102 	/* 19 */
103 	{ TYPE_X25, "X25", T_X25, 1, 1,
104 	  { RDATA_WF_TEXT },
105 	  { RDATA_ZF_TEXT } },
106 	/* 20 */
107 	{ TYPE_ISDN, "ISDN", T_ISDN, 1, 2,
108 	  { RDATA_WF_TEXT, RDATA_WF_TEXT },
109 	  { RDATA_ZF_TEXT, RDATA_ZF_TEXT } },
110 	/* 21 */
111 	{ TYPE_RT, "RT", T_RT, 2, 2,
112 	  { RDATA_WF_SHORT, RDATA_WF_COMPRESSED_DNAME },
113 	  { RDATA_ZF_SHORT, RDATA_ZF_DNAME } },
114 	/* 22 */
115 	{ TYPE_NSAP, "NSAP", T_NSAP, 1, 1,
116 	  { RDATA_WF_BINARY },
117 	  { RDATA_ZF_NSAP } },
118 	/* 23 */
119 	{ 23, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
120 	/* 24 */
121 	{ TYPE_SIG, "SIG", T_SIG, 9, 9,
122 	  { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_LONG,
123 	    RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_SHORT,
124 	    RDATA_WF_UNCOMPRESSED_DNAME, RDATA_WF_BINARY },
125 	  { RDATA_ZF_RRTYPE, RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_PERIOD,
126 	    RDATA_ZF_TIME, RDATA_ZF_TIME, RDATA_ZF_SHORT, RDATA_ZF_DNAME,
127 	    RDATA_ZF_BASE64 } },
128 	/* 25 */
129 	{ TYPE_KEY, "KEY", T_KEY, 4, 4,
130 	  { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
131 	  { RDATA_ZF_SHORT, RDATA_ZF_BYTE, RDATA_ZF_ALGORITHM,
132 	    RDATA_ZF_BASE64 } },
133 	/* 26 */
134 	{ TYPE_PX, "PX", T_PX, 3, 3,
135 	  { RDATA_WF_SHORT, RDATA_WF_UNCOMPRESSED_DNAME,
136 	    RDATA_WF_UNCOMPRESSED_DNAME },
137 	  { RDATA_ZF_SHORT, RDATA_ZF_DNAME, RDATA_ZF_DNAME } },
138 	/* 27 */
139 	{ 27, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
140 	/* 28 */
141 	{ TYPE_AAAA, "AAAA", T_AAAA, 1, 1,
142 	  { RDATA_WF_AAAA },
143 	  { RDATA_ZF_AAAA } },
144 	/* 29 */
145 	{ TYPE_LOC, "LOC", T_LOC, 1, 1,
146 	  { RDATA_WF_BINARY },
147 	  { RDATA_ZF_LOC } },
148 	/* 30 */
149 	{ TYPE_NXT, "NXT", T_NXT, 2, 2,
150 	  { RDATA_WF_UNCOMPRESSED_DNAME, RDATA_WF_BINARY },
151 	  { RDATA_ZF_DNAME, RDATA_ZF_NXT } },
152 	/* 31 */
153 	{ 31, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
154 	/* 32 */
155 	{ 32, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
156 	/* 33 */
157 	{ TYPE_SRV, "SRV", T_SRV, 4, 4,
158 	  { RDATA_WF_SHORT, RDATA_WF_SHORT, RDATA_WF_SHORT,
159 	    RDATA_WF_UNCOMPRESSED_DNAME },
160 	  { RDATA_ZF_SHORT, RDATA_ZF_SHORT, RDATA_ZF_SHORT, RDATA_ZF_DNAME } },
161 	/* 34 */
162 	{ 34, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
163 	/* 35 */
164 	{ TYPE_NAPTR, "NAPTR", T_NAPTR, 6, 6,
165 	  { RDATA_WF_SHORT, RDATA_WF_SHORT, RDATA_WF_TEXT, RDATA_WF_TEXT,
166 	    RDATA_WF_TEXT, RDATA_WF_UNCOMPRESSED_DNAME },
167 	  { RDATA_ZF_SHORT, RDATA_ZF_SHORT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
168 	    RDATA_ZF_TEXT, RDATA_ZF_DNAME } },
169 	/* 36 */
170 	{ TYPE_KX, "KX", T_KX, 2, 2,
171 	  { RDATA_WF_SHORT, RDATA_WF_UNCOMPRESSED_DNAME },
172 	  { RDATA_ZF_SHORT, RDATA_ZF_DNAME } },
173 	/* 37 */
174 	{ TYPE_CERT, "CERT", T_CERT, 4, 4,
175 	  { RDATA_WF_SHORT, RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BINARY },
176 	  { RDATA_ZF_CERTIFICATE_TYPE, RDATA_ZF_SHORT, RDATA_ZF_ALGORITHM,
177 	    RDATA_ZF_BASE64 } },
178 	/* 38 */
179 	{ TYPE_A6, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
180 	/* 39 */
181 	{ TYPE_DNAME, "DNAME", T_DNAME, 1, 1,
182 	  { RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_DNAME } },
183 	/* 40 */
184 	{ 40, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
185 	/* 41 */
186 	{ TYPE_OPT, "OPT", T_UTYPE, 1, 1,
187 	  { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
188 	/* 42 */
189 	{ TYPE_APL, "APL", T_APL, 0, MAXRDATALEN,
190 	  { RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
191 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
192 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
193 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
194 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
195 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
196 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
197 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
198 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
199 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
200 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
201 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
202 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
203 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
204 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL,
205 	    RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL },
206 	  { RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
207 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
208 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
209 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
210 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
211 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
212 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
213 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
214 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
215 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
216 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
217 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
218 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
219 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
220 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL,
221 	    RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL } },
222 	/* 43 */
223 	{ TYPE_DS, "DS", T_DS, 4, 4,
224 	  { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
225 	  { RDATA_ZF_SHORT, RDATA_ZF_ALGORITHM, RDATA_ZF_BYTE, RDATA_ZF_HEX } },
226 	/* 44 */
227 	{ TYPE_SSHFP, "SSHFP", T_SSHFP, 3, 3,
228 	  { RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
229 	  { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_HEX } },
230 	/* 45 */
231 	{ TYPE_IPSECKEY, "IPSECKEY", T_IPSECKEY, 4, 5,
232 	  { RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_IPSECGATEWAY,
233 	    RDATA_WF_BINARY },
234 	  { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_IPSECGATEWAY,
235 	    RDATA_ZF_BASE64 } },
236 	/* 46 */
237 	{ TYPE_RRSIG, "RRSIG", T_RRSIG, 9, 9,
238 	  { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_LONG,
239 	    RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_SHORT,
240 	    RDATA_WF_LITERAL_DNAME, RDATA_WF_BINARY },
241 	  { RDATA_ZF_RRTYPE, RDATA_ZF_ALGORITHM, RDATA_ZF_BYTE, RDATA_ZF_PERIOD,
242 	    RDATA_ZF_TIME, RDATA_ZF_TIME, RDATA_ZF_SHORT,
243 		RDATA_ZF_LITERAL_DNAME, RDATA_ZF_BASE64 } },
244 	/* 47 */
245 	{ TYPE_NSEC, "NSEC", T_NSEC, 2, 2,
246 	  { RDATA_WF_LITERAL_DNAME, RDATA_WF_BINARY },
247 	  { RDATA_ZF_LITERAL_DNAME, RDATA_ZF_NSEC } },
248 	/* 48 */
249 	{ TYPE_DNSKEY, "DNSKEY", T_DNSKEY, 4, 4,
250 	  { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
251 	  { RDATA_ZF_SHORT, RDATA_ZF_BYTE, RDATA_ZF_ALGORITHM,
252 	    RDATA_ZF_BASE64 } },
253 	/* 49 */
254 	{ TYPE_DHCID, "DHCID", T_DHCID, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_BASE64 } },
255 	/* 50 */
256 	{ TYPE_NSEC3, "NSEC3", T_NSEC3, 6, 6,
257 	  { RDATA_WF_BYTE, /* hash type */
258 	    RDATA_WF_BYTE, /* flags */
259 	    RDATA_WF_SHORT, /* iterations */
260 	    RDATA_WF_BINARYWITHLENGTH, /* salt */
261 	    RDATA_WF_BINARYWITHLENGTH, /* next hashed name */
262 	    RDATA_WF_BINARY /* type bitmap */ },
263 	  { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_SHORT, RDATA_ZF_HEX_LEN,
264 	    RDATA_ZF_BASE32, RDATA_ZF_NSEC } },
265 	/* 51 */
266 	{ TYPE_NSEC3PARAM, "NSEC3PARAM", T_NSEC3PARAM, 4, 4,
267 	  { RDATA_WF_BYTE, /* hash type */
268 	    RDATA_WF_BYTE, /* flags */
269 	    RDATA_WF_SHORT, /* iterations */
270 	    RDATA_WF_BINARYWITHLENGTH /* salt */ },
271 	  { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_SHORT, RDATA_ZF_HEX_LEN } },
272 	/* 52 */
273 	{ 52, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
274 	/* 53 */
275 	{ 53, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
276 	/* 54 */
277 	{ 54, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
278 	/* 55 */
279 	{ 55, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
280 	/* 56 */
281 	{ 56, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
282 	/* 57 */
283 	{ 57, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
284 	/* 58 */
285 	{ 58, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
286 	/* 59 */
287 	{ 59, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
288 	/* 60 */
289 	{ 60, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
290 	/* 61 */
291 	{ 61, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
292 	/* 62 */
293 	{ 62, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
294 	/* 63 */
295 	{ 63, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
296 	/* 64 */
297 	{ 64, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
298 	/* 65 */
299 	{ 65, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
300 	/* 66 */
301 	{ 66, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
302 	/* 67 */
303 	{ 67, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
304 	/* 68 */
305 	{ 68, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
306 	/* 69 */
307 	{ 69, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
308 	/* 70 */
309 	{ 70, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
310 	/* 71 */
311 	{ 71, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
312 	/* 72 */
313 	{ 72, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
314 	/* 73 */
315 	{ 73, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
316 	/* 74 */
317 	{ 74, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
318 	/* 75 */
319 	{ 75, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
320 	/* 76 */
321 	{ 76, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
322 	/* 77 */
323 	{ 77, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
324 	/* 78 */
325 	{ 78, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
326 	/* 79 */
327 	{ 79, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
328 	/* 80 */
329 	{ 80, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
330 	/* 81 */
331 	{ 81, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
332 	/* 82 */
333 	{ 82, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
334 	/* 83 */
335 	{ 83, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
336 	/* 84 */
337 	{ 84, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
338 	/* 85 */
339 	{ 85, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
340 	/* 86 */
341 	{ 86, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
342 	/* 87 */
343 	{ 87, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
344 	/* 88 */
345 	{ 88, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
346 	/* 89 */
347 	{ 89, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
348 	/* 90 */
349 	{ 90, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
350 	/* 91 */
351 	{ 91, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
352 	/* 92 */
353 	{ 92, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
354 	/* 93 */
355 	{ 93, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
356 	/* 94 */
357 	{ 94, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
358 	/* 95 */
359 	{ 95, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
360 	/* 96 */
361 	{ 96, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
362 	/* 97 */
363 	{ 97, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
364 	/* 98 */
365 	{ 98, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } },
366 	/* 99 */
367 	{ TYPE_SPF, "SPF", T_SPF, 1, MAXRDATALEN,
368 	  { RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
369 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
370 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
371 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
372 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
373 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
374 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
375 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
376 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
377 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
378 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
379 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
380 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
381 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
382 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT,
383 	    RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT },
384 	  { RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
385 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
386 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
387 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
388 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
389 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
390 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
391 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
392 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
393 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
394 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
395 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
396 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
397 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
398 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT,
399 	    RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT } },
400 	/* 32769 */
401 	{ TYPE_DLV, "DLV", T_DLV, 4, 4,
402 	  { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY },
403 	  { RDATA_ZF_SHORT, RDATA_ZF_ALGORITHM, RDATA_ZF_BYTE, RDATA_ZF_HEX } },
404 };
405 
406 rrtype_descriptor_type *
407 rrtype_descriptor_by_type(uint16_t type)
408 {
409 	if (type < RRTYPE_DESCRIPTORS_LENGTH)
410 		return &rrtype_descriptors[type];
411 	else if (type == TYPE_DLV)
412 		return &rrtype_descriptors[PSEUDO_TYPE_DLV];
413 	return &rrtype_descriptors[0];
414 }
415 
416 rrtype_descriptor_type *
417 rrtype_descriptor_by_name(const char *name)
418 {
419 	int i;
420 
421 	for (i = 0; i < RRTYPE_DESCRIPTORS_LENGTH; ++i) {
422 		if (rrtype_descriptors[i].name
423 		    && strcasecmp(rrtype_descriptors[i].name, name) == 0)
424 		{
425 			return &rrtype_descriptors[i];
426 		}
427 	}
428 
429 	if (rrtype_descriptors[PSEUDO_TYPE_DLV].name
430 	    && strcasecmp(rrtype_descriptors[PSEUDO_TYPE_DLV].name, name) == 0)
431 	{
432 		return &rrtype_descriptors[PSEUDO_TYPE_DLV];
433 	}
434 
435 	return NULL;
436 }
437 
438 const char *
439 rrtype_to_string(uint16_t rrtype)
440 {
441 	static char buf[20];
442 	rrtype_descriptor_type *descriptor = rrtype_descriptor_by_type(rrtype);
443 	if (descriptor->name) {
444 		return descriptor->name;
445 	} else {
446 		snprintf(buf, sizeof(buf), "TYPE%d", (int) rrtype);
447 		return buf;
448 	}
449 }
450 
451 /*
452  * Lookup the type in the ztypes lookup table.  If not found, check if
453  * the type uses the "TYPExxx" notation for unknown types.
454  *
455  * Return 0 if no type matches.
456  */
457 uint16_t
458 rrtype_from_string(const char *name)
459 {
460         char *end;
461         long rrtype;
462 	rrtype_descriptor_type *entry;
463 
464 	entry = rrtype_descriptor_by_name(name);
465 	if (entry) {
466 		return entry->type;
467 	}
468 
469 	if (strlen(name) < 5)
470 		return 0;
471 
472 	if (strncasecmp(name, "TYPE", 4) != 0)
473 		return 0;
474 
475 	if (!isdigit((int)name[4]))
476 		return 0;
477 
478 	/* The rest from the string must be a number.  */
479 	rrtype = strtol(name + 4, &end, 10);
480 	if (*end != '\0')
481 		return 0;
482 	if (rrtype < 0 || rrtype > 65535L)
483 		return 0;
484 
485         return (uint16_t) rrtype;
486 }
487 
488 const char *
489 rrclass_to_string(uint16_t rrclass)
490 {
491 	static char buf[20];
492 	lookup_table_type *entry = lookup_by_id(dns_rrclasses, rrclass);
493 	if (entry) {
494 		assert(strlen(entry->name) < sizeof(buf));
495 		strlcpy(buf, entry->name, sizeof(buf));
496 	} else {
497 		snprintf(buf, sizeof(buf), "CLASS%d", (int) rrclass);
498 	}
499 	return buf;
500 }
501 
502 uint16_t
503 rrclass_from_string(const char *name)
504 {
505         char *end;
506         long rrclass;
507 	lookup_table_type *entry;
508 
509 	entry = lookup_by_name(dns_rrclasses, name);
510 	if (entry) {
511 		return (uint16_t) entry->id;
512 	}
513 
514 	if (strlen(name) < 6)
515 		return 0;
516 
517 	if (strncasecmp(name, "CLASS", 5) != 0)
518 		return 0;
519 
520 	if (!isdigit((int)name[5]))
521 		return 0;
522 
523 	/* The rest from the string must be a number.  */
524 	rrclass = strtol(name + 5, &end, 10);
525 	if (*end != '\0')
526 		return 0;
527 	if (rrclass < 0 || rrclass > 65535L)
528 		return 0;
529 
530 	return (uint16_t) rrclass;
531 }
532