xref: /openbsd/usr.bin/dig/lib/dns/rdata.c (revision 905646f0)
1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /* $Id: rdata.c,v 1.32 2020/09/14 08:40:43 florian Exp $ */
18 
19 /*! \file */
20 
21 #include <arpa/inet.h>
22 
23 #include <ctype.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include <isc/base64.h>
28 #include <isc/hex.h>
29 #include <isc/util.h>
30 #include <isc/buffer.h>
31 
32 #include <dns/cert.h>
33 #include <dns/compress.h>
34 #include <dns/keyvalues.h>
35 #include <dns/rcode.h>
36 #include <dns/rdata.h>
37 #include <dns/rdatatype.h>
38 #include <dns/result.h>
39 #include <dns/time.h>
40 #include <dns/ttl.h>
41 
42 #define RETERR(x) \
43 	do { \
44 		isc_result_t _r = (x); \
45 		if (_r != ISC_R_SUCCESS) \
46 			return (_r); \
47 	} while (0)
48 
49 #define ARGS_TOTEXT	dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, \
50 			isc_buffer_t *target
51 
52 #define ARGS_FROMWIRE	int rdclass, dns_rdatatype_t type, \
53 			isc_buffer_t *source, dns_decompress_t *dctx, \
54 			unsigned int options, isc_buffer_t *target
55 
56 #define ARGS_TOWIRE	dns_rdata_t *rdata, dns_compress_t *cctx, \
57 			isc_buffer_t *target
58 
59 #define ARGS_FROMSTRUCT	int rdclass, dns_rdatatype_t type, \
60 			void *source, isc_buffer_t *target
61 
62 #define ARGS_TOSTRUCT	const dns_rdata_t *rdata, void *target
63 
64 #define ARGS_FREESTRUCT void *source
65 
66 #define ARGS_CHECKOWNER dns_name_t *name, dns_rdataclass_t rdclass, \
67 			dns_rdatatype_t type, int wildcard
68 
69 /*%
70  * Context structure for the totext_ functions.
71  * Contains formatting options for rdata-to-text
72  * conversion.
73  */
74 typedef struct dns_rdata_textctx {
75 	dns_name_t *origin;	/*%< Current origin, or NULL. */
76 	unsigned int flags;	/*%< DNS_STYLEFLAG_*  */
77 	unsigned int width;	/*%< Width of rdata column. */
78 	const char *linebreak;	/*%< Line break string. */
79 } dns_rdata_textctx_t;
80 
81 typedef struct dns_rdata_type_lookup {
82 	const char	*type;
83 	int		 val;
84 } dns_rdata_type_lookup_t;
85 
86 static isc_result_t
87 txt_totext(isc_region_t *source, int quote, isc_buffer_t *target);
88 
89 static isc_result_t
90 txt_fromwire(isc_buffer_t *source, isc_buffer_t *target);
91 
92 static isc_result_t
93 multitxt_totext(isc_region_t *source, isc_buffer_t *target);
94 
95 static int
96 name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target);
97 
98 static unsigned int
99 name_length(dns_name_t *name);
100 
101 static isc_result_t
102 inet_totext(int af, isc_region_t *src, isc_buffer_t *target);
103 
104 static int
105 buffer_empty(isc_buffer_t *source);
106 
107 static isc_result_t
108 uint32_tobuffer(uint32_t, isc_buffer_t *target);
109 
110 static isc_result_t
111 uint16_tobuffer(uint32_t, isc_buffer_t *target);
112 
113 static isc_result_t
114 name_tobuffer(dns_name_t *name, isc_buffer_t *target);
115 
116 static uint32_t
117 uint32_fromregion(isc_region_t *region);
118 
119 static uint16_t
120 uint16_fromregion(isc_region_t *region);
121 
122 static uint8_t
123 uint8_fromregion(isc_region_t *region);
124 
125 static uint8_t
126 uint8_consume_fromregion(isc_region_t *region);
127 
128 static isc_result_t
129 btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target);
130 
131 static isc_result_t
132 rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
133 	     isc_buffer_t *target);
134 
135 static isc_result_t
136 unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
137 	       isc_buffer_t *target);
138 
139 static inline isc_result_t
140 generic_totext_key(ARGS_TOTEXT);
141 
142 static inline isc_result_t
143 generic_fromwire_key(ARGS_FROMWIRE);
144 
145 static isc_result_t
146 generic_totext_txt(ARGS_TOTEXT);
147 
148 static isc_result_t
149 generic_fromwire_txt(ARGS_FROMWIRE);
150 
151 static isc_result_t
152 generic_totext_ds(ARGS_TOTEXT);
153 
154 static isc_result_t
155 generic_fromwire_ds(ARGS_FROMWIRE);
156 
157 static isc_result_t
158 generic_totext_tlsa(ARGS_TOTEXT);
159 
160 static isc_result_t
161 generic_fromwire_tlsa(ARGS_FROMWIRE);
162 
163 static inline isc_result_t
164 name_duporclone(dns_name_t *source, dns_name_t *target) {
165 
166 	return (dns_name_dup(source, target));
167 }
168 
169 static inline void *
170 mem_maybedup(void *source, size_t length) {
171 	void *copy;
172 
173 	copy = malloc(length);
174 	if (copy != NULL)
175 		memmove(copy, source, length);
176 
177 	return (copy);
178 }
179 
180 static inline isc_result_t
181 typemap_totext(isc_region_t *sr, dns_rdata_textctx_t *tctx,
182 	       isc_buffer_t *target)
183 {
184 	unsigned int i, j, k;
185 	unsigned int window, len;
186 	int first = 1;
187 
188 	for (i = 0; i < sr->length; i += len) {
189 		if (tctx != NULL &&
190 		    (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
191 			RETERR(isc_str_tobuffer(tctx->linebreak, target));
192 			first = 1;
193 		}
194 		INSIST(i + 2 <= sr->length);
195 		window = sr->base[i];
196 		len = sr->base[i + 1];
197 		INSIST(len > 0 && len <= 32);
198 		i += 2;
199 		INSIST(i + len <= sr->length);
200 		for (j = 0; j < len; j++) {
201 			dns_rdatatype_t t;
202 			if (sr->base[i + j] == 0)
203 				continue;
204 			for (k = 0; k < 8; k++) {
205 				if ((sr->base[i + j] & (0x80 >> k)) == 0)
206 					continue;
207 				t = window * 256 + j * 8 + k;
208 				if (!first)
209 					RETERR(isc_str_tobuffer(" ", target));
210 				first = 0;
211 				RETERR(dns_rdatatype_totext(t, target));
212 			}
213 		}
214 	}
215 	return (ISC_R_SUCCESS);
216 }
217 
218 static isc_result_t
219 typemap_test(isc_region_t *sr, int allow_empty) {
220 	unsigned int window, lastwindow = 0;
221 	unsigned int len;
222 	int first = 1;
223 	unsigned int i;
224 
225 	for (i = 0; i < sr->length; i += len) {
226 		/*
227 		 * Check for overflow.
228 		 */
229 		if (i + 2 > sr->length)
230 			return (DNS_R_FORMERR);
231 		window = sr->base[i];
232 		len = sr->base[i + 1];
233 		i += 2;
234 		/*
235 		 * Check that bitmap windows are in the correct order.
236 		 */
237 		if (!first && window <= lastwindow)
238 			return (DNS_R_FORMERR);
239 		/*
240 		 * Check for legal lengths.
241 		 */
242 		if (len < 1 || len > 32)
243 			return (DNS_R_FORMERR);
244 		/*
245 		 * Check for overflow.
246 		 */
247 		if (i + len > sr->length)
248 			return (DNS_R_FORMERR);
249 		/*
250 		 * The last octet of the bitmap must be non zero.
251 		 */
252 		if (sr->base[i + len - 1] == 0)
253 			return (DNS_R_FORMERR);
254 		lastwindow = window;
255 		first = 0;
256 	}
257 	if (i != sr->length)
258 		return (DNS_R_EXTRADATA);
259 	if (!allow_empty && first)
260 		return (DNS_R_FORMERR);
261 	return (ISC_R_SUCCESS);
262 }
263 
264 static const char decdigits[] = "0123456789";
265 
266 #include "code.h"
267 
268 /***
269  *** Initialization
270  ***/
271 
272 void
273 dns_rdata_init(dns_rdata_t *rdata) {
274 
275 	REQUIRE(rdata != NULL);
276 
277 	rdata->data = NULL;
278 	rdata->length = 0;
279 	rdata->rdclass = 0;
280 	rdata->type = 0;
281 	rdata->flags = 0;
282 	ISC_LINK_INIT(rdata, link);
283 	/* ISC_LIST_INIT(rdata->list); */
284 }
285 
286 void
287 dns_rdata_reset(dns_rdata_t *rdata) {
288 
289 	REQUIRE(rdata != NULL);
290 
291 	REQUIRE(!ISC_LINK_LINKED(rdata, link));
292 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
293 
294 	rdata->data = NULL;
295 	rdata->length = 0;
296 	rdata->rdclass = 0;
297 	rdata->type = 0;
298 	rdata->flags = 0;
299 }
300 
301 /***
302  ***
303  ***/
304 
305 void
306 dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target) {
307 
308 	REQUIRE(src != NULL);
309 	REQUIRE(target != NULL);
310 
311 	REQUIRE(DNS_RDATA_INITIALIZED(target));
312 
313 	REQUIRE(DNS_RDATA_VALIDFLAGS(src));
314 	REQUIRE(DNS_RDATA_VALIDFLAGS(target));
315 
316 	target->data = src->data;
317 	target->length = src->length;
318 	target->rdclass = src->rdclass;
319 	target->type = src->type;
320 	target->flags = src->flags;
321 }
322 
323 /***
324  *** Conversions
325  ***/
326 
327 void
328 dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
329 		     dns_rdatatype_t type, isc_region_t *r)
330 {
331 
332 	REQUIRE(rdata != NULL);
333 	REQUIRE(DNS_RDATA_INITIALIZED(rdata));
334 	REQUIRE(r != NULL);
335 
336 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
337 
338 	rdata->data = r->base;
339 	rdata->length = r->length;
340 	rdata->rdclass = rdclass;
341 	rdata->type = type;
342 	rdata->flags = 0;
343 }
344 
345 void
346 dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r) {
347 
348 	REQUIRE(rdata != NULL);
349 	REQUIRE(r != NULL);
350 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
351 
352 	r->base = rdata->data;
353 	r->length = rdata->length;
354 }
355 
356 isc_result_t
357 dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
358 		   dns_rdatatype_t type, isc_buffer_t *source,
359 		   dns_decompress_t *dctx, unsigned int options,
360 		   isc_buffer_t *target)
361 {
362 	isc_result_t result = ISC_R_NOTIMPLEMENTED;
363 	isc_region_t region;
364 	isc_buffer_t ss;
365 	isc_buffer_t st;
366 	int use_default = 0;
367 	uint32_t activelength;
368 	unsigned int length;
369 
370 	REQUIRE(dctx != NULL);
371 	if (rdata != NULL) {
372 		REQUIRE(DNS_RDATA_INITIALIZED(rdata));
373 		REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
374 	}
375 	REQUIRE(source != NULL);
376 	REQUIRE(target != NULL);
377 
378 	if (type == 0)
379 		return (DNS_R_FORMERR);
380 
381 	ss = *source;
382 	st = *target;
383 
384 	activelength = isc_buffer_activelength(source);
385 	INSIST(activelength < 65536);
386 
387 	FROMWIRESWITCH
388 
389 	if (use_default) {
390 		if (activelength > isc_buffer_availablelength(target))
391 			result = ISC_R_NOSPACE;
392 		else {
393 			isc_buffer_putmem(target, isc_buffer_current(source),
394 					  activelength);
395 			isc_buffer_forward(source, activelength);
396 			result = ISC_R_SUCCESS;
397 		}
398 	}
399 
400 	/*
401 	 * Reject any rdata that expands out to more than DNS_RDATA_MAXLENGTH
402 	 * as we cannot transmit it.
403 	 */
404 	length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st);
405 	if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH)
406 		result = DNS_R_FORMERR;
407 
408 	/*
409 	 * We should have consumed all of our buffer.
410 	 */
411 	if (result == ISC_R_SUCCESS && !buffer_empty(source))
412 		result = DNS_R_EXTRADATA;
413 
414 	if (rdata != NULL && result == ISC_R_SUCCESS) {
415 		region.base = isc_buffer_used(&st);
416 		region.length = length;
417 		dns_rdata_fromregion(rdata, rdclass, type, &region);
418 	}
419 
420 	if (result != ISC_R_SUCCESS) {
421 		*source = ss;
422 		*target = st;
423 	}
424 	return (result);
425 }
426 
427 isc_result_t
428 dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
429 		 isc_buffer_t *target)
430 {
431 	isc_result_t result = ISC_R_NOTIMPLEMENTED;
432 	int use_default = 0;
433 	isc_region_t tr;
434 	isc_buffer_t st;
435 
436 	REQUIRE(rdata != NULL);
437 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
438 
439 	/*
440 	 * Some DynDNS meta-RRs have empty rdata.
441 	 */
442 	if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
443 		INSIST(rdata->length == 0);
444 		return (ISC_R_SUCCESS);
445 	}
446 
447 	st = *target;
448 
449 	TOWIRESWITCH
450 
451 	if (use_default) {
452 		isc_buffer_availableregion(target, &tr);
453 		if (tr.length < rdata->length)
454 			return (ISC_R_NOSPACE);
455 		memmove(tr.base, rdata->data, rdata->length);
456 		isc_buffer_add(target, rdata->length);
457 		return (ISC_R_SUCCESS);
458 	}
459 	if (result != ISC_R_SUCCESS) {
460 		*target = st;
461 		INSIST(target->used < 65536);
462 		dns_compress_rollback(cctx, (uint16_t)target->used);
463 	}
464 	return (result);
465 }
466 
467 static isc_result_t
468 unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
469 	       isc_buffer_t *target)
470 {
471 	isc_result_t result;
472 	char buf[sizeof("65535")];
473 	isc_region_t sr;
474 
475 	strlcpy(buf, "\\# ", sizeof(buf));
476 	result = isc_str_tobuffer(buf, target);
477 	if (result != ISC_R_SUCCESS)
478 		return (result);
479 
480 	dns_rdata_toregion(rdata, &sr);
481 	INSIST(sr.length < 65536);
482 	snprintf(buf, sizeof(buf), "%u", sr.length);
483 	result = isc_str_tobuffer(buf, target);
484 	if (result != ISC_R_SUCCESS)
485 		return (result);
486 
487 	if (sr.length != 0U) {
488 		if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
489 			result = isc_str_tobuffer(" ( ", target);
490 		else
491 			result = isc_str_tobuffer(" ", target);
492 
493 		if (result != ISC_R_SUCCESS)
494 			return (result);
495 
496 		if (tctx->width == 0) /* No splitting */
497 			result = isc_hex_totext(&sr, 0, "", target);
498 		else
499 			result = isc_hex_totext(&sr, tctx->width - 2,
500 						tctx->linebreak,
501 						target);
502 		if (result == ISC_R_SUCCESS &&
503 		    (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
504 			result = isc_str_tobuffer(" )", target);
505 	}
506 	return (result);
507 }
508 
509 static isc_result_t
510 rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
511 	     isc_buffer_t *target)
512 {
513 	isc_result_t result = ISC_R_NOTIMPLEMENTED;
514 	int use_default = 0;
515 	unsigned int cur;
516 
517 	REQUIRE(rdata != NULL);
518 	REQUIRE(tctx->origin == NULL ||	dns_name_isabsolute(tctx->origin));
519 
520 	/*
521 	 * Some DynDNS meta-RRs have empty rdata.
522 	 */
523 	if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
524 		INSIST(rdata->length == 0);
525 		return (ISC_R_SUCCESS);
526 	}
527 
528 	cur = isc_buffer_usedlength(target);
529 
530 	TOTEXTSWITCH
531 
532 	if (use_default || (result == ISC_R_NOTIMPLEMENTED)) {
533 		unsigned int u = isc_buffer_usedlength(target);
534 
535 		INSIST(u >= cur);
536 		isc_buffer_subtract(target, u - cur);
537 		result = unknown_totext(rdata, tctx, target);
538 	}
539 
540 	return (result);
541 }
542 
543 isc_result_t
544 dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target)
545 {
546 	dns_rdata_textctx_t tctx;
547 
548 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
549 
550 	/*
551 	 * Set up formatting options for single-line output.
552 	 */
553 	tctx.origin = origin;
554 	tctx.flags = 0;
555 	tctx.width = 60;
556 	tctx.linebreak = " ";
557 	return (rdata_totext(rdata, &tctx, target));
558 }
559 
560 isc_result_t
561 dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin,
562 		    unsigned int flags, unsigned int width,
563 		    unsigned int split_width, const char *linebreak,
564 		    isc_buffer_t *target)
565 {
566 	dns_rdata_textctx_t tctx;
567 
568 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
569 
570 	/*
571 	 * Set up formatting options for formatted output.
572 	 */
573 	tctx.origin = origin;
574 	tctx.flags = flags;
575 	if (split_width == 0xffffffff)
576 		tctx.width = width;
577 	else
578 		tctx.width = split_width;
579 
580 	if ((flags & DNS_STYLEFLAG_MULTILINE) != 0)
581 		tctx.linebreak = linebreak;
582 	else {
583 		if (split_width == 0xffffffff)
584 			tctx.width = 60; /* Used for hex word length only. */
585 		tctx.linebreak = " ";
586 	}
587 	return (rdata_totext(rdata, &tctx, target));
588 }
589 
590 isc_result_t
591 dns_rdata_fromstruct_soa(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
592 		     dns_rdatatype_t type, dns_rdata_soa_t *soa,
593 		     isc_buffer_t *target)
594 {
595 	isc_result_t result = ISC_R_NOTIMPLEMENTED;
596 	isc_buffer_t st;
597 	isc_region_t region;
598 	unsigned int length;
599 
600 	REQUIRE(soa != NULL);
601 	if (rdata != NULL) {
602 		REQUIRE(DNS_RDATA_INITIALIZED(rdata));
603 		REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
604 	}
605 
606 	st = *target;
607 	result = fromstruct_soa(rdclass, type, soa, target);
608 
609 	length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st);
610 	if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH)
611 		result = ISC_R_NOSPACE;
612 
613 	if (rdata != NULL && result == ISC_R_SUCCESS) {
614 		region.base = isc_buffer_used(&st);
615 		region.length = length;
616 		dns_rdata_fromregion(rdata, rdclass, type, &region);
617 	}
618 	if (result != ISC_R_SUCCESS)
619 		*target = st;
620 	return (result);
621 }
622 
623 isc_result_t
624 dns_rdata_fromstruct_tsig(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
625 		     dns_rdatatype_t type, dns_rdata_any_tsig_t *tsig,
626 		     isc_buffer_t *target)
627 {
628 	isc_result_t result = ISC_R_NOTIMPLEMENTED;
629 	isc_buffer_t st;
630 	isc_region_t region;
631 	unsigned int length;
632 
633 	REQUIRE(tsig != NULL);
634 	if (rdata != NULL) {
635 		REQUIRE(DNS_RDATA_INITIALIZED(rdata));
636 		REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
637 	}
638 
639 	st = *target;
640 	result = fromstruct_any_tsig(rdclass, type, tsig, target);
641 
642 	length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st);
643 	if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH)
644 		result = ISC_R_NOSPACE;
645 
646 	if (rdata != NULL && result == ISC_R_SUCCESS) {
647 		region.base = isc_buffer_used(&st);
648 		region.length = length;
649 		dns_rdata_fromregion(rdata, rdclass, type, &region);
650 	}
651 	if (result != ISC_R_SUCCESS)
652 		*target = st;
653 	return (result);
654 }
655 
656 isc_result_t
657 dns_rdata_tostruct_cname(const dns_rdata_t *rdata, dns_rdata_cname_t *cname) {
658 	REQUIRE(rdata != NULL);
659 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
660 
661 	return (tostruct_cname(rdata, cname));
662 }
663 
664 isc_result_t
665 dns_rdata_tostruct_ns(const dns_rdata_t *rdata, dns_rdata_ns_t *ns) {
666 	REQUIRE(rdata != NULL);
667 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
668 
669 	return (tostruct_ns(rdata, ns));
670 }
671 
672 isc_result_t
673 dns_rdata_tostruct_soa(const dns_rdata_t *rdata, dns_rdata_soa_t *soa) {
674 	REQUIRE(rdata != NULL);
675 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
676 
677 	return (tostruct_soa(rdata, soa));
678 }
679 
680 isc_result_t
681 dns_rdata_tostruct_tsig(const dns_rdata_t *rdata, dns_rdata_any_tsig_t *tsig) {
682 	REQUIRE(rdata != NULL);
683 	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
684 
685 	return (tostruct_any_tsig(rdata, tsig));
686 }
687 
688 void
689 dns_rdata_freestruct_cname(dns_rdata_cname_t *cname) {
690 	REQUIRE(cname != NULL);
691 
692 	freestruct_cname(cname);
693 }
694 
695 void
696 dns_rdata_freestruct_ns(dns_rdata_ns_t *ns) {
697 	REQUIRE(ns != NULL);
698 
699 	freestruct_ns(ns);
700 }
701 
702 void
703 dns_rdata_freestruct_soa(dns_rdata_soa_t *soa) {
704 	REQUIRE(soa != NULL);
705 
706 	freestruct_soa(soa);
707 }
708 
709 void
710 dns_rdata_freestruct_tsig(dns_rdata_any_tsig_t *tsig) {
711 	REQUIRE(tsig != NULL);
712 
713 	freestruct_any_tsig(tsig);
714 }
715 
716 int
717 dns_rdata_checkowner_nsec3(dns_name_t *name, dns_rdataclass_t rdclass,
718 		     dns_rdatatype_t type, int wildcard)
719 {
720 	return checkowner_nsec3(name, rdclass, type, wildcard);
721 }
722 
723 unsigned int
724 dns_rdatatype_attributes(dns_rdatatype_t type)
725 {
726 	switch (type) {
727 	case 0:
728 	case 31:
729 	case 32:
730 	case 34:
731 	case 100:
732 	case 101:
733 	case 102:
734 		return (DNS_RDATATYPEATTR_RESERVED);
735 	default:
736 		return (0);
737 	}
738 }
739 
740 static int
741 type_cmp(const void *k, const void *e)
742 {
743 	return (strcasecmp(k, ((const dns_rdata_type_lookup_t *)e)->type));
744 }
745 
746 isc_result_t
747 dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) {
748 	/* This has to be sorted always. */
749 	static const dns_rdata_type_lookup_t type_lookup[] = {
750 		{"a",		1},
751 		{"a6",		38},
752 		{"aaaa",	28},
753 		{"afsdb",	18},
754 		{"any",		255},
755 		{"apl",		42},
756 		{"atma",	34},
757 		{"avc",		258},
758 		{"axfr",	252},
759 		{"caa",		257},
760 		{"cdnskey",	60},
761 		{"cds",		59},
762 		{"cert",	37},
763 		{"cname",	5},
764 		{"csync",	62},
765 		{"dhcid",	49},
766 		{"dlv",		32769},
767 		{"dname",	39},
768 		{"dnskey",	48},
769 		{"doa",		259},
770 		{"ds",		43},
771 		{"eid",		31},
772 		{"eui48",	108},
773 		{"eui64",	109},
774 		{"gid",		102},
775 		{"gpos",	27},
776 		{"hinfo",	13},
777 		{"hip",		55},
778 		{"ipseckey",	45},
779 		{"isdn",	20},
780 		{"ixfr",	251},
781 		{"key",		25},
782 		{"keydata",	65533},
783 		{"kx",		36},
784 		{"l32",		105},
785 		{"l64",		106},
786 		{"loc",		29},
787 		{"lp",		107},
788 		{"maila",	254},
789 		{"mailb",	253},
790 		{"mb",		7},
791 		{"md",		3},
792 		{"mf",		4},
793 		{"mg",		8},
794 		{"minfo",	14},
795 		{"mr",		9},
796 		{"mx",		15},
797 		{"naptr",	35},
798 		{"nid",		104},
799 		{"nimloc",	32},
800 		{"ninfo",	56},
801 		{"ns",		2},
802 		{"nsap",	22},
803 		{"nsap-ptr",	23},
804 		{"nsec",	47},
805 		{"nsec3",	50},
806 		{"nsec3param",	51},
807 		{"null",	10},
808 		{"nxt",		30},
809 		{"openpgpkey",	61},
810 		{"opt",		41},
811 		{"ptr",		12},
812 		{"px",		26},
813 		{"reserved0",	0},
814 		{"rkey",	57},
815 		{"rp",		17},
816 		{"rrsig",	46},
817 		{"rt",		21},
818 		{"sig",		24},
819 		{"sink",	40},
820 		{"smimea",	53},
821 		{"soa",		6},
822 		{"spf",		99},
823 		{"srv",		33},
824 		{"sshfp",	44},
825 		{"ta",		32768},
826 		{"talink",	58},
827 		{"tkey",	249},
828 		{"tlsa",	52},
829 		{"tsig",	250},
830 		{"txt",		16},
831 		{"uid",		101},
832 		{"uinfo",	100},
833 		{"unspec",	103},
834 		{"uri",		256},
835 		{"wks",		11},
836 		{"x25",		19}
837 	};
838 	const dns_rdata_type_lookup_t *p;
839 	unsigned int n;
840 	char lookup[sizeof("nsec3param")];
841 
842 	n = source->length;
843 
844 	if (n == 0)
845 		return (DNS_R_UNKNOWN);
846 
847 	/* source->base is not required to be NUL terminated. */
848 	if ((size_t)snprintf(lookup, sizeof(lookup), "%.*s", n, source->base)
849 	    >= sizeof(lookup))
850 		return (DNS_R_UNKNOWN);
851 
852 	p = bsearch(lookup, type_lookup,
853 	    sizeof(type_lookup)/sizeof(type_lookup[0]), sizeof(type_lookup[0]),
854 	    type_cmp);
855 
856 	if (p) {
857 		if ((dns_rdatatype_attributes(p->val) &
858 		    DNS_RDATATYPEATTR_RESERVED) != 0)
859 			return (ISC_R_NOTIMPLEMENTED);
860 		*typep = p->val;
861 		return (ISC_R_SUCCESS);
862 	}
863 
864 	if (n > 4 && strncasecmp("type", lookup, 4) == 0) {
865 		int val;
866 		const char *errstr;
867 		val = strtonum(lookup + 4, 0, UINT16_MAX, &errstr);
868 		if (errstr == NULL) {
869 			*typep = val;
870 			return (ISC_R_SUCCESS);
871 		}
872 	}
873 
874 	return (DNS_R_UNKNOWN);
875 }
876 
877 isc_result_t
878 dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) {
879 	char buf[sizeof("TYPE65535")];
880 
881 	switch (type) {
882 	case 0:
883 		return (isc_str_tobuffer("RESERVED0", target));
884 	case 1:
885 		return (isc_str_tobuffer("A", target));
886 	case 2:
887 		return (isc_str_tobuffer("NS", target));
888 	case 3:
889 		return (isc_str_tobuffer("MD", target));
890 	case 4:
891 		return (isc_str_tobuffer("MF", target));
892 	case 5:
893 		return (isc_str_tobuffer("CNAME", target));
894 	case 6:
895 		return (isc_str_tobuffer("SOA", target));
896 	case 7:
897 		return (isc_str_tobuffer("MB", target));
898 	case 8:
899 		return (isc_str_tobuffer("MG", target));
900 	case 9:
901 		return (isc_str_tobuffer("MR", target));
902 	case 10:
903 		return (isc_str_tobuffer("NULL", target));
904 	case 11:
905 		return (isc_str_tobuffer("WKS", target));
906 	case 12:
907 		return (isc_str_tobuffer("PTR", target));
908 	case 13:
909 		return (isc_str_tobuffer("HINFO", target));
910 	case 14:
911 		return (isc_str_tobuffer("MINFO", target));
912 	case 15:
913 		return (isc_str_tobuffer("MX", target));
914 	case 16:
915 		return (isc_str_tobuffer("TXT", target));
916 	case 17:
917 		return (isc_str_tobuffer("RP", target));
918 	case 18:
919 		return (isc_str_tobuffer("AFSDB", target));
920 	case 19:
921 		return (isc_str_tobuffer("X25", target));
922 	case 20:
923 		return (isc_str_tobuffer("ISDN", target));
924 	case 21:
925 		return (isc_str_tobuffer("RT", target));
926 	case 22:
927 		return (isc_str_tobuffer("NSAP", target));
928 	case 23:
929 		return (isc_str_tobuffer("NSAP-PTR", target));
930 	case 24:
931 		return (isc_str_tobuffer("SIG", target));
932 	case 25:
933 		return (isc_str_tobuffer("KEY", target));
934 	case 26:
935 		return (isc_str_tobuffer("PX", target));
936 	case 27:
937 		return (isc_str_tobuffer("GPOS", target));
938 	case 28:
939 		return (isc_str_tobuffer("AAAA", target));
940 	case 29:
941 		return (isc_str_tobuffer("LOC", target));
942 	case 30:
943 		return (isc_str_tobuffer("NXT", target));
944 	case 31:
945 		return (isc_str_tobuffer("EID", target));
946 	case 32:
947 		return (isc_str_tobuffer("NIMLOC", target));
948 	case 33:
949 		return (isc_str_tobuffer("SRV", target));
950 	case 34:
951 		return (isc_str_tobuffer("ATMA", target));
952 	case 35:
953 		return (isc_str_tobuffer("NAPTR", target));
954 	case 36:
955 		return (isc_str_tobuffer("KX", target));
956 	case 37:
957 		return (isc_str_tobuffer("CERT", target));
958 	case 38:
959 		return (isc_str_tobuffer("A6", target));
960 	case 39:
961 		return (isc_str_tobuffer("DNAME", target));
962 	case 40:
963 		return (isc_str_tobuffer("SINK", target));
964 	case 41:
965 		return (isc_str_tobuffer("OPT", target));
966 	case 42:
967 		return (isc_str_tobuffer("APL", target));
968 	case 43:
969 		return (isc_str_tobuffer("DS", target));
970 	case 44:
971 		return (isc_str_tobuffer("SSHFP", target));
972 	case 45:
973 		return (isc_str_tobuffer("IPSECKEY", target));
974 	case 46:
975 		return (isc_str_tobuffer("RRSIG", target));
976 	case 47:
977 		return (isc_str_tobuffer("NSEC", target));
978 	case 48:
979 		return (isc_str_tobuffer("DNSKEY", target));
980 	case 49:
981 		return (isc_str_tobuffer("DHCID", target));
982 	case 50:
983 		return (isc_str_tobuffer("NSEC3", target));
984 	case 51:
985 		return (isc_str_tobuffer("NSEC3PARAM", target));
986 	case 52:
987 		return (isc_str_tobuffer("TLSA", target));
988 	case 53:
989 		return (isc_str_tobuffer("SMIMEA", target));
990 	case 55:
991 		return (isc_str_tobuffer("HIP", target));
992 	case 56:
993 		return (isc_str_tobuffer("NINFO", target));
994 	case 57:
995 		return (isc_str_tobuffer("RKEY", target));
996 	case 58:
997 		return (isc_str_tobuffer("TALINK", target));
998 	case 59:
999 		return (isc_str_tobuffer("CDS", target));
1000 	case 60:
1001 		return (isc_str_tobuffer("CDNSKEY", target));
1002 	case 61:
1003 		return (isc_str_tobuffer("OPENPGPKEY", target));
1004 	case 62:
1005 		return (isc_str_tobuffer("CSYNC", target));
1006 	case 99:
1007 		return (isc_str_tobuffer("SPF", target));
1008 	case 100:
1009 		return (isc_str_tobuffer("UINFO", target));
1010 	case 101:
1011 		return (isc_str_tobuffer("UID", target));
1012 	case 102:
1013 		return (isc_str_tobuffer("GID", target));
1014 	case 103:
1015 		return (isc_str_tobuffer("UNSPEC", target));
1016 	case 104:
1017 		return (isc_str_tobuffer("NID", target));
1018 	case 105:
1019 		return (isc_str_tobuffer("L32", target));
1020 	case 106:
1021 		return (isc_str_tobuffer("L64", target));
1022 	case 107:
1023 		return (isc_str_tobuffer("LP", target));
1024 	case 108:
1025 		return (isc_str_tobuffer("EUI48", target));
1026 	case 109:
1027 		return (isc_str_tobuffer("EUI64", target));
1028 	case 249:
1029 		return (isc_str_tobuffer("TKEY", target));
1030 	case 250:
1031 		return (isc_str_tobuffer("TSIG", target));
1032 	case 251:
1033 		return (isc_str_tobuffer("IXFR", target));
1034 	case 252:
1035 		return (isc_str_tobuffer("AXFR", target));
1036 	case 253:
1037 		return (isc_str_tobuffer("MAILB", target));
1038 	case 254:
1039 		return (isc_str_tobuffer("MAILA", target));
1040 	case 255:
1041 		return (isc_str_tobuffer("ANY", target));
1042 	case 256:
1043 		return (isc_str_tobuffer("URI", target));
1044 	case 257:
1045 		return (isc_str_tobuffer("CAA", target));
1046 	case 258:
1047 		return (isc_str_tobuffer("AVC", target));
1048 	case 259:
1049 		return (isc_str_tobuffer("DOA", target));
1050 	case 32768:
1051 		return (isc_str_tobuffer("TA", target));
1052 	case 32769:
1053 		return (isc_str_tobuffer("DLV", target));
1054 	default:
1055 		snprintf(buf, sizeof(buf), "TYPE%u", type);
1056 		return (isc_str_tobuffer(buf, target));
1057 	}
1058 }
1059 
1060 void
1061 dns_rdatatype_format(dns_rdatatype_t rdtype,
1062 		     char *array, unsigned int size)
1063 {
1064 	isc_result_t result;
1065 	isc_buffer_t buf;
1066 
1067 	if (size == 0U)
1068 		return;
1069 
1070 	isc_buffer_init(&buf, array, size);
1071 	result = dns_rdatatype_totext(rdtype, &buf);
1072 	/*
1073 	 * Null terminate.
1074 	 */
1075 	if (result == ISC_R_SUCCESS) {
1076 		if (isc_buffer_availablelength(&buf) >= 1)
1077 			isc_buffer_putuint8(&buf, 0);
1078 		else
1079 			result = ISC_R_NOSPACE;
1080 	}
1081 	if (result != ISC_R_SUCCESS)
1082 		strlcpy(array, "<unknown>", size);
1083 }
1084 
1085 /*
1086  * Private function.
1087  */
1088 
1089 static unsigned int
1090 name_length(dns_name_t *name) {
1091 	return (name->length);
1092 }
1093 
1094 static isc_result_t
1095 txt_totext(isc_region_t *source, int quote, isc_buffer_t *target) {
1096 	unsigned int tl;
1097 	unsigned int n;
1098 	unsigned char *sp;
1099 	char *tp;
1100 	isc_region_t region;
1101 
1102 	isc_buffer_availableregion(target, &region);
1103 	sp = source->base;
1104 	tp = (char *)region.base;
1105 	tl = region.length;
1106 
1107 	n = *sp++;
1108 
1109 	REQUIRE(n + 1 <= source->length);
1110 	if (n == 0U)
1111 		REQUIRE(quote);
1112 
1113 	if (quote) {
1114 		if (tl < 1)
1115 			return (ISC_R_NOSPACE);
1116 		*tp++ = '"';
1117 		tl--;
1118 	}
1119 	while (n--) {
1120 		/*
1121 		 * \DDD space (0x20) if not quoting.
1122 		 */
1123 		if (*sp < (quote ? 0x20 : 0x21) || *sp >= 0x7f) {
1124 			if (tl < 4)
1125 				return (ISC_R_NOSPACE);
1126 			*tp++ = 0x5c;
1127 			*tp++ = 0x30 + ((*sp / 100) % 10);
1128 			*tp++ = 0x30 + ((*sp / 10) % 10);
1129 			*tp++ = 0x30 + (*sp % 10);
1130 			sp++;
1131 			tl -= 4;
1132 			continue;
1133 		}
1134 		/*
1135 		 * Escape double quote and backslash.  If we are not
1136 		 * enclosing the string in double quotes also escape
1137 		 * at sign and semicolon.
1138 		 */
1139 		if (*sp == 0x22 || *sp == 0x5c ||
1140 		    (!quote && (*sp == 0x40 || *sp == 0x3b))) {
1141 			if (tl < 2)
1142 				return (ISC_R_NOSPACE);
1143 			*tp++ = '\\';
1144 			tl--;
1145 		}
1146 		if (tl < 1)
1147 			return (ISC_R_NOSPACE);
1148 		*tp++ = *sp++;
1149 		tl--;
1150 	}
1151 	if (quote) {
1152 		if (tl < 1)
1153 			return (ISC_R_NOSPACE);
1154 		*tp++ = '"';
1155 		tl--;
1156 		POST(tl);
1157 	}
1158 	isc_buffer_add(target, (unsigned int)(tp - (char *)region.base));
1159 	isc_region_consume(source, *source->base + 1);
1160 	return (ISC_R_SUCCESS);
1161 }
1162 
1163 static isc_result_t
1164 txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
1165 	unsigned int n;
1166 	isc_region_t sregion;
1167 	isc_region_t tregion;
1168 
1169 	isc_buffer_activeregion(source, &sregion);
1170 	if (sregion.length == 0)
1171 		return (ISC_R_UNEXPECTEDEND);
1172 	n = *sregion.base + 1;
1173 	if (n > sregion.length)
1174 		return (ISC_R_UNEXPECTEDEND);
1175 
1176 	isc_buffer_availableregion(target, &tregion);
1177 	if (n > tregion.length)
1178 		return (ISC_R_NOSPACE);
1179 
1180 	if (tregion.base != sregion.base)
1181 		memmove(tregion.base, sregion.base, n);
1182 	isc_buffer_forward(source, n);
1183 	isc_buffer_add(target, n);
1184 	return (ISC_R_SUCCESS);
1185 }
1186 
1187 /*
1188  * Conversion of TXT-like rdata fields without length limits.
1189  */
1190 static isc_result_t
1191 multitxt_totext(isc_region_t *source, isc_buffer_t *target) {
1192 	unsigned int tl;
1193 	unsigned int n0, n;
1194 	unsigned char *sp;
1195 	char *tp;
1196 	isc_region_t region;
1197 
1198 	isc_buffer_availableregion(target, &region);
1199 	sp = source->base;
1200 	tp = (char *)region.base;
1201 	tl = region.length;
1202 
1203 	if (tl < 1)
1204 		return (ISC_R_NOSPACE);
1205 	*tp++ = '"';
1206 	tl--;
1207 	do {
1208 		n = source->length;
1209 		n0 = source->length - 1;
1210 
1211 		while (n--) {
1212 			if (*sp < 0x20 || *sp >= 0x7f) {
1213 				if (tl < 4)
1214 					return (ISC_R_NOSPACE);
1215 				*tp++ = 0x5c;
1216 				*tp++ = 0x30 + ((*sp / 100) % 10);
1217 				*tp++ = 0x30 + ((*sp / 10) % 10);
1218 				*tp++ = 0x30 + (*sp % 10);
1219 				sp++;
1220 				tl -= 4;
1221 				continue;
1222 			}
1223 			/* double quote, backslash */
1224 			if (*sp == 0x22 || *sp == 0x5c) {
1225 				if (tl < 2)
1226 					return (ISC_R_NOSPACE);
1227 				*tp++ = '\\';
1228 				tl--;
1229 			}
1230 			if (tl < 1)
1231 				return (ISC_R_NOSPACE);
1232 			*tp++ = *sp++;
1233 			tl--;
1234 		}
1235 		isc_region_consume(source, n0 + 1);
1236 	} while (source->length != 0);
1237 	if (tl < 1)
1238 		return (ISC_R_NOSPACE);
1239 	*tp++ = '"';
1240 	tl--;
1241 	POST(tl);
1242 	isc_buffer_add(target, (unsigned int)(tp - (char *)region.base));
1243 	return (ISC_R_SUCCESS);
1244 }
1245 
1246 static int
1247 name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) {
1248 	int l1, l2;
1249 
1250 	if (origin == NULL)
1251 		goto return_false;
1252 
1253 	if (dns_name_compare(origin, dns_rootname) == 0)
1254 		goto return_false;
1255 
1256 	if (!dns_name_issubdomain(name, origin))
1257 		goto return_false;
1258 
1259 	l1 = dns_name_countlabels(name);
1260 	l2 = dns_name_countlabels(origin);
1261 
1262 	if (l1 == l2)
1263 		goto return_false;
1264 
1265 	/* Master files should be case preserving. */
1266 	dns_name_getlabelsequence(name, l1 - l2, l2, target);
1267 	if (!dns_name_caseequal(origin, target))
1268 		goto return_false;
1269 
1270 	dns_name_getlabelsequence(name, 0, l1 - l2, target);
1271 	return (1);
1272 
1273 return_false:
1274 	*target = *name;
1275 	return (0);
1276 }
1277 
1278 static isc_result_t
1279 inet_totext(int af, isc_region_t *src, isc_buffer_t *target) {
1280 	char tmpbuf[64];
1281 
1282 	/* Note - inet_ntop doesn't do size checking on its input. */
1283 	if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL)
1284 		return (ISC_R_NOSPACE);
1285 	if (strlen(tmpbuf) > isc_buffer_availablelength(target))
1286 		return (ISC_R_NOSPACE);
1287 	isc_buffer_putstr(target, tmpbuf);
1288 	return (ISC_R_SUCCESS);
1289 }
1290 
1291 static int
1292 buffer_empty(isc_buffer_t *source) {
1293 	return((source->current == source->active) ? 1 : 0);
1294 }
1295 
1296 static isc_result_t
1297 uint32_tobuffer(uint32_t value, isc_buffer_t *target) {
1298 	isc_region_t region;
1299 
1300 	isc_buffer_availableregion(target, &region);
1301 	if (region.length < 4)
1302 		return (ISC_R_NOSPACE);
1303 	isc_buffer_putuint32(target, value);
1304 	return (ISC_R_SUCCESS);
1305 }
1306 
1307 static isc_result_t
1308 uint16_tobuffer(uint32_t value, isc_buffer_t *target) {
1309 	isc_region_t region;
1310 
1311 	if (value > 0xffff)
1312 		return (ISC_R_RANGE);
1313 	isc_buffer_availableregion(target, &region);
1314 	if (region.length < 2)
1315 		return (ISC_R_NOSPACE);
1316 	isc_buffer_putuint16(target, (uint16_t)value);
1317 	return (ISC_R_SUCCESS);
1318 }
1319 
1320 static isc_result_t
1321 name_tobuffer(dns_name_t *name, isc_buffer_t *target) {
1322 	isc_region_t r;
1323 	dns_name_toregion(name, &r);
1324 	return (isc_buffer_copyregion(target, &r));
1325 }
1326 
1327 static uint32_t
1328 uint32_fromregion(isc_region_t *region) {
1329 	uint32_t value;
1330 
1331 	REQUIRE(region->length >= 4);
1332 	value = region->base[0] << 24;
1333 	value |= region->base[1] << 16;
1334 	value |= region->base[2] << 8;
1335 	value |= region->base[3];
1336 	return(value);
1337 }
1338 
1339 static uint16_t
1340 uint16_fromregion(isc_region_t *region) {
1341 
1342 	REQUIRE(region->length >= 2);
1343 
1344 	return ((region->base[0] << 8) | region->base[1]);
1345 }
1346 
1347 static uint8_t
1348 uint8_fromregion(isc_region_t *region) {
1349 
1350 	REQUIRE(region->length >= 1);
1351 
1352 	return (region->base[0]);
1353 }
1354 
1355 static uint8_t
1356 uint8_consume_fromregion(isc_region_t *region) {
1357 	uint8_t r = uint8_fromregion(region);
1358 
1359 	isc_region_consume(region, 1);
1360 	return r;
1361 }
1362 
1363 static const char atob_digits[86] =
1364 	"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \
1365 	"abcdefghijklmnopqrstu";
1366 /*
1367  * Subroutines to convert between 8 bit binary bytes and printable ASCII.
1368  * Computes the number of bytes, and three kinds of simple checksums.
1369  * Incoming bytes are collected into 32-bit words, then printed in base 85:
1370  *	exp(85,5) > exp(2,32)
1371  * The ASCII characters used are between '!' and 'u';
1372  * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data.
1373  *
1374  * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for
1375  * the atob/btoa programs, released with the compress program, in mod.sources.
1376  * Modified by Mike Schwartz 8/19/86 for use in BIND.
1377  * Modified to be re-entrant 3/2/99.
1378  */
1379 
1380 struct state {
1381 	int32_t Ceor;
1382 	int32_t Csum;
1383 	int32_t Crot;
1384 	int32_t word;
1385 	int32_t bcount;
1386 };
1387 
1388 #define Ceor state->Ceor
1389 #define Csum state->Csum
1390 #define Crot state->Crot
1391 #define word state->word
1392 #define bcount state->bcount
1393 
1394 static isc_result_t	byte_btoa(int c, isc_buffer_t *, struct state *state);
1395 
1396 /*
1397  * Encode binary byte c into ASCII representation and place into *bufp,
1398  * advancing bufp.
1399  */
1400 static isc_result_t
1401 byte_btoa(int c, isc_buffer_t *target, struct state *state) {
1402 	isc_region_t tr;
1403 
1404 	isc_buffer_availableregion(target, &tr);
1405 	Ceor ^= c;
1406 	Csum += c;
1407 	Csum += 1;
1408 	if ((Crot & 0x80000000)) {
1409 		Crot <<= 1;
1410 		Crot += 1;
1411 	} else {
1412 		Crot <<= 1;
1413 	}
1414 	Crot += c;
1415 
1416 	word <<= 8;
1417 	word |= c;
1418 	if (bcount == 3) {
1419 		if (word == 0) {
1420 			if (tr.length < 1)
1421 				return (ISC_R_NOSPACE);
1422 			tr.base[0] = 'z';
1423 			isc_buffer_add(target, 1);
1424 		} else {
1425 		    register int tmp = 0;
1426 		    register int32_t tmpword = word;
1427 
1428 		    if (tmpword < 0) {
1429 			   /*
1430 			    * Because some don't support u_long.
1431 			    */
1432 			tmp = 32;
1433 			tmpword -= (int32_t)(85 * 85 * 85 * 85 * 32);
1434 		    }
1435 		    if (tmpword < 0) {
1436 			tmp = 64;
1437 			tmpword -= (int32_t)(85 * 85 * 85 * 85 * 32);
1438 		    }
1439 			if (tr.length < 5)
1440 				return (ISC_R_NOSPACE);
1441 			tr.base[0] = atob_digits[(tmpword /
1442 					      (int32_t)(85 * 85 * 85 * 85))
1443 						+ tmp];
1444 			tmpword %= (int32_t)(85 * 85 * 85 * 85);
1445 			tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)];
1446 			tmpword %= (85 * 85 * 85);
1447 			tr.base[2] = atob_digits[tmpword / (85 * 85)];
1448 			tmpword %= (85 * 85);
1449 			tr.base[3] = atob_digits[tmpword / 85];
1450 			tmpword %= 85;
1451 			tr.base[4] = atob_digits[tmpword];
1452 			isc_buffer_add(target, 5);
1453 		}
1454 		bcount = 0;
1455 	} else {
1456 		bcount += 1;
1457 	}
1458 	return (ISC_R_SUCCESS);
1459 }
1460 
1461 /*
1462  * Encode the binary data from inbuf, of length inbuflen, into a
1463  * target.  Return success/failure status
1464  */
1465 static isc_result_t
1466 btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) {
1467 	int inc;
1468 	struct state statebuf, *state = &statebuf;
1469 	char buf[sizeof("x 2000000000 ffffffff ffffffff ffffffff")];
1470 
1471 	Ceor = Csum = Crot = word = bcount = 0;
1472 	for (inc = 0; inc < inbuflen; inbuf++, inc++)
1473 		RETERR(byte_btoa(*inbuf, target, state));
1474 
1475 	while (bcount != 0)
1476 		RETERR(byte_btoa(0, target, state));
1477 
1478 	/*
1479 	 * Put byte count and checksum information at end of buffer,
1480 	 * delimited by 'x'
1481 	 */
1482 	snprintf(buf, sizeof(buf), "x %d %x %x %x", inbuflen, Ceor, Csum, Crot);
1483 	return (isc_str_tobuffer(buf, target));
1484 }
1485 
1486 dns_rdatatype_t
1487 dns_rdata_covers(dns_rdata_t *rdata) {
1488 	if (rdata->type == dns_rdatatype_rrsig)
1489 		return (covers_rrsig(rdata));
1490 	return (covers_sig(rdata));
1491 }
1492