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