Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2  * rdata.c -- RDATA conversion functions.
      3  *
      4  * Copyright (c) 2001-2006, 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 <stdlib.h>
     19 #include <string.h>
     20 #include <inttypes.h>
     21 #ifdef HAVE_STRINGS_H
     22 #include <strings.h>
     23 #endif
     24 
     25 #include "rdata.h"
     26 #include "zonec.h"
     27 #include "query.h"
     28 #include "dname.h"
     29 
     30 /* Taken from RFC 4398, section 2.1.  */
     31 lookup_table_type dns_certificate_types[] = {
     32 /*	0		Reserved */
     33 	{ 1, "PKIX" },	/* X.509 as per PKIX */
     34 	{ 2, "SPKI" },	/* SPKI cert */
     35 	{ 3, "PGP" },	/* OpenPGP packet */
     36 	{ 4, "IPKIX" },	/* The URL of an X.509 data object */
     37 	{ 5, "ISPKI" },	/* The URL of an SPKI certificate */
     38 	{ 6, "IPGP" },	/* The fingerprint and URL of an OpenPGP packet */
     39 	{ 7, "ACPKIX" },	/* Attribute Certificate */
     40 	{ 8, "IACPKIX" },	/* The URL of an Attribute Certificate */
     41 	{ 253, "URI" },	/* URI private */
     42 	{ 254, "OID" },	/* OID private */
     43 /*	255 		Reserved */
     44 /* 	256-65279	Available for IANA assignment */
     45 /*	65280-65534	Experimental */
     46 /*	65535		Reserved */
     47 	{ 0, NULL }
     48 };
     49 
     50 /* Taken from RFC 2535, section 7.  */
     51 lookup_table_type dns_algorithms[] = {
     52 	{ 1, "RSAMD5" },	/* RFC 2537 */
     53 	{ 2, "DH" },		/* RFC 2539 */
     54 	{ 3, "DSA" },		/* RFC 2536 */
     55 	{ 4, "ECC" },
     56 	{ 5, "RSASHA1" },	/* RFC 3110 */
     57 	{ 6, "DSA-NSEC3-SHA1" },	/* RFC 5155 */
     58 	{ 7, "RSASHA1-NSEC3-SHA1" },	/* RFC 5155 */
     59 	{ 8, "RSASHA256" },		/* RFC 5702 */
     60 	{ 10, "RSASHA512" },		/* RFC 5702 */
     61 	{ 12, "ECC-GOST" },		/* RFC 5933 */
     62 	{ 13, "ECDSAP256SHA256" },	/* RFC 6605 */
     63 	{ 14, "ECDSAP384SHA384" },	/* RFC 6605 */
     64 	{ 15, "ED25519" },		/* RFC 8080 */
     65 	{ 16, "ED448" },		/* RFC 8080 */
     66 	{ 252, "INDIRECT" },
     67 	{ 253, "PRIVATEDNS" },
     68 	{ 254, "PRIVATEOID" },
     69 	{ 0, NULL }
     70 };
     71 
     72 /* Print svcparam key without a value */
     73 static int print_svcparam_no_value(struct buffer *output, uint16_t svcparamkey,
     74 	const uint8_t* data, uint16_t datalen);
     75 
     76 /* Print svcparam mandatory */
     77 static int print_svcparam_mandatory(struct buffer *output,
     78 	uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
     79 
     80 /* Print svcparam alpn */
     81 static int print_svcparam_alpn(struct buffer *output,
     82 	uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
     83 
     84 /* Print svcparam port */
     85 static int print_svcparam_port(struct buffer *output,
     86 	uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
     87 
     88 /* Print svcparam ipv4hint */
     89 static int print_svcparam_ipv4hint(struct buffer *output,
     90 	uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
     91 
     92 /* Print svcparam ech */
     93 static int print_svcparam_ech(struct buffer *output,
     94 	uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
     95 
     96 /* Print svcparam ipv6hint */
     97 static int print_svcparam_ipv6hint(struct buffer *output,
     98 	uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
     99 
    100 /* Print svcparam dohpath */
    101 static int print_svcparam_dohpath(struct buffer *output,
    102 	uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
    103 
    104 /* Print svcparam tls-supported-groups */
    105 static int print_svcparam_tls_supported_groups(struct buffer *output,
    106 	uint16_t svcparamkey, const uint8_t* data, uint16_t datalen);
    107 
    108 static const nsd_svcparam_descriptor_type svcparams[] = {
    109 	{ SVCB_KEY_MANDATORY, "mandatory", print_svcparam_mandatory },
    110 	{ SVCB_KEY_ALPN, "alpn", print_svcparam_alpn },
    111 	{ SVCB_KEY_NO_DEFAULT_ALPN, "no-default-alpn",
    112 		print_svcparam_no_value },
    113 	{ SVCB_KEY_PORT, "port", print_svcparam_port },
    114 	{ SVCB_KEY_IPV4HINT, "ipv4hint", print_svcparam_ipv4hint },
    115 	{ SVCB_KEY_ECH, "ech", print_svcparam_ech },
    116 	{ SVCB_KEY_IPV6HINT, "ipv6hint", print_svcparam_ipv6hint },
    117 	{ SVCB_KEY_DOHPATH, "dohpath", print_svcparam_dohpath },
    118 	{ SVCB_KEY_OHTTP, "ohttp", print_svcparam_no_value },
    119 	{ SVCB_KEY_TLS_SUPPORTED_GROUPS, "tls-supported-groups",
    120 		print_svcparam_tls_supported_groups },
    121 };
    122 
    123 /*
    124  * Print domain name, as example.com. with escapes.
    125  * The domain name is wireformat in the rdata. That is a literal dname
    126  * in the rdata.
    127  * @param output: the string is output here.
    128  * @param rdlength: length of rdata.
    129  * @param rdata: the rdata. The rdata+*offset is where the field is.
    130  * @param offset: the current position on input. The position is updated to
    131  *	be incremented with the length of rdata that was used.
    132  * @return false on failure.
    133  */
    134 static int
    135 print_name_literal(struct buffer *output, uint16_t rdlength,
    136 	const uint8_t *rdata, uint16_t *offset)
    137 {
    138 	const uint8_t *name, *label, *limit;
    139 	assert(rdlength >= *offset);
    140 	if (rdlength - *offset == 0)
    141 		return 0;
    142 
    143 	name = rdata + *offset;
    144 	label = name;
    145 	limit = rdata + rdlength;
    146 
    147 	if(*label) {
    148 		do {
    149 			/* space for labellen, label and a next root label. */
    150 			if (label - name > MAXDOMAINLEN-1
    151 				|| *label > MAXLABELLEN
    152 				|| limit - label < 2 + *label)
    153 				return 0;
    154 			label += 1 + *label;
    155 		} while (*label);
    156 	} else {
    157 		/* root domain. */
    158 		/* The label is within the rdlength by the checks at start of
    159 		 * the function. */
    160 	}
    161 
    162 	buffer_printf(output, "%s", wiredname2str(name));
    163 	*offset += (label - name) + 1 /* root label */;
    164 	return 1;
    165 }
    166 
    167 /*
    168  * Print domain name, as example.com. with escapes.
    169  * The domain must be a reference in the rdata. That is a stored pointer
    170  * to struct domain.
    171  * @param output: the string is output here.
    172  * @param rdlength: length of rdata.
    173  * @param rdata: the rdata. The rdata+*offset is where the field is.
    174  * @param offset: the current position on input. The position is updated to
    175  *	be incremented with the length of rdata that was used.
    176  * @return false on failure.
    177  */
    178 static int
    179 print_domain(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
    180 	uint16_t *offset)
    181 {
    182 	const struct dname *dname;
    183 	struct domain *domain;
    184 	if(rdlength - *offset < (uint16_t)sizeof(void*))
    185 		return 0;
    186 	memcpy(&domain, rdata+*offset, sizeof(void*));
    187 	dname = domain_dname(domain);
    188 	buffer_printf(output, "%s", dname_to_string(dname, NULL));
    189 	*offset += sizeof(void*);
    190 	return 1;
    191 }
    192 
    193 /* Return length of string or -1 on wireformat error. offset is moved +len. */
    194 static inline int32_t
    195 skip_string(struct buffer* output, uint16_t rdlength, uint16_t* offset)
    196 {
    197 	int32_t length;
    198 	if (rdlength - *offset < 1)
    199 		return -1;
    200 	length = buffer_read_u8(output);
    201 	if (length + 1 > rdlength - *offset)
    202 		return -1;
    203 	buffer_skip(output, length);
    204 	*offset += length + 1;
    205 	return length + 1;
    206 }
    207 
    208 /* Return length of strings or -1 on wireformat error. offset is moved +len. */
    209 static inline int32_t
    210 skip_strings(struct buffer* output, uint16_t rdlength, uint16_t* offset)
    211 {
    212 	int32_t olen = 0;
    213 	while(*offset < rdlength) {
    214 		int32_t slen = skip_string(output, rdlength, offset);
    215 		if(slen < 0)
    216 			return slen;
    217 		olen += slen;
    218 	}
    219 	return olen;
    220 }
    221 
    222 /*
    223  * Print string, as "string" with escapes.
    224  * @param output: the string is output here.
    225  * @param rdlength: length of rdata.
    226  * @param rdata: the rdata. The rdata+*offset is where the field is.
    227  * @param offset: the current position on input. The position is updated to
    228  *	be incremented with the length of rdata that was used.
    229  * @return false on failure.
    230  */
    231 static int
    232 print_string(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
    233 	uint16_t *offset)
    234 {
    235 	size_t n;
    236 	if(rdlength - *offset < 1)
    237 		return 0;
    238 	n = rdata[*offset];
    239 	if((size_t)rdlength - *offset < 1 + n)
    240 		return 0;
    241 	buffer_printf(output, "\"");
    242 	for (size_t i = 1; i <= n; i++) {
    243 		char ch = (char) rdata[*offset+i];
    244 		if (isprint((unsigned char)ch)) {
    245 			if (ch == '"' || ch == '\\') {
    246 				buffer_printf(output, "\\");
    247 			}
    248 			buffer_printf(output, "%c", ch);
    249 		} else {
    250 			buffer_printf(output, "\\%03u",
    251 				(unsigned) rdata[*offset+i]);
    252 		}
    253 	}
    254 	buffer_printf(output, "\"");
    255 	*offset += 1;
    256 	*offset += n;
    257 	return 1;
    258 }
    259 
    260 static int32_t
    261 print_text(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
    262 	uint16_t *offset)
    263 {
    264 	buffer_printf(output, "\"");
    265 	for (size_t i = *offset; i < rdlength; ++i) {
    266 		char ch = (char) rdata[i];
    267 		if (isprint((unsigned char)ch)) {
    268 			if (ch == '"' || ch == '\\') {
    269 				buffer_printf(output, "\\");
    270 			}
    271 			buffer_printf(output, "%c", ch);
    272 		} else {
    273 			buffer_printf(output, "\\%03u", (unsigned) rdata[i]);
    274 		}
    275 	}
    276 	buffer_printf(output, "\"");
    277 	*offset = rdlength;
    278 	return 1;
    279 }
    280 
    281 static int
    282 print_unquoted(buffer_type *output, uint16_t rdlength,
    283 	const uint8_t* rdata, uint16_t* offset)
    284 {
    285 	uint8_t len;
    286 	size_t i;
    287 
    288 	if(rdlength - *offset < 1)
    289 		return 0;
    290 	len = rdata[*offset];
    291 	if(((size_t)len) + 1 > (size_t)rdlength - *offset)
    292 		return 0;
    293 
    294 	for (i = 1; i <= (size_t)len; ++i) {
    295 		char ch = (char) rdata[*offset + i];
    296 		if (isprint((unsigned char)ch)) {
    297 			if (ch == '"' || ch == '\\' || ch == '(' || ch == ')'
    298 			  || ch == '\'' || isspace((unsigned char)ch)) {
    299 				buffer_printf(output, "\\");
    300 			}
    301 			buffer_printf(output, "%c", ch);
    302 		} else {
    303 			buffer_printf(output, "\\%03u",
    304 				(unsigned) rdata[*offset + i]);
    305 		}
    306 	}
    307 	*offset += 1;
    308 	*offset += len;
    309 	return 1;
    310 }
    311 
    312 static int
    313 print_unquoteds(buffer_type *output, uint16_t rdlength,
    314 	const uint8_t* rdata, uint16_t* offset)
    315 {
    316 	while (*offset < rdlength) {
    317 		if(!print_unquoted(output, rdlength, rdata, offset))
    318 			return 0;
    319 		if(*offset < rdlength)
    320 			buffer_printf(output, " ");
    321 	}
    322 	return 1;
    323 }
    324 
    325 /*
    326  * Print IP4 address.
    327  * @param output: the string is output here.
    328  * @param rdlength: length of rdata.
    329  * @param rdata: the rdata. The rdata+*offset is where the field is.
    330  * @param offset: the current position on input. The position is updated to
    331  *	be incremented with the length of rdata that was used.
    332  * @return false on failure.
    333  */
    334 static int
    335 print_ip4(struct buffer *output, size_t rdlength, const uint8_t *rdata,
    336 	uint16_t *offset)
    337 {
    338 	char str[INET_ADDRSTRLEN + 1];
    339 	assert(rdlength >= *offset);
    340 	if(((size_t)*offset) + 4 > rdlength)
    341 		return 0;
    342 	if(!inet_ntop(AF_INET, rdata + *offset, str, sizeof(str)))
    343 		return 0;
    344 	buffer_printf(output, "%s", str);
    345 	*offset += 4;
    346 	return 1;
    347 }
    348 
    349 /*
    350  * Print IP6 address.
    351  * @param output: the string is output here.
    352  * @param rdlength: length of rdata.
    353  * @param rdata: the rdata. The rdata+*offset is where the field is.
    354  * @param offset: the current position on input. The position is updated to
    355  *	be incremented with the length of rdata that was used.
    356  * @return false on failure.
    357  */
    358 static int
    359 print_ip6(struct buffer *output, size_t rdlength, const uint8_t *rdata,
    360 	uint16_t *offset)
    361 {
    362 	char str[INET6_ADDRSTRLEN + 1];
    363 	assert(rdlength >= *offset);
    364 	if (rdlength - *offset < 16)
    365 		return 0;
    366 	if (!inet_ntop(AF_INET6, rdata + *offset, str, sizeof(str)))
    367 		return 0;
    368 	buffer_printf(output, "%s", str);
    369 	*offset += 16;
    370 	return 1;
    371 }
    372 
    373 /*
    374  * Print ilnp64 field.
    375  * @param output: the string is output here.
    376  * @param rdlength: length of rdata.
    377  * @param rdata: the rdata. The rdata+*offset is where the field is.
    378  * @param offset: the current position on input. The position is updated to
    379  *	be incremented with the length of rdata that was used.
    380  * @return false on failure.
    381  */
    382 static int
    383 print_ilnp64(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
    384 	uint16_t *offset)
    385 {
    386 	uint16_t a1, a2, a3, a4;
    387 	assert(rdlength >= *offset);
    388 	if (rdlength - *offset < 8)
    389 		return 0;
    390 	a1 = read_uint16(rdata + *offset);
    391 	a2 = read_uint16(rdata + *offset + 2);
    392 	a3 = read_uint16(rdata + *offset + 4);
    393 	a4 = read_uint16(rdata + *offset + 6);
    394 
    395 	buffer_printf(output, "%.4x:%.4x:%.4x:%.4x", a1, a2, a3, a4);
    396 	*offset += 8;
    397 	return 1;
    398 }
    399 
    400 /*
    401  * Print certificate type.
    402  * @param output: the string is output here.
    403  * @param rdlength: length of rdata.
    404  * @param rdata: the rdata. The rdata+*offset is where the field is.
    405  * @param offset: the current position on input. The position is updated to
    406  *	be incremented with the length of rdata that was used.
    407  * @return false on failure.
    408  */
    409 static int
    410 print_certificate_type(struct buffer *output, size_t rdlength,
    411 	const uint8_t *rdata, uint16_t *offset)
    412 {
    413 	uint16_t id;
    414 	lookup_table_type* type;
    415 	if (rdlength < *offset || rdlength - *offset < 2)
    416 		return 0;
    417 	id = read_uint16(rdata + *offset);
    418 	type = lookup_by_id(dns_certificate_types, id);
    419 	if (type)
    420 		buffer_printf(output, "%s", type->name);
    421 	else
    422 		buffer_printf(output, "%u", (unsigned) id);
    423 	*offset += 2;
    424 	return 1;
    425 }
    426 
    427 /*
    428  * Print time field.
    429  * @param output: the string is output here.
    430  * @param rdlength: length of rdata.
    431  * @param rdata: the rdata. The rdata+*offset is where the field is.
    432  * @param offset: the current position on input. The position is updated to
    433  *	be incremented with the length of rdata that was used.
    434  * @return false on failure.
    435  */
    436 static int
    437 print_time(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
    438 	uint16_t *offset)
    439 {
    440 	time_t time;
    441 	struct tm tmbuf;
    442 	struct tm* tm;
    443 	char buf[15];
    444 
    445 	assert(rdlength >= *offset);
    446 	if (rdlength - *offset < 4)
    447 		return 0;
    448 	time = (time_t)read_uint32(rdata + *offset);
    449 	tm = gmtime_r(&time, &tmbuf);
    450 	if (!strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", tm))
    451 		return 0;
    452 	buffer_printf(output, "%s", buf);
    453 	*offset += 4;
    454 	return 1;
    455 }
    456 
    457 /*
    458  * Print base32 output for a b32 field length uint8_t, like for NSEC3.
    459  * @param output: the string is output here.
    460  * @param rdlength: length of rdata.
    461  * @param rdata: the rdata. The rdata+*offset is where the field is.
    462  * @param offset: the current position on input. The position is updated to
    463  *	be incremented with the length of rdata that was used.
    464  * @return false on failure.
    465  */
    466 static int
    467 print_base32(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
    468 	uint16_t *offset)
    469 {
    470 	size_t size;
    471 	int length;
    472 	if(rdlength - *offset == 0)
    473 		return 0;
    474 	size = rdata[*offset];
    475 	if (rdlength - ((size_t)*offset) < 1 + size)
    476 		return 0;
    477 
    478 	if (size == 0) {
    479 		buffer_write(output, "-", 1);
    480 		*offset += 1;
    481 		return 1;
    482 	}
    483 
    484 	buffer_reserve(output, size * 2 + 1);
    485 	length = b32_ntop(rdata + *offset + 1, size,
    486 			  (char *)buffer_current(output), size * 2);
    487 	if (length == -1)
    488 		return 0;
    489 	buffer_skip(output, length);
    490 	*offset += 1 + size;
    491 	return 1;
    492 }
    493 
    494 /*
    495  * Print base64 output for the remainder of rdata.
    496  * @param output: the string is output here.
    497  * @param rdlength: length of rdata.
    498  * @param rdata: the rdata. The rdata+*offset is where the field is.
    499  * @param offset: the current position on input. The position is updated to
    500  *	be incremented with the length of rdata that was used.
    501  * @return false on failure.
    502  */
    503 static int
    504 print_base64(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
    505 	uint16_t *offset)
    506 {
    507 	int length;
    508 	size_t size = rdlength - *offset;
    509 	if(size == 0) {
    510 		/* single zero represents empty buffer */
    511 		buffer_write(output, "0", 1);
    512 		return 1;
    513 	}
    514 	buffer_reserve(output, size * 2 + 1);
    515 	length = b64_ntop(rdata + *offset, size,
    516 			  (char *) buffer_current(output), size * 2);
    517 	if (length == -1)
    518 		return 0;
    519 	buffer_skip(output, length);
    520 	*offset += size;
    521 	return 1;
    522 }
    523 
    524 static void
    525 buffer_print_hex(buffer_type *output, const uint8_t *data, size_t size)
    526 {
    527 	static const char hexdigits[] = {
    528 		'0', '1', '2', '3', '4', '5', '6', '7',
    529 		'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
    530 	};
    531 	size_t i;
    532 
    533 	buffer_reserve(output, size * 2);
    534 	for (i = 0; i < size; ++i) {
    535 		uint8_t octet = *data++;
    536 		buffer_write_u8(output, hexdigits[octet >> 4]);
    537 		buffer_write_u8(output, hexdigits[octet & 0x0f]);
    538 	}
    539 }
    540 
    541 /*
    542  * Print base16 output for the remainder of rdata, in hex lowercase.
    543  * @param output: the string is output here.
    544  * @param rdlength: length of rdata.
    545  * @param rdata: the rdata. The rdata+*offset is where the field is.
    546  * @param offset: the current position on input. The position is updated to
    547  *	be incremented with the length of rdata that was used.
    548  * @return false on failure.
    549  */
    550 static int
    551 print_base16(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
    552 	uint16_t *offset)
    553 {
    554 	size_t size = rdlength - *offset;
    555 	if(size == 0) {
    556 		/* single zero represents empty buffer, such as CDS deletes */
    557 		buffer_write(output, "0", 1);
    558 		return 1;
    559 	} else {
    560 		buffer_print_hex(output, rdata+*offset, size);
    561 	}
    562 	*offset += size;
    563 	return 1;
    564 }
    565 
    566 /*
    567  * Print salt, for NSEC3, in hex lowercase.
    568  * @param output: the string is output here.
    569  * @param rdlength: length of rdata.
    570  * @param rdata: the rdata. The rdata+*offset is where the field is.
    571  * @param offset: the current position on input. The position is updated to
    572  *	be incremented with the length of rdata that was used.
    573  * @return false on failure.
    574  */
    575 static int
    576 print_salt(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
    577 	uint16_t *offset)
    578 {
    579 	uint8_t length;
    580 	assert(rdlength >= *offset);
    581 	if (rdlength - *offset == 0)
    582 		return 0;
    583 
    584 	length = rdata[*offset];
    585 	if (rdlength - *offset < 1 + length)
    586 		return 0;
    587 	if (!length)
    588 		/* NSEC3 salt hex can be empty */
    589 		buffer_printf(output, "-");
    590 	else
    591 		buffer_print_hex(output, rdata + *offset + 1, length);
    592 	*offset += 1 + (uint16_t)length;
    593 	return 1;
    594 }
    595 
    596 /* Return length of nsec type bitmap or -1 on wireformat error. offset is
    597  * moved +len. rdlength is the length of the rdata, offset is offset in it. */
    598 static inline int32_t
    599 skip_nsec(struct buffer* packet, uint16_t rdlength, uint16_t *offset)
    600 {
    601 	uint16_t length = 0;
    602 	uint8_t last_window = 0;
    603 
    604 	while (rdlength - *offset - length > 2) {
    605 		uint8_t window = buffer_read_u8(packet);
    606 		uint8_t blocks = buffer_read_u8(packet);
    607 		if (length > 0 && window <= last_window)
    608 			return -1;
    609 		if (!blocks || blocks > 32)
    610 			return -1;
    611 		if (rdlength - *offset - length < 2 + blocks)
    612 			return -1;
    613 		buffer_skip(packet, blocks);
    614 		length += 2 + blocks;
    615 		last_window = window;
    616 	}
    617 
    618 	*offset += length;
    619 	if (rdlength != *offset)
    620 		return -1;
    621 
    622 	return length;
    623 }
    624 
    625 /*
    626  * Print nsec type bitmap, for the remainder of rdata.
    627  * @param output: the string is output here.
    628  * @param rdlength: length of rdata.
    629  * @param rdata: the rdata. The rdata+*offset is where the field is.
    630  * @param offset: the current position on input. The position is updated to
    631  *	be incremented with the length of rdata that was used.
    632  * @return false on failure.
    633  */
    634 static int
    635 print_nsec_bitmap(struct buffer *output, uint16_t rdlength,
    636 	const uint8_t *rdata, uint16_t *offset)
    637 {
    638 	int insert_space = 0;
    639 
    640 	rdata += *offset;
    641 	while(rdlength - *offset > 0) {
    642 		uint8_t window, bitmap_size;
    643 		const uint8_t* bitmap;
    644 		int i;
    645 
    646 		if(rdlength - *offset < 2)
    647 			return 0;
    648 		window = rdata[0];
    649 		bitmap_size = rdata[1];
    650 		*offset += 2;
    651 
    652 		if(rdlength - *offset < bitmap_size)
    653 			return 0;
    654 
    655 		bitmap = rdata + 2;
    656 		rdata += 2;
    657 		for(i=0; i<((int)bitmap_size)*8; i++) {
    658 			if (get_bit(bitmap, i)) {
    659 				buffer_printf(output,
    660 					      "%s%s",
    661 					      insert_space ? " " : "",
    662 					      rrtype_to_string(
    663 						      window * 256 + i));
    664 				insert_space = 1;
    665 			}
    666 		}
    667 		rdata += bitmap_size;
    668 		*offset += bitmap_size;
    669 	}
    670 	return 1;
    671 }
    672 
    673 /* If an svcparam must have a value */
    674 static int
    675 svcparam_must_have_value(uint16_t svcparamkey)
    676 {
    677 	switch (svcparamkey) {
    678 	case SVCB_KEY_ALPN:
    679 	case SVCB_KEY_PORT:
    680 	case SVCB_KEY_IPV4HINT:
    681 	case SVCB_KEY_IPV6HINT:
    682 	case SVCB_KEY_MANDATORY:
    683 	case SVCB_KEY_DOHPATH:
    684 	case SVCB_KEY_TLS_SUPPORTED_GROUPS:
    685 		return 1;
    686 	default:
    687 		break;
    688 	}
    689 	return 0;
    690 }
    691 
    692 /* If an svcparam must not have a value */
    693 static int
    694 svcparam_must_not_have_value(uint16_t svcparamkey)
    695 {
    696 	switch (svcparamkey) {
    697 	case SVCB_KEY_NO_DEFAULT_ALPN:
    698 	case SVCB_KEY_OHTTP:
    699 		return 1;
    700 	default:
    701 		break;
    702 	}
    703 	return 0;
    704 };
    705 
    706 /*
    707  * Skip over the svcparams in the packet. Moves position.
    708  * @param packet: wire packet, position at rdata fields of svcparams.
    709  * @param rdlength: remaining rdata length in the packet.
    710  * @return 0 on wireformat error.
    711  */
    712 static inline int
    713 skip_svcparams(struct buffer *packet, uint16_t rdlength)
    714 {
    715 	unsigned pos = 0;
    716 	uint16_t key, count;
    717 	while(pos < rdlength) {
    718 		if(pos+4 > (unsigned)rdlength)
    719 			return 0;
    720 		if(!buffer_available(packet, 4))
    721 			return 0;
    722 		key = buffer_read_u16(packet);
    723 		count = buffer_read_u16(packet);
    724 		if(count == 0 && svcparam_must_have_value(key))
    725 			return 0;
    726 		if(count != 0 && svcparam_must_not_have_value(key))
    727 			return 0;
    728 		pos += 4;
    729 		if(pos+count > (unsigned)rdlength)
    730 			return 0;
    731 		if(!buffer_available(packet, count))
    732 			return 0;
    733 		buffer_skip(packet, count);
    734 		pos += count;
    735 	}
    736 	return 1;
    737 }
    738 
    739 /*
    740  * Print svcparamkey name to the buffer, or unknown as key<NUM>.
    741  * @param output: printed to string.
    742  * @param svcparamkey: the key to print.
    743  */
    744 static void
    745 buffer_print_svcparamkey(buffer_type *output, uint16_t svcparamkey)
    746 {
    747 	if (svcparamkey < sizeof(svcparams)/sizeof(svcparams[0]))
    748 		buffer_printf(output, "%s", svcparams[svcparamkey].name);
    749 	else
    750 		buffer_printf(output, "key%" PRIu16, svcparamkey);
    751 }
    752 
    753 static int
    754 print_svcparam_no_value(struct buffer *output, uint16_t svcparamkey,
    755 	const uint8_t* ATTR_UNUSED(data), uint16_t ATTR_UNUSED(datalen))
    756 {
    757 	buffer_print_svcparamkey(output, svcparamkey);
    758 	return 1;
    759 }
    760 
    761 static int
    762 print_svcparam_mandatory(struct buffer *output, uint16_t svcparamkey,
    763 	const uint8_t* data, uint16_t datalen)
    764 {
    765 	assert(datalen > 0); /* Guaranteed by svcparam_print */
    766 
    767 	if (datalen % sizeof(uint16_t))
    768 		return 0; /* wireformat error, val_len must be multiple of shorts */
    769 	buffer_print_svcparamkey(output, svcparamkey);
    770 	buffer_write_u8(output, '=');
    771 	buffer_print_svcparamkey(output, read_uint16(data));
    772 	data += 2;
    773 
    774 	while ((datalen -= sizeof(uint16_t))) {
    775 		buffer_write_u8(output, ',');
    776 		buffer_print_svcparamkey(output, read_uint16(data));
    777 		data += 2;
    778 	}
    779 
    780 	return 1;
    781 }
    782 
    783 static int
    784 print_svcparam_alpn(struct buffer *output, uint16_t svcparamkey,
    785 	const uint8_t* data, uint16_t datalen)
    786 {
    787 	uint8_t *dp = (void *)data;
    788 
    789 	assert(datalen > 0); /* Guaranteed by svcparam_print */
    790 
    791 	buffer_print_svcparamkey(output, svcparamkey);
    792 	buffer_write_u8(output, '=');
    793 	buffer_write_u8(output, '"');
    794 	while (datalen) {
    795 		uint8_t i, str_len = *dp++;
    796 
    797 		if (str_len > --datalen)
    798 			return 0;
    799 
    800 		for (i = 0; i < str_len; i++) {
    801 			if (dp[i] == '"' || dp[i] == '\\')
    802 				buffer_printf(output, "\\\\\\%c", dp[i]);
    803 
    804 			else if (dp[i] == ',')
    805 				buffer_printf(output, "\\\\%c", dp[i]);
    806 
    807 			else if (!isprint(dp[i]))
    808 				buffer_printf(output, "\\%03u", (unsigned) dp[i]);
    809 
    810 			else
    811 				buffer_write_u8(output, dp[i]);
    812 		}
    813 		dp += str_len;
    814 		if ((datalen -= str_len))
    815 			buffer_write_u8(output, ',');
    816 	}
    817 	buffer_write_u8(output, '"');
    818 	return 1;
    819 }
    820 
    821 static int
    822 print_svcparam_port(struct buffer *output, uint16_t svcparamkey,
    823 	const uint8_t* data, uint16_t datalen)
    824 {
    825 	if (datalen != 2)
    826 		return 0; /* wireformat error, a short is 2 bytes */
    827 	buffer_print_svcparamkey(output, svcparamkey);
    828 	buffer_printf(output, "=%d", (int)read_uint16(data));
    829 	return 1;
    830 }
    831 
    832 static int
    833 print_svcparam_ipv4hint(struct buffer *output, uint16_t svcparamkey,
    834 	const uint8_t* data, uint16_t datalen)
    835 {
    836 	char ip_str[INET_ADDRSTRLEN + 1];
    837 
    838 	assert(datalen > 0); /* Guaranteed by svcparam_print */
    839 
    840 	buffer_print_svcparamkey(output, svcparamkey);
    841 	if ((datalen % IP4ADDRLEN) == 0) {
    842 		if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL)
    843 			return 0; /* wireformat error, incorrect size or inet family */
    844 
    845 		buffer_printf(output, "=%s", ip_str);
    846 		data += IP4ADDRLEN;
    847 
    848 		while ((datalen -= IP4ADDRLEN) > 0) {
    849 			if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str))
    850 				== NULL)
    851 				return 0; /* wireformat error, incorrect size or inet family */
    852 
    853 			buffer_printf(output, ",%s", ip_str);
    854 			data += IP4ADDRLEN;
    855 		}
    856 		return 1;
    857 	}
    858 	return 0;
    859 }
    860 
    861 static int
    862 print_svcparam_ech(struct buffer *output, uint16_t svcparamkey,
    863 	const uint8_t* data, uint16_t datalen)
    864 {
    865 	int length;
    866 
    867 	buffer_print_svcparamkey(output, svcparamkey);
    868 	if(datalen == 0)
    869 		return 1;
    870 	buffer_write_u8(output, '=');
    871 
    872 	buffer_reserve(output, datalen * 2 + 1);
    873 	length = b64_ntop(data, datalen, (char*)buffer_current(output),
    874 		datalen * 2);
    875 	if (length > 0) {
    876 		buffer_skip(output, length);
    877 	}
    878 
    879 	return length != -1;
    880 }
    881 
    882 static int
    883 print_svcparam_ipv6hint(struct buffer *output, uint16_t svcparamkey,
    884 	const uint8_t* data, uint16_t datalen)
    885 {
    886 	char ip_str[INET6_ADDRSTRLEN + 1];
    887 
    888 	assert(datalen > 0); /* Guaranteed by svcparam_print */
    889 
    890 	buffer_print_svcparamkey(output, svcparamkey);
    891 	if ((datalen % IP6ADDRLEN) == 0) {
    892 		if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL)
    893 			return 0; /* wireformat error, incorrect size or inet family */
    894 
    895 		buffer_printf(output, "=%s", ip_str);
    896 		data += IP6ADDRLEN;
    897 
    898 		while ((datalen -= IP6ADDRLEN) > 0) {
    899 			if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str))
    900 				== NULL)
    901 				return 0; /* wireformat error, incorrect size or inet family */
    902 
    903 			buffer_printf(output, ",%s", ip_str);
    904 			data += IP6ADDRLEN;
    905 		}
    906 		return 1;
    907 	}
    908 	return 0;
    909 }
    910 
    911 static int
    912 print_svcparam_dohpath(struct buffer *output, uint16_t svcparamkey,
    913 	const uint8_t* data, uint16_t datalen)
    914 {
    915 	const uint8_t* dp = data;
    916 	unsigned i;
    917 
    918 	buffer_print_svcparamkey(output, svcparamkey);
    919 	buffer_write(output, "=\"", 2);
    920 	for (i = 0; i < datalen; i++) {
    921 		if (dp[i] == '"' || dp[i] == '\\')
    922 			buffer_printf(output, "\\%c", dp[i]);
    923 
    924 		else if (!isprint(dp[i]))
    925 			buffer_printf(output, "\\%03u", (unsigned) dp[i]);
    926 
    927 		else
    928 			buffer_write_u8(output, dp[i]);
    929 	}
    930 	buffer_write_u8(output, '"');
    931 	return 1;
    932 }
    933 
    934 static int
    935 print_svcparam_tls_supported_groups(struct buffer *output,
    936 	uint16_t svcparamkey, const uint8_t* data, uint16_t datalen)
    937 {
    938 	assert(datalen > 0); /* Guaranteed by svcparam_print */
    939 
    940 	if ((datalen % sizeof(uint16_t)) == 1)
    941 		return 0; /* A series of uint16_t is an even number of bytes */
    942 
    943 	buffer_print_svcparamkey(output, svcparamkey);
    944 	buffer_printf(output, "=%d", (int)read_uint16(data));
    945 	data += 2;
    946 	while ((datalen -= sizeof(uint16_t)) > 0) {
    947 		buffer_printf(output, ",%d", (int)read_uint16(data));
    948 		data += 2;
    949 	}
    950 	return 1;
    951 }
    952 
    953 /*
    954  * Print svcparam.
    955  * @param output: the string is output here.
    956  * @param rdlength: length of rdata.
    957  * @param rdata: the rdata. The rdata+*offset is where the field is.
    958  * @param offset: the current position on input. The position is updated to
    959  *	be incremented with the length of rdata that was used.
    960  * @return false on failure.
    961  */
    962 static int
    963 print_svcparam(struct buffer *output, uint16_t rdlength, const uint8_t *rdata,
    964 	uint16_t *offset)
    965 {
    966 	uint16_t key, length;
    967 	const uint8_t* dp;
    968 	unsigned i;
    969 
    970 	assert(rdlength >= *offset);
    971 	if (rdlength - *offset < 4)
    972 		return 0;
    973 
    974 	key = read_uint16(rdata + *offset);
    975 	length = read_uint16(rdata + *offset + 2);
    976 
    977 	if (rdlength - *offset < length + 4)
    978 		return 0; /* wireformat error */
    979 
    980 	if(length == 0 && svcparam_must_have_value(key))
    981 		return 0;
    982 	if(length != 0 && svcparam_must_not_have_value(key))
    983 		return 0;
    984 	if (key < sizeof(svcparams)/sizeof(svcparams[0])) {
    985 		if(!svcparams[key].print_rdata(output, key, rdata+*offset+4, length))
    986 			return 0;
    987 		*offset += length+4;
    988 		return 1;
    989 	}
    990 
    991 	buffer_printf(output, "key%" PRIu16, key);
    992 	if (!length) {
    993 		*offset += 4;
    994 		return 1;
    995 	}
    996 
    997 	buffer_write(output, "=\"", 2);
    998 	dp = rdata + *offset + 4;
    999 
   1000 	for (i = 0; i < length; i++) {
   1001 		if (dp[i] == '"' || dp[i] == '\\')
   1002 			buffer_printf(output, "\\%c", dp[i]);
   1003 
   1004 		else if (!isprint(dp[i]))
   1005 			buffer_printf(output, "\\%03u", (unsigned) dp[i]);
   1006 
   1007 		else
   1008 			buffer_write_u8(output, dp[i]);
   1009 	}
   1010 	buffer_write_u8(output, '"');
   1011 	*offset += length + 4;
   1012 	return 1;
   1013 }
   1014 
   1015 static inline int32_t
   1016 read_rdata(struct domain_table *domains, uint16_t rdlength,
   1017 	struct buffer *packet, struct rr **rr)
   1018 {
   1019 	if (buffer_remaining(packet) < rdlength)
   1020 		return MALFORMED;
   1021 	if (!(*rr = region_alloc(domains->region, sizeof(**rr) + rdlength)))
   1022 		return TRUNCATED;
   1023 	if(rdlength != 0)
   1024 		buffer_read(packet, (*rr)->rdata, rdlength);
   1025 	(*rr)->rdlength = rdlength;
   1026 	return rdlength;
   1027 }
   1028 
   1029 int32_t
   1030 read_generic_rdata(struct domain_table *domains, uint16_t rdlength,
   1031 	struct buffer *packet, struct rr **rr)
   1032 {
   1033 	return read_rdata(domains, rdlength, packet, rr);
   1034 }
   1035 
   1036 void
   1037 write_generic_rdata(struct query *query, const struct rr *rr)
   1038 {
   1039 	if(rr->rdlength != 0)
   1040 		buffer_write(query->packet, rr->rdata, rr->rdlength);
   1041 }
   1042 
   1043 int
   1044 print_generic_rdata(struct buffer *output, const struct rr *rr)
   1045 {
   1046 	const nsd_type_descriptor_type* descriptor =
   1047 		nsd_type_descriptor(rr->type);
   1048 	return print_unknown_rdata_field(output, descriptor, rr);
   1049 }
   1050 
   1051 int
   1052 lookup_rdata_field_entry(const nsd_type_descriptor_type* descriptor,
   1053 	size_t index, const rr_type* rr, uint16_t offset, uint16_t* field_len,
   1054 	struct domain** domain)
   1055 {
   1056 	const nsd_rdata_descriptor_type* field =
   1057 		&descriptor->rdata.fields[index];
   1058 	if(field->calculate_length) {
   1059 		/* Call field length function. */
   1060 		int32_t l = field->calculate_length(rr->rdlength, rr->rdata,
   1061 			offset, domain);
   1062 		if(l < 0)
   1063 			return 0;
   1064 		*field_len = l;
   1065 	} else if(field->length >= 0) {
   1066 		*field_len = field->length;
   1067 		*domain = NULL;
   1068 	} else {
   1069 		size_t dlen;
   1070 		int32_t flen;
   1071 		if(offset > rr->rdlength)
   1072 			return 0;
   1073 		/* Handle the specialized value cases. */
   1074 		switch(field->length) {
   1075 		case RDATA_COMPRESSED_DNAME:
   1076 		case RDATA_UNCOMPRESSED_DNAME:
   1077 			if(rr->rdlength - offset <
   1078 				(uint16_t)sizeof(void*))
   1079 				return 0;
   1080 			*field_len = sizeof(void*);
   1081 			memcpy(domain, rr->rdata+offset, sizeof(void*));
   1082 			break;
   1083 		case RDATA_LITERAL_DNAME:
   1084 			dlen = buf_dname_length(rr->rdata+offset,
   1085 				rr->rdlength-offset);
   1086 			if(dlen == 0)
   1087 				return 0;
   1088 			*field_len = dlen;
   1089 			*domain = NULL;
   1090 			break;
   1091 		case RDATA_STRING:
   1092 		case RDATA_BINARY:
   1093 			if(rr->rdlength - offset < 1)
   1094 				return 0;
   1095 			flen = (rr->rdata+offset)[0];
   1096 			*field_len = flen+1;
   1097 			*domain = NULL;
   1098 			break;
   1099 		case RDATA_IPSECGATEWAY:
   1100 		case RDATA_AMTRELAY_RELAY:
   1101 			return 0; /* Has a callback function. */
   1102 		case RDATA_REMAINDER:
   1103 			*field_len = rr->rdlength - offset;
   1104 			*domain = NULL;
   1105 			break;
   1106 		default:
   1107 			/* Unknown specialized value. */
   1108 			return 0;
   1109 		}
   1110 	}
   1111 	if(offset + *field_len > rr->rdlength)
   1112 		return 0; /* The field does not fit in the rdata. */
   1113 	return 1;
   1114 }
   1115 
   1116 int
   1117 lookup_rdata_field_entry_uncompressed_wire(
   1118 	const nsd_type_descriptor_type* descriptor, size_t index,
   1119 	const uint8_t* rdata, uint16_t rdlength, uint16_t offset,
   1120 	uint16_t* field_len, struct domain** domain)
   1121 {
   1122 	const nsd_rdata_descriptor_type* field =
   1123 		&descriptor->rdata.fields[index];
   1124 	if(field->calculate_length) {
   1125 		/* Call field length function. */
   1126 		int32_t l = field->calculate_length_uncompressed_wire(rdlength,
   1127 			rdata, offset, domain);
   1128 		if(l < 0)
   1129 			return 0;
   1130 		*field_len = l;
   1131 	} else if(field->length >= 0) {
   1132 		*field_len = field->length;
   1133 		*domain = NULL;
   1134 	} else {
   1135 		size_t dlen;
   1136 		int32_t flen;
   1137 		if(offset > rdlength)
   1138 			return 0;
   1139 		/* Handle the specialized value cases. */
   1140 		switch(field->length) {
   1141 		case RDATA_COMPRESSED_DNAME:
   1142 		case RDATA_UNCOMPRESSED_DNAME:
   1143 			/* In the case that the field type is of type dname,
   1144 			 * since this function deals with uncompressed
   1145 			 * wireformat in the rdata buffer, the dname is
   1146 			 * going to be there as an uncompressed wireformat
   1147 			 * dname, for RDATA_COMPRESSED_DNAME and
   1148 			 * RDATA_UNCOMPRESSED_DNAME. */
   1149 		case RDATA_LITERAL_DNAME:
   1150 			dlen = buf_dname_length(rdata+offset, rdlength-offset);
   1151 			if(dlen == 0)
   1152 				return 0;
   1153 			*field_len = dlen;
   1154 			*domain = NULL;
   1155 			break;
   1156 		case RDATA_STRING:
   1157 		case RDATA_BINARY:
   1158 			if(rdlength - offset < 1)
   1159 				return 0;
   1160 			flen = (rdata+offset)[0];
   1161 			*field_len = flen+1;
   1162 			*domain = NULL;
   1163 			break;
   1164 		case RDATA_IPSECGATEWAY:
   1165 		case RDATA_AMTRELAY_RELAY:
   1166 			return 0; /* Has a callback function. */
   1167 		case RDATA_REMAINDER:
   1168 			*field_len = rdlength - offset;
   1169 			*domain = NULL;
   1170 			break;
   1171 		default:
   1172 			/* Unknown specialized value. */
   1173 			return 0;
   1174 		}
   1175 	}
   1176 	if(offset + *field_len > rdlength)
   1177 		return 0; /* The field does not fit in the rdata. */
   1178 	return 1;
   1179 }
   1180 
   1181 int32_t
   1182 rr_calculate_uncompressed_rdata_length(const rr_type* rr)
   1183 {
   1184 	size_t i;
   1185 	const nsd_type_descriptor_type* descriptor =
   1186 		nsd_type_descriptor(rr->type);
   1187 	uint16_t offset = 0;
   1188 	int32_t result = 0;
   1189 	if(!descriptor->has_references)
   1190 		return rr->rdlength; /* It does not really validate the
   1191 			fields versus the rdlength. */
   1192 	for(i=0; i < descriptor->rdata.length; i++) {
   1193 		uint16_t field_len;
   1194 		struct domain* domain;
   1195 		if(rr->rdlength == offset &&
   1196 			descriptor->rdata.fields[i].is_optional)
   1197 			break; /* There are no more rdata fields. */
   1198 		if(!lookup_rdata_field_entry(descriptor, i, rr, offset,
   1199 			&field_len, &domain))
   1200 			return -1; /* malformed rdata buffer */
   1201 		if(domain != NULL) {
   1202 			/* Handle RDATA_COMPRESSED_DNAME and
   1203 			 * RDATA_UNCOMPRESSED_DNAME fields. */
   1204 			const struct dname* dname = domain_dname(domain);
   1205 			result += dname->name_size;
   1206 		} else {
   1207 			result += field_len;
   1208 		}
   1209 		offset += field_len;
   1210 	}
   1211 	return result;
   1212 }
   1213 
   1214 void
   1215 rr_write_uncompressed_rdata(const rr_type* rr, uint8_t* buf, size_t len)
   1216 {
   1217 	size_t i;
   1218 	const nsd_type_descriptor_type* descriptor =
   1219 		nsd_type_descriptor(rr->type);
   1220 	uint16_t offset = 0; /* The offset in rr->rdatas. */
   1221 	size_t pos = 0; /* The position in buf. */
   1222 	if(!descriptor->has_references) {
   1223 		/* It does not really validate the fields versus the
   1224 		 * rdlength. */
   1225 		if(rr->rdlength > len)
   1226 			return; /* buffer too small */
   1227 		memcpy(buf, rr->rdata, rr->rdlength);
   1228 		return;
   1229 	}
   1230 	for(i=0; i < descriptor->rdata.length; i++) {
   1231 		uint16_t field_len;
   1232 		struct domain* domain;
   1233 		if(rr->rdlength == offset &&
   1234 			descriptor->rdata.fields[i].is_optional)
   1235 			break; /* There are no more rdata fields. */
   1236 		if(!lookup_rdata_field_entry(descriptor, i, rr, offset,
   1237 			&field_len, &domain))
   1238 			return; /* malformed rdata buffer */
   1239 		if(domain != NULL) {
   1240 			/* Handle RDATA_COMPRESSED_DNAME and
   1241 			 * RDATA_UNCOMPRESSED_DNAME fields. */
   1242 			const struct dname* dname = domain_dname(domain);
   1243 			if(pos + dname->name_size > len)
   1244 				return; /* buffer too small */
   1245 			memcpy(buf+pos, dname_name(dname), dname->name_size);
   1246 			pos += dname->name_size;
   1247 		} else {
   1248 			if(pos + field_len > len)
   1249 				return; /* buffer too small */
   1250 			memcpy(buf+pos, rr->rdata+offset, field_len);
   1251 			pos += field_len;
   1252 		}
   1253 		offset += field_len;
   1254 	}
   1255 }
   1256 
   1257 int print_unknown_rdata_field(buffer_type *output,
   1258 	const nsd_type_descriptor_type *descriptor, const rr_type *rr)
   1259 {
   1260 	size_t i;
   1261 	int32_t size;
   1262 	uint16_t length = 0;
   1263 
   1264 	if(!descriptor->has_references) {
   1265 		/* There are no references to the domain table, the
   1266 		 * rdata can be printed literally. */
   1267 		buffer_printf(output, "\\# %lu ", (unsigned long)rr->rdlength);
   1268 		buffer_print_hex(output, rr->rdata, rr->rdlength);
   1269 		return 1;
   1270 	}
   1271 
   1272 	size = rr_calculate_uncompressed_rdata_length(rr);
   1273 	if(size < 0)
   1274 		return 0;
   1275 	buffer_printf(output, "\\# %lu ", (unsigned long) size);
   1276 
   1277 	for(i=0; i < descriptor->rdata.length; i++) {
   1278 		uint16_t field_len;
   1279 		struct domain* domain;
   1280 		const uint8_t* to_print;
   1281 		size_t to_print_len;
   1282 		if(rr->rdlength == length &&
   1283 			descriptor->rdata.fields[i].is_optional)
   1284 			break; /* There are no more rdata fields. */
   1285 		if(!lookup_rdata_field_entry(descriptor, i, rr, length,
   1286 			&field_len, &domain))
   1287 			return 0; /* malformed rdata buffer */
   1288 		if(domain != NULL) {
   1289 			/* Handle RDATA_COMPRESSED_DNAME and
   1290 			 * RDATA_UNCOMPRESSED_DNAME fields. */
   1291 			const struct dname* dname = domain_dname(domain);
   1292 			to_print = dname_name(dname);
   1293 			to_print_len = dname->name_size;
   1294 		} else {
   1295 			to_print = rr->rdata+length;
   1296 			to_print_len = field_len;
   1297 		}
   1298 		buffer_print_hex(output, to_print, to_print_len);
   1299 		length += field_len;
   1300 	}
   1301 	return 1;
   1302 }
   1303 
   1304 int print_unknown_rdata(buffer_type *output,
   1305 	const nsd_type_descriptor_type *descriptor, const rr_type *rr)
   1306 {
   1307 	buffer_printf(output, "\t");
   1308 	return print_unknown_rdata_field(output, descriptor, rr);
   1309 }
   1310 
   1311 int32_t
   1312 read_compressed_name_rdata(struct domain_table *domains, uint16_t rdlength,
   1313 	struct buffer *packet, struct rr **rr)
   1314 {
   1315 	struct domain *domain;
   1316 	struct dname_buffer dname;
   1317 	size_t size;
   1318 	const size_t mark = buffer_position(packet);
   1319 
   1320 	if (!dname_make_from_packet_buffered(&dname, packet, 1, 1) ||
   1321 	    rdlength != buffer_position(packet) - mark)
   1322 		return MALFORMED;
   1323 	size = sizeof(**rr) + sizeof(void*);
   1324 	if (!(*rr = region_alloc(domains->region, size)))
   1325 		return TRUNCATED;
   1326 	domain = domain_table_insert(domains, (void*)&dname);
   1327 	domain->usage++;
   1328 	memcpy((*rr)->rdata, &domain, sizeof(void*));
   1329 	(*rr)->rdlength = sizeof(void*);
   1330 	return rdlength;
   1331 }
   1332 
   1333 int32_t
   1334 read_uncompressed_name_rdata(struct domain_table *domains, uint16_t rdlength,
   1335 	struct buffer *packet, struct rr **rr)
   1336 {
   1337 	struct domain *domain;
   1338 	struct dname_buffer dname;
   1339 	size_t size;
   1340 	const size_t mark = buffer_position(packet);
   1341 
   1342 	if (!dname_make_from_packet_buffered(&dname, packet,
   1343 		1 /* Lenient, allows pointers. */, 1) ||
   1344 		rdlength != buffer_position(packet)-mark)
   1345 		return MALFORMED;
   1346 	size = sizeof(**rr) + sizeof(void*);
   1347 	if (!(*rr = region_alloc(domains->region, size)))
   1348 		return TRUNCATED;
   1349 	domain = domain_table_insert(domains, (void*)&dname);
   1350 	domain->usage++;
   1351 	memcpy((*rr)->rdata, &domain, sizeof(void*));
   1352 	(*rr)->rdlength = sizeof(void*);
   1353 	return rdlength;
   1354 }
   1355 
   1356 static void
   1357 encode_dname(query_type *q, domain_type *domain)
   1358 {
   1359 	while (domain->parent && query_get_dname_offset(q, domain) == 0) {
   1360 		query_put_dname_offset(q, domain, buffer_position(q->packet));
   1361 		DEBUG(DEBUG_NAME_COMPRESSION, 2,
   1362 		      (LOG_INFO, "dname: %s, number: %lu, offset: %u\n",
   1363 		       domain_to_string(domain),
   1364 		       (unsigned long) domain->number,
   1365 		       query_get_dname_offset(q, domain)));
   1366 		buffer_write(q->packet, dname_name(domain_dname(domain)),
   1367 			     label_length(dname_name(domain_dname(domain))) + 1U);
   1368 		domain = domain->parent;
   1369 	}
   1370 	if (domain->parent) {
   1371 		DEBUG(DEBUG_NAME_COMPRESSION, 2,
   1372 		      (LOG_INFO, "dname: %s, number: %lu, pointer: %u\n",
   1373 		       domain_to_string(domain),
   1374 		       (unsigned long) domain->number,
   1375 		       query_get_dname_offset(q, domain)));
   1376 		assert(query_get_dname_offset(q, domain) <= MAX_COMPRESSION_OFFSET);
   1377 		buffer_write_u16(q->packet,
   1378 				 0xc000 | query_get_dname_offset(q, domain));
   1379 	} else {
   1380 		buffer_write_u8(q->packet, 0);
   1381 	}
   1382 }
   1383 
   1384 void
   1385 write_compressed_name_rdata(struct query *query, const struct rr *rr)
   1386 {
   1387 	struct domain *domain;
   1388 	assert(rr->rdlength == sizeof(void*));
   1389 	memcpy(&domain, rr->rdata, sizeof(void*));
   1390 	encode_dname(query, domain);
   1391 }
   1392 
   1393 void
   1394 write_uncompressed_name_rdata(struct query *query, const struct rr *rr)
   1395 {
   1396 	const struct dname *dname;
   1397 	struct domain *domain;
   1398 	assert(rr->rdlength >= sizeof(void*));
   1399 	memcpy(&domain, rr->rdata, sizeof(void*));
   1400 	dname = domain_dname(domain);
   1401 	buffer_write(query->packet, dname_name(dname), dname->name_size);
   1402 }
   1403 
   1404 int
   1405 print_name_rdata(struct buffer *output, const struct rr *rr)
   1406 {
   1407 	uint16_t length = 0;
   1408 	assert(rr->rdlength == sizeof(void*));
   1409 	/* This prints a reference to a name stored as a pointer. */
   1410 	return print_domain(output, rr->rdlength, rr->rdata, &length);
   1411 }
   1412 
   1413 int32_t
   1414 read_a_rdata(struct domain_table *domains, uint16_t rdlength,
   1415 	struct buffer *packet, struct rr **rr)
   1416 {
   1417 	if (rdlength != 4)
   1418 		return MALFORMED;
   1419 	return read_rdata(domains, rdlength, packet, rr);
   1420 }
   1421 
   1422 int
   1423 print_a_rdata(struct buffer *output, const struct rr *rr)
   1424 {
   1425 	uint16_t length = 0;
   1426 	assert(rr->rdlength == 4);
   1427 	return print_ip4(output, rr->rdlength, rr->rdata, &length);
   1428 }
   1429 
   1430 int32_t
   1431 read_soa_rdata(struct domain_table *domains, uint16_t rdlength,
   1432 	struct buffer *packet, struct rr **rr)
   1433 {
   1434 	struct domain *primary_domain, *mailbox_domain;
   1435 	struct dname_buffer primary, mailbox;
   1436 	size_t size;
   1437 
   1438 	/* domain + domain + uint32 + uint32 + uint32 + uint32 + uint32 */
   1439 	const size_t mark = buffer_position(packet);
   1440 	if (!dname_make_from_packet_buffered(&primary, packet, 1, 1) ||
   1441 	    !dname_make_from_packet_buffered(&mailbox, packet, 1, 1) ||
   1442 	    rdlength != (buffer_position(packet) - mark) + 20)
   1443 		return MALFORMED;
   1444 
   1445 	size = sizeof(**rr) + 2 * sizeof(void*) + 20;
   1446 	if (!(*rr = region_alloc(domains->region, size)))
   1447 		return TRUNCATED;
   1448 	primary_domain = domain_table_insert(domains, (void*)&primary);
   1449 	primary_domain->usage++;
   1450 	mailbox_domain = domain_table_insert(domains, (void*)&mailbox);
   1451 	mailbox_domain->usage++;
   1452 
   1453 	memcpy((*rr)->rdata, &primary_domain, sizeof(void*));
   1454 	memcpy((*rr)->rdata + sizeof(void*), &mailbox_domain, sizeof(void*));
   1455 	buffer_read(packet, (*rr)->rdata + 2 * sizeof(void*), 20);
   1456 	(*rr)->rdlength = 2 * sizeof(void*) + 20;
   1457 	return rdlength;
   1458 }
   1459 
   1460 void
   1461 write_soa_rdata(struct query *query, const struct rr *rr)
   1462 {
   1463 	struct domain *primary, *mailbox;
   1464 	/* domain + domain + uint32 + uint32 + uint32 + uint32 + uint32 */
   1465 	assert(rr->rdlength == 2 * sizeof(void*) + 20);
   1466 	memcpy(&primary, rr->rdata, sizeof(void*));
   1467 	memcpy(&mailbox, rr->rdata + sizeof(void*), sizeof(void*));
   1468 	encode_dname(query, primary);
   1469 	encode_dname(query, mailbox);
   1470 	buffer_write(query->packet, rr->rdata + (2 * sizeof(void*)), 20);
   1471 }
   1472 
   1473 int
   1474 print_soa_rdata(struct buffer *output, const struct rr *rr)
   1475 {
   1476 	uint16_t length = 0;
   1477 	uint32_t serial, refresh, retry, expire, minimum;
   1478 	assert(rr->rdlength == 2 * sizeof(void*) + 20);
   1479 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   1480 		return 0;
   1481 	buffer_printf(output, " ");
   1482 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   1483 		return 0;
   1484 
   1485 	assert(length == 2 * sizeof(void*));
   1486 	serial = read_uint32(rr->rdata + length);
   1487 	refresh = read_uint32(rr->rdata + length + 4);
   1488 	retry = read_uint32(rr->rdata + length + 8);
   1489 	expire = read_uint32(rr->rdata + length + 12);
   1490 	minimum = read_uint32(rr->rdata + length + 16);
   1491 
   1492 	buffer_printf(
   1493 		output, " %" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32,
   1494 		serial, refresh, retry, expire, minimum);
   1495 	return 1;
   1496 }
   1497 
   1498 int
   1499 print_soa_rdata_twoline(struct buffer *output, const struct rr *rr)
   1500 {
   1501 	uint16_t length = 0;
   1502 	uint32_t serial, refresh, retry, expire, minimum;
   1503 	assert(rr->rdlength == 2 * sizeof(void*) + 20);
   1504 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   1505 		return 0;
   1506 	buffer_printf(output, " ");
   1507 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   1508 		return 0;
   1509 
   1510 	assert(length == 2 * sizeof(void*));
   1511 	serial = read_uint32(rr->rdata + length);
   1512 	refresh = read_uint32(rr->rdata + length + 4);
   1513 	retry = read_uint32(rr->rdata + length + 8);
   1514 	expire = read_uint32(rr->rdata + length + 12);
   1515 	minimum = read_uint32(rr->rdata + length + 16);
   1516 
   1517 	buffer_printf(
   1518 		output, " (\n\t\t%" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 " )",
   1519 		serial, refresh, retry, expire, minimum);
   1520 	return 1;
   1521 }
   1522 
   1523 int32_t
   1524 read_wks_rdata(struct domain_table *domains, uint16_t rdlength,
   1525 	struct buffer *packet, struct rr **rr)
   1526 {
   1527 	if (rdlength < 5)
   1528 		return MALFORMED;
   1529 	return read_rdata(domains, rdlength, packet, rr);
   1530 }
   1531 
   1532 /*
   1533  * Print protocol and service numbers rather than names for Well-Know Services
   1534  * (WKS) RRs. WKS RRs are deprecated, though not technically, and should not
   1535  * be used. The parser supports tcp/udp for protocols and a small subset of
   1536  * services because getprotobyname and/or getservbyname are marked MT-Unsafe
   1537  * and locale. getprotobyname_r and getservbyname_r exist on some platforms,
   1538  * but are still marked locale (meaning the locale object is used without
   1539  * synchonization, which is a problem for a library). Failure to load a zone
   1540  * on a primary server because of an unknown protocol or service name is
   1541  * acceptable as the operator can opt to use the numeric value. Failure to
   1542  * load a zone on a secondary server is problematic because "unsupported"
   1543  * protocols and services might be written. Print the numeric value for
   1544  * maximum compatibility.
   1545  *
   1546  * (see simdzone/generic/wks.h for details).
   1547  */
   1548 int
   1549 print_wks_rdata(struct buffer *output, const struct rr *rr)
   1550 {
   1551 	uint16_t length = 0;
   1552 	uint8_t protocol;
   1553 	int bits;
   1554 	const uint8_t* bitmap;
   1555 
   1556 	if(rr->rdlength < 5)
   1557 		return 0;
   1558 	if (!print_ip4(output, rr->rdlength, rr->rdata, &length))
   1559 		return 0;
   1560 
   1561 	buffer_printf(output, " ");
   1562 	protocol = rr->rdata[4];
   1563 	if(protocol == 6)
   1564 		buffer_printf(output, "tcp");
   1565 	else if(protocol == 17)
   1566 		buffer_printf(output, "udp");
   1567 	else
   1568 		buffer_printf(output, "%" PRIu8, protocol);
   1569 
   1570 	bits = (rr->rdlength - 5) * 8;
   1571 	bitmap = rr->rdata + 5;
   1572 	for (int service = 0; service < bits; service++) {
   1573 		if (get_bit(bitmap, service))
   1574 			buffer_printf(output, " %d", service);
   1575 	}
   1576 	return 1;
   1577 }
   1578 
   1579 int32_t
   1580 read_hinfo_rdata(struct domain_table *domains, uint16_t rdlength,
   1581 	struct buffer *packet, struct rr **rr)
   1582 {
   1583 	uint16_t length = 0;
   1584 	const size_t mark = buffer_position(packet);
   1585 
   1586 	if(!buffer_available(packet, rdlength))
   1587 		return MALFORMED;
   1588 	if (skip_string(packet, rdlength, &length) < 0
   1589 	 || skip_string(packet, rdlength, &length) < 0
   1590 	 || rdlength != length)
   1591 		return MALFORMED;
   1592 	buffer_set_position(packet, mark);
   1593 	return read_rdata(domains, rdlength, packet, rr);
   1594 }
   1595 
   1596 int
   1597 print_hinfo_rdata(struct buffer *output, const struct rr *rr)
   1598 {
   1599 	uint16_t length = 0;
   1600 	if (!print_string(output, rr->rdlength, rr->rdata, &length))
   1601 		return 0;
   1602 	buffer_printf(output, " ");
   1603 	if (!print_string(output, rr->rdlength, rr->rdata, &length))
   1604 		return 0;
   1605 	if(rr->rdlength != length)
   1606 		return 0;
   1607 	return 1;
   1608 }
   1609 
   1610 int32_t
   1611 read_minfo_rdata(struct domain_table *domains, uint16_t rdlength,
   1612 	struct buffer *packet, struct rr **rr)
   1613 {
   1614 	struct domain *rmailbx_domain, *emailbx_domain;
   1615 	struct dname_buffer rmailbx, emailbx;
   1616 	size_t size;
   1617 	const size_t mark = buffer_position(packet);
   1618 
   1619 	if (buffer_remaining(packet) < rdlength ||
   1620 	    !dname_make_from_packet_buffered(&rmailbx, packet, 1, 1) ||
   1621 	    !dname_make_from_packet_buffered(&emailbx, packet, 1, 1) ||
   1622 	    rdlength != buffer_position(packet)-mark)
   1623 		return MALFORMED;
   1624 	size = sizeof(**rr) + 2 * sizeof(void*);
   1625 	if (!(*rr = region_alloc(domains->region, size)))
   1626 		return TRUNCATED;
   1627 	rmailbx_domain = domain_table_insert(domains, (void*)&rmailbx);
   1628 	rmailbx_domain->usage++;
   1629 	emailbx_domain = domain_table_insert(domains, (void*)&emailbx);
   1630 	emailbx_domain->usage++;
   1631 	memcpy((*rr)->rdata, &rmailbx_domain, sizeof(void*));
   1632 	memcpy((*rr)->rdata + sizeof(void*), &emailbx_domain, sizeof(void*));
   1633 	(*rr)->rdlength = 2 * sizeof(void*);
   1634 	return rdlength;
   1635 }
   1636 
   1637 void
   1638 write_minfo_rdata(struct query *query, const struct rr *rr)
   1639 {
   1640 	struct domain *rmailbx, *emailbx;
   1641 	assert(rr->rdlength == 2 * sizeof(void*));
   1642 	memcpy(&rmailbx, rr->rdata, sizeof(void*));
   1643 	memcpy(&emailbx, rr->rdata + sizeof(void*), sizeof(void*));
   1644 	encode_dname(query, rmailbx);
   1645 	encode_dname(query, emailbx);
   1646 }
   1647 
   1648 int
   1649 print_minfo_rdata(struct buffer *output, const struct rr *rr)
   1650 {
   1651 	uint16_t length = 0;
   1652 	assert(rr->rdlength == 2 * sizeof(void*));
   1653 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   1654 		return 0;
   1655 	buffer_printf(output, " ");
   1656 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   1657 		return 0;
   1658 	assert(rr->rdlength == length);
   1659 	return 1;
   1660 }
   1661 
   1662 int32_t
   1663 read_mx_rdata(struct domain_table *domains, uint16_t rdlength,
   1664 	struct buffer *packet, struct rr **rr)
   1665 {
   1666 	struct domain *domain;
   1667 	struct dname_buffer exchange;
   1668 	size_t size;
   1669 
   1670 	/* short + name */
   1671 	const size_t mark = buffer_position(packet);
   1672 	if (buffer_remaining(packet) < rdlength || rdlength < 2)
   1673 		return MALFORMED;
   1674 	buffer_skip(packet, 2);
   1675 	if (!dname_make_from_packet_buffered(&exchange, packet, 1, 1))
   1676 		return MALFORMED;
   1677 	if (rdlength != buffer_position(packet)-mark)
   1678 		return MALFORMED;
   1679 	size = sizeof(**rr) + 2 + sizeof(void*);
   1680 	if (!(*rr = region_alloc(domains->region, size)))
   1681 		return -1;
   1682 	domain = domain_table_insert(domains, (void*)&exchange);
   1683 	domain->usage++;
   1684 	buffer_read_at(packet, mark, (*rr)->rdata, 2);
   1685 	memcpy((*rr)->rdata + 2, &domain, sizeof(void*));
   1686 	(*rr)->rdlength = 2 + sizeof(void*);
   1687 	return rdlength;
   1688 }
   1689 
   1690 void
   1691 write_mx_rdata(struct query *query, const struct rr *rr)
   1692 {
   1693 	struct domain *domain;
   1694 	assert(rr->rdlength == 2 + sizeof(void*));
   1695 	memcpy(&domain, rr->rdata + 2, sizeof(void*));
   1696 	buffer_write(query->packet, rr->rdata, 2);
   1697 	encode_dname(query, domain);
   1698 }
   1699 
   1700 int
   1701 print_mx_rdata(struct buffer *output, const struct rr *rr)
   1702 {
   1703 	uint16_t length = 2;
   1704 	assert(rr->rdlength > length);
   1705 	buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
   1706 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   1707 		return 0;
   1708 	assert(rr->rdlength == length);
   1709 	return 1;
   1710 }
   1711 
   1712 int32_t
   1713 read_txt_rdata(struct domain_table *owners, uint16_t rdlength,
   1714 	struct buffer *packet, struct rr **rr)
   1715 {
   1716 	uint16_t length = 0;
   1717 	const size_t mark = buffer_position(packet);
   1718 	if(!buffer_available(packet, rdlength))
   1719 		return MALFORMED;
   1720 	if (skip_strings(packet, rdlength, &length) < 0 || rdlength != length)
   1721 		return MALFORMED;
   1722 	buffer_set_position(packet, mark);
   1723 	return read_rdata(owners, rdlength, packet, rr);
   1724 }
   1725 
   1726 int
   1727 print_txt_rdata(struct buffer *output, const struct rr *rr)
   1728 {
   1729 	uint16_t length = 0;
   1730 	if (length < rr->rdlength) {
   1731 		if (!print_string(output, rr->rdlength, rr->rdata, &length))
   1732 			return 0;
   1733 		while (length < rr->rdlength) {
   1734 			buffer_printf(output, " ");
   1735 			if (!print_string(output, rr->rdlength, rr->rdata,
   1736 				&length))
   1737 				return 0;
   1738 		}
   1739 	}
   1740 	return 1;
   1741 }
   1742 
   1743 int32_t
   1744 read_rp_rdata(struct domain_table *domains, uint16_t rdlength,
   1745 	struct buffer *packet, struct rr **rr)
   1746 {
   1747 	struct domain *mbox_domain, *txt_domain;
   1748 	struct dname_buffer mbox, txt;
   1749 	size_t size;
   1750 	const size_t mark = buffer_position(packet);
   1751 
   1752 	if (buffer_remaining(packet) < rdlength ||
   1753 	    !dname_make_from_packet_buffered(&mbox, packet, 1 /*lenient*/, 1) ||
   1754 	    !dname_make_from_packet_buffered(&txt, packet, 1 /*lenient*/, 1) ||
   1755 	    rdlength != buffer_position(packet)-mark)
   1756 		return MALFORMED;
   1757 	size = sizeof(**rr) + 2 * sizeof(void*);
   1758 	if (!(*rr = region_alloc(domains->region, size)))
   1759 		return TRUNCATED;
   1760 	mbox_domain = domain_table_insert(domains, (void*)&mbox);
   1761 	mbox_domain->usage++;
   1762 	txt_domain = domain_table_insert(domains, (void*)&txt);
   1763 	txt_domain->usage++;
   1764 	memcpy((*rr)->rdata, &mbox_domain, sizeof(void*));
   1765 	memcpy((*rr)->rdata + sizeof(void*), &txt_domain, sizeof(void*));
   1766 	(*rr)->rdlength = 2 * sizeof(void*);
   1767 	return rdlength;
   1768 }
   1769 
   1770 void
   1771 write_rp_rdata(struct query *query, const struct rr *rr)
   1772 {
   1773 	struct domain *mbox_domain, *txt_domain;
   1774 	const struct dname *mbox, *txt;
   1775 
   1776 	assert(rr->rdlength == 2 * sizeof(void*));
   1777 	memcpy(&mbox_domain, rr->rdata, sizeof(void*));
   1778 	memcpy(&txt_domain, rr->rdata + sizeof(void*), sizeof(void*));
   1779 	mbox = domain_dname(mbox_domain);
   1780 	txt = domain_dname(txt_domain);
   1781 	buffer_write(query->packet, dname_name(mbox), mbox->name_size);
   1782 	buffer_write(query->packet, dname_name(txt), txt->name_size);
   1783 }
   1784 
   1785 int
   1786 print_rp_rdata(struct buffer *output, const struct rr *rr)
   1787 {
   1788 	uint16_t length = 0;
   1789 	if(!print_domain(output, rr->rdlength, rr->rdata, &length))
   1790 		return 0;
   1791 	buffer_printf(output, " ");
   1792 	if(!print_domain(output, rr->rdlength, rr->rdata, &length))
   1793 		return 0;
   1794 	assert(rr->rdlength == length);
   1795 	return 1;
   1796 }
   1797 
   1798 int32_t
   1799 read_afsdb_rdata(struct domain_table *domains, uint16_t rdlength,
   1800 	struct buffer *packet, struct rr **rr)
   1801 {
   1802 	struct domain *domain;
   1803 	struct dname_buffer hostname;
   1804 	size_t size;
   1805 	/* short + uncompressed name */
   1806 	const size_t mark = buffer_position(packet);
   1807 
   1808 	if (buffer_remaining(packet) < rdlength || rdlength < 2)
   1809 		return MALFORMED;
   1810 	buffer_skip(packet, 2);
   1811 	if (!dname_make_from_packet_buffered(&hostname, packet,
   1812 		1 /*lenient*/, 1) ||
   1813 	    rdlength != buffer_position(packet)-mark)
   1814 		return MALFORMED;
   1815 	size = sizeof(**rr) + 2 + sizeof(void*);
   1816 	if (!(*rr = region_alloc(domains->region, size)))
   1817 		return TRUNCATED;
   1818 	domain = domain_table_insert(domains, (void*)&hostname);
   1819 	domain->usage++;
   1820 	buffer_read_at(packet, mark, (*rr)->rdata, 2);
   1821 	memcpy((*rr)->rdata + 2, &domain, sizeof(void*));
   1822 	(*rr)->rdlength = 2 + sizeof(void*);
   1823 	return rdlength;
   1824 }
   1825 
   1826 void
   1827 write_afsdb_rdata(struct query *query, const struct rr *rr)
   1828 {
   1829 	struct domain *domain;
   1830 	const struct dname *dname;
   1831 
   1832 	assert(rr->rdlength == 2 + sizeof(void*));
   1833 	memcpy(&domain, rr->rdata + 2, sizeof(void*));
   1834 	dname = domain_dname(domain);
   1835 	buffer_write(query->packet, rr->rdata, 2);
   1836 	buffer_write(query->packet, dname_name(dname), dname->name_size);
   1837 }
   1838 
   1839 int
   1840 print_afsdb_rdata(struct buffer *output, const struct rr *rr)
   1841 {
   1842 	uint16_t subtype, length=2;
   1843 	assert(rr->rdlength == 2 + sizeof(void*));
   1844 	subtype = read_uint16(rr->rdata);
   1845 	buffer_printf(output, "%" PRIu16 " ", subtype);
   1846 	if(!print_domain(output, rr->rdlength, rr->rdata, &length))
   1847 		return 0;
   1848 	return 1;
   1849 }
   1850 
   1851 int32_t
   1852 read_x25_rdata(struct domain_table *domains, uint16_t rdlength,
   1853 	struct buffer *packet, struct rr **rr)
   1854 {
   1855 	uint16_t length = 0;
   1856 	const size_t mark = buffer_position(packet);
   1857 	if(!buffer_available(packet, rdlength))
   1858 		return MALFORMED;
   1859 	if (skip_string(packet, rdlength, &length) < 0 || rdlength != length)
   1860 		return MALFORMED;
   1861 	buffer_set_position(packet, mark);
   1862 	return read_rdata(domains, rdlength, packet, rr);
   1863 }
   1864 
   1865 int
   1866 print_x25_rdata(struct buffer *output, const struct rr *rr)
   1867 {
   1868 	uint16_t length = 0;
   1869 	if (!print_string(output, rr->rdlength, rr->rdata, &length))
   1870 		return 0;
   1871 	if(rr->rdlength != length)
   1872 		return 0;
   1873 	return 1;
   1874 }
   1875 
   1876 int32_t
   1877 read_isdn_rdata(struct domain_table *domains, uint16_t rdlength,
   1878 	struct buffer *packet, struct rr **rr)
   1879 {
   1880 	uint16_t length = 0;
   1881 	const size_t mark = buffer_position(packet);
   1882 
   1883 	if(!buffer_available(packet, rdlength))
   1884 		return MALFORMED;
   1885 	if (skip_string(packet, rdlength, &length) < 0)
   1886 		return MALFORMED;
   1887 	if(rdlength > length) {
   1888 		/* Optional subaddress field is present. */
   1889 		if (skip_string(packet, rdlength, &length) < 0
   1890 		 || rdlength != length)
   1891 			return MALFORMED;
   1892 	}
   1893 	buffer_set_position(packet, mark);
   1894 	return read_rdata(domains, rdlength, packet, rr);
   1895 }
   1896 
   1897 int
   1898 print_isdn_rdata(struct buffer *output, const struct rr *rr)
   1899 {
   1900 	uint16_t length = 0;
   1901 	if (!print_string(output, rr->rdlength, rr->rdata, &length))
   1902 		return 0;
   1903 	if(rr->rdlength > length) {
   1904 		/* Optional subaddress field is present. */
   1905 		buffer_printf(output, " ");
   1906 		if (!print_string(output, rr->rdlength, rr->rdata, &length))
   1907 			return 0;
   1908 	}
   1909 	if(rr->rdlength != length)
   1910 		return 0;
   1911 	return 1;
   1912 }
   1913 
   1914 int32_t
   1915 read_rt_rdata(struct domain_table *domains, uint16_t rdlength,
   1916 	struct buffer *packet, struct rr **rr)
   1917 {
   1918 	struct domain *domain;
   1919 	struct dname_buffer dname;
   1920 	size_t size;
   1921 	const size_t mark = buffer_position(packet);
   1922 
   1923 	if(!buffer_available(packet, rdlength))
   1924 		return MALFORMED;
   1925 	if (rdlength < 2)
   1926 		return MALFORMED;
   1927 	buffer_skip(packet, 2);
   1928 	if (!dname_make_from_packet_buffered(&dname, packet, 1 /*lenient*/, 1))
   1929 		return MALFORMED;
   1930 	if (rdlength != buffer_position(packet)-mark)
   1931 		return MALFORMED;
   1932 	size = sizeof(**rr) + 2 + sizeof(void*);
   1933 	if (!(*rr = region_alloc(domains->region, size)))
   1934 		return -1;
   1935 	domain = domain_table_insert(domains, (void*)&dname);
   1936 	domain->usage++;
   1937 	buffer_read_at(packet, mark, (*rr)->rdata, 2);
   1938 	memcpy((*rr)->rdata + 2, &domain, sizeof(void*));
   1939 	(*rr)->rdlength = 2 + sizeof(void*);
   1940 	return rdlength;
   1941 }
   1942 
   1943 void
   1944 write_rt_rdata(struct query *query, const struct rr *rr)
   1945 {
   1946 	struct domain *domain;
   1947 	const struct dname *dname;
   1948 
   1949 	assert(rr->rdlength == 2 + sizeof(void*));
   1950 	memcpy(&domain, rr->rdata + 2, sizeof(void*));
   1951 	dname = domain_dname(domain);
   1952 	buffer_write(query->packet, rr->rdata, 2);
   1953 	buffer_write(query->packet, dname_name(dname), dname->name_size);
   1954 }
   1955 
   1956 int
   1957 print_nsap_rdata(struct buffer *output, const struct rr *rr)
   1958 {
   1959 	buffer_printf(output, "0x");
   1960 	buffer_print_hex(output, rr->rdata, rr->rdlength);
   1961 	return 1;
   1962 }
   1963 
   1964 int
   1965 print_nsap_ptr_rdata(struct buffer *output, const struct rr *rr)
   1966 {
   1967 	uint16_t length = 0;
   1968 	if(!print_unquoted(output, rr->rdlength, rr->rdata, &length))
   1969 		return 0;
   1970 	if(rr->rdlength != length)
   1971 		return 0;
   1972 	return 1;
   1973 }
   1974 
   1975 int
   1976 print_key_rdata(struct buffer *output, const struct rr *rr)
   1977 {
   1978 	uint16_t length = 4;
   1979 	if(rr->rdlength < length)
   1980 		return 0;
   1981 	buffer_printf(
   1982 		output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ",
   1983 		read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]);
   1984 	if (!print_base64(output, rr->rdlength, rr->rdata, &length))
   1985 		return 0;
   1986 	if(rr->rdlength != length)
   1987 		return 0;
   1988 	return 1;
   1989 }
   1990 
   1991 int32_t
   1992 read_px_rdata(struct domain_table *domains, uint16_t rdlength,
   1993 	struct buffer *packet, struct rr **rr)
   1994 {
   1995 	struct domain *map822_domain, *mapx400_domain;
   1996 	struct dname_buffer map822, mapx400;
   1997 	size_t size;
   1998 	const size_t mark = buffer_position(packet);
   1999 
   2000 	/* short + uncompressed name + uncompressed name */
   2001 	if (buffer_remaining(packet) < rdlength ||
   2002 	    rdlength < 2)
   2003 		return MALFORMED;
   2004 	buffer_skip(packet, 2);
   2005 	if(!dname_make_from_packet_buffered(&map822, packet,
   2006 		1 /*lenient*/, 1) ||
   2007 	   !dname_make_from_packet_buffered(&mapx400, packet,
   2008 		1 /*lenient*/, 1) ||
   2009 	   rdlength != buffer_position(packet) - mark)
   2010 		return MALFORMED;
   2011 
   2012 	size = sizeof(**rr) + 2 + 2*sizeof(void*);
   2013 	if (!(*rr = region_alloc(domains->region, size)))
   2014 		return TRUNCATED;
   2015 	map822_domain = domain_table_insert(domains, (void*)&map822);
   2016 	map822_domain->usage++;
   2017 	mapx400_domain = domain_table_insert(domains, (void*)&mapx400);
   2018 	mapx400_domain->usage++;
   2019 
   2020 	buffer_read_at(packet, mark, (*rr)->rdata, 2);
   2021 	memcpy((*rr)->rdata+2, &map822_domain, sizeof(void*));
   2022 	memcpy((*rr)->rdata+2+sizeof(void*), &mapx400_domain, sizeof(void*));
   2023 	(*rr)->rdlength = 2 + 2*sizeof(void*);
   2024 	return rdlength;
   2025 }
   2026 
   2027 void
   2028 write_px_rdata(struct query *query, const struct rr *rr)
   2029 {
   2030 	struct domain *map822_domain, *mapx400_domain;
   2031 	const struct dname *map822, *mapx400;
   2032 
   2033 	memcpy(&map822_domain, rr->rdata + 2, sizeof(void*));
   2034 	memcpy(&mapx400_domain, rr->rdata + 2 + sizeof(void*), sizeof(void*));
   2035 	map822 = domain_dname(map822_domain);
   2036 	mapx400 = domain_dname(mapx400_domain);
   2037 	buffer_write(query->packet, rr->rdata, 2);
   2038 	buffer_write(query->packet, dname_name(map822), map822->name_size);
   2039 	buffer_write(query->packet, dname_name(mapx400), mapx400->name_size);
   2040 }
   2041 
   2042 int
   2043 print_px_rdata(struct buffer *output, const struct rr *rr)
   2044 {
   2045 	uint16_t length = 2;
   2046 	assert(rr->rdlength > 3);
   2047 	buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
   2048 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   2049 		return 0;
   2050 	buffer_printf(output, " ");
   2051 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   2052 		return 0;
   2053 	assert(rr->rdlength == length);
   2054 	return 1;
   2055 }
   2056 
   2057 int
   2058 print_gpos_rdata(struct buffer *output, const struct rr *rr)
   2059 {
   2060 	uint16_t length = 0;
   2061 	if(!print_unquoted(output, rr->rdlength, rr->rdata, &length))
   2062 		return 0;
   2063 	buffer_printf(output, " ");
   2064 	if(!print_unquoted(output, rr->rdlength, rr->rdata, &length))
   2065 		return 0;
   2066 	buffer_printf(output, " ");
   2067 	if(!print_unquoted(output, rr->rdlength, rr->rdata, &length))
   2068 		return 0;
   2069 	if(rr->rdlength != length)
   2070 		return 0;
   2071 	return 1;
   2072 }
   2073 
   2074 int32_t
   2075 read_aaaa_rdata(struct domain_table *domains, uint16_t rdlength,
   2076 	struct buffer *packet, struct rr **rr)
   2077 {
   2078 	if (rdlength != 16)
   2079 		return MALFORMED;
   2080 	return read_rdata(domains, rdlength, packet, rr);
   2081 }
   2082 
   2083 int
   2084 print_aaaa_rdata(struct buffer *output, const struct rr *rr)
   2085 {
   2086 	uint16_t length = 0;
   2087 	assert(rr->rdlength == 16);
   2088 	return print_ip6(output, rr->rdlength, rr->rdata, &length);
   2089 }
   2090 
   2091 int32_t
   2092 read_loc_rdata(struct domain_table *domains, uint16_t rdlength,
   2093 	struct buffer *packet, struct rr **rr)
   2094 {
   2095 	size_t mark;
   2096 	uint8_t version;
   2097 	uint16_t size_version_0;
   2098 
   2099 	if(!buffer_available(packet, rdlength))
   2100 		return MALFORMED;
   2101 	/* version (byte) */
   2102 	if (rdlength < 1)
   2103 		return MALFORMED;
   2104 	/* version (byte) + size (byte)
   2105 	 * + horizontal precision (byte) + vertical precision (byte)
   2106 	 * + latitude (uint32) + longitude (uint32) + altitude (uint32) */
   2107 	mark = buffer_position(packet);
   2108 	version = buffer_read_u8_at(packet, mark + 0);
   2109 	size_version_0 = 16u;
   2110 	if (version == 0 && rdlength != size_version_0)
   2111 		return MALFORMED;
   2112 	return read_rdata(domains, rdlength, packet, rr);
   2113 }
   2114 
   2115 /* Print the cm for LOC. */
   2116 static void
   2117 loc_cm_print(struct buffer* output, uint8_t mantissa, uint8_t exponent)
   2118 {
   2119 	uint8_t i;
   2120 	/* is it 0.<two digits> ? */
   2121 	if(exponent < 2) {
   2122 		if(exponent == 1)
   2123 			mantissa *= 10;
   2124 		buffer_printf(output, "0.%02ld", (long)mantissa);
   2125 		return;
   2126 	}
   2127 	/* always <digit><string of zeros> */
   2128 	buffer_printf(output, "%d", (int)mantissa);
   2129 	for(i=0; i<exponent-2; i++)
   2130 		buffer_printf(output, "0");
   2131 }
   2132 
   2133 int
   2134 print_loc_rdata(struct buffer *output, const struct rr *rr)
   2135 {
   2136 	/* This does not perform checking (ie degrees < 90 etc). */
   2137 	uint8_t version;
   2138 	uint8_t size;
   2139 	uint8_t horizontal_precision;
   2140 	uint8_t vertical_precision;
   2141 	uint32_t longitude;
   2142 	uint32_t latitude;
   2143 	uint32_t altitude;
   2144 	char northerness;
   2145 	char easterness;
   2146 	uint32_t h;
   2147 	uint32_t m;
   2148 	double s;
   2149 	uint32_t equator = (uint32_t)1 << 31; /* 2**31 */
   2150 
   2151 	if(rr->rdlength < 16)
   2152 		return 0;
   2153 	version = rr->rdata[0];
   2154 	if(version != 0)
   2155 		return 0;
   2156 	size = rr->rdata[1];
   2157 	horizontal_precision = rr->rdata[2];
   2158 	vertical_precision = rr->rdata[3];
   2159 
   2160 	latitude = read_uint32(rr->rdata+4);
   2161 	longitude = read_uint32(rr->rdata+8);
   2162 	altitude = read_uint32(rr->rdata+12);
   2163 
   2164 	if (latitude > equator) {
   2165 		northerness = 'N';
   2166 		latitude = latitude - equator;
   2167 	} else {
   2168 		northerness = 'S';
   2169 		latitude = equator - latitude;
   2170 	}
   2171 	h = latitude / (1000 * 60 * 60);
   2172 	latitude = latitude % (1000 * 60 * 60);
   2173 	m = latitude / (1000 * 60);
   2174 	latitude = latitude % (1000 * 60);
   2175 	s = (double) latitude / 1000.0;
   2176 	buffer_printf(output, "%02u %02u %06.3f %c ",
   2177 		h, m, s, northerness);
   2178 
   2179 	if (longitude > equator) {
   2180 		easterness = 'E';
   2181 		longitude = longitude - equator;
   2182 	} else {
   2183 		easterness = 'W';
   2184 		longitude = equator - longitude;
   2185 	}
   2186 	h = longitude / (1000 * 60 * 60);
   2187 	longitude = longitude % (1000 * 60 * 60);
   2188 	m = longitude / (1000 * 60);
   2189 	longitude = longitude % (1000 * 60);
   2190 	s = (double) longitude / (1000.0);
   2191 	buffer_printf(output, "%02u %02u %06.3f %c ",
   2192 		h, m, s, easterness);
   2193 
   2194 	s = ((double) altitude) / 100;
   2195 	s -= 100000;
   2196 
   2197 	if(altitude%100 != 0)
   2198 		buffer_printf(output, "%.2f", s);
   2199 	else
   2200 		buffer_printf(output, "%.0f", s);
   2201 	buffer_printf(output, "m ");
   2202 
   2203 	loc_cm_print(output, (size & 0xf0) >> 4, size & 0x0f);
   2204 	buffer_printf(output, "m ");
   2205 
   2206 	loc_cm_print(output, (horizontal_precision & 0xf0) >> 4,
   2207 		horizontal_precision & 0x0f);
   2208 	buffer_printf(output, "m ");
   2209 
   2210 	loc_cm_print(output, (vertical_precision & 0xf0) >> 4,
   2211 		vertical_precision & 0x0f);
   2212 	buffer_printf(output, "m");
   2213 
   2214 	return 1;
   2215 }
   2216 
   2217 int32_t
   2218 read_nxt_rdata(struct domain_table *domains, uint16_t rdlength,
   2219 	struct buffer *packet, struct rr **rr)
   2220 {
   2221 	struct domain *domain;
   2222 	struct dname_buffer dname;
   2223 	size_t size;
   2224 	uint16_t bitmap_size;
   2225 	const size_t mark = buffer_position(packet);
   2226 
   2227 	/* name + nxt */
   2228 	if(!buffer_available(packet, rdlength))
   2229 		return MALFORMED;
   2230 	if (!dname_make_from_packet_buffered(&dname, packet, 1, 1))
   2231 		return MALFORMED;
   2232 	if(rdlength < buffer_position(packet) - mark)
   2233 		return MALFORMED;
   2234 	bitmap_size = rdlength - (buffer_position(packet) - mark);
   2235 	size = sizeof(**rr) + sizeof(void*) + bitmap_size;
   2236 	if (!(*rr = region_alloc(domains->region, size)))
   2237 		return TRUNCATED;
   2238 	domain = domain_table_insert(domains, (void*)&dname);
   2239 	domain->usage++;
   2240 	memcpy((*rr)->rdata, &domain, sizeof(void*));
   2241 	if(bitmap_size != 0)
   2242 		buffer_read(packet, (*rr)->rdata + sizeof(void*), bitmap_size);
   2243 	(*rr)->rdlength = sizeof(void*) + bitmap_size;
   2244 	return rdlength;
   2245 }
   2246 
   2247 void
   2248 write_nxt_rdata(struct query *query, const struct rr *rr)
   2249 {
   2250 	struct domain *domain;
   2251 	const struct dname *dname;
   2252 
   2253 	assert(rr->rdlength >= sizeof(void*));
   2254 	memcpy(&domain, rr->rdata, sizeof(void*));
   2255 	dname = domain_dname(domain);
   2256 	buffer_write(query->packet, dname_name(dname), dname->name_size);
   2257 	if(rr->rdlength - sizeof(void*) != 0)
   2258 		buffer_write(query->packet, rr->rdata + sizeof(void*),
   2259 			rr->rdlength - sizeof(void*));
   2260 }
   2261 
   2262 int
   2263 print_nxt_rdata(struct buffer *output, const struct rr *rr)
   2264 {
   2265 	uint16_t length = 0;
   2266 	int bitmap_size;
   2267 	const uint8_t* bitmap;
   2268 
   2269 	assert(rr->rdlength > sizeof(void*));
   2270 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   2271 		return 0;
   2272 
   2273 	bitmap_size = rr->rdlength - length;
   2274 	bitmap = rr->rdata + length;
   2275 	for (int type = 0; type < bitmap_size * 8; type++) {
   2276 		if (get_bit(bitmap, type)) {
   2277 			buffer_printf(output, " %s", rrtype_to_string(type));
   2278 		}
   2279 	}
   2280 
   2281 	return 1;
   2282 }
   2283 
   2284 int
   2285 print_eid_rdata(struct buffer *output, const struct rr *rr)
   2286 {
   2287 	uint16_t length = 0;
   2288 	if(!print_base16(output, rr->rdlength, rr->rdata, &length))
   2289 		return 0;
   2290 	if(rr->rdlength != length)
   2291 		return 0;
   2292 	return 1;
   2293 }
   2294 
   2295 int
   2296 print_nimloc_rdata(struct buffer *output, const struct rr *rr)
   2297 {
   2298 	uint16_t length = 0;
   2299 	if(!print_base16(output, rr->rdlength, rr->rdata, &length))
   2300 		return 0;
   2301 	if(rr->rdlength != length)
   2302 		return 0;
   2303 	return 1;
   2304 }
   2305 
   2306 int32_t
   2307 read_srv_rdata(struct domain_table *domains, uint16_t rdlength,
   2308 	struct buffer *packet, struct rr **rr)
   2309 {
   2310 	struct domain *domain;
   2311 	struct dname_buffer dname;
   2312 	size_t size;
   2313 	const size_t mark = buffer_position(packet);
   2314 
   2315 	/* short + short + short + name */
   2316 	if (buffer_remaining(packet) < rdlength || rdlength < 6)
   2317 		return MALFORMED;
   2318 	buffer_skip(packet, 6);
   2319 	if (!dname_make_from_packet_buffered(&dname, packet,
   2320 		1 /* lenient */, 1) ||
   2321 	    rdlength != buffer_position(packet)-mark)
   2322 		return MALFORMED;
   2323 	size = sizeof(**rr) + 6 + sizeof(void*);
   2324 	if (!(*rr = region_alloc(domains->region, size)))
   2325 		return TRUNCATED;
   2326 	domain = domain_table_insert(domains, (void*)&dname);
   2327 	domain->usage++;
   2328 	buffer_read_at(packet, mark, (*rr)->rdata, 6);
   2329 	memcpy((*rr)->rdata + 6, &domain, sizeof(void*));
   2330 	(*rr)->rdlength = 6 + sizeof(void*);
   2331 	return rdlength;
   2332 }
   2333 
   2334 void
   2335 write_srv_rdata(struct query *query, const struct rr *rr)
   2336 {
   2337 	struct domain *domain;
   2338 	const struct dname *dname;
   2339 
   2340 	assert(rr->rdlength == 6 + sizeof(void*));
   2341 	memcpy(&domain, rr->rdata + 6, sizeof(void*));
   2342 	dname = domain_dname(domain);
   2343 	buffer_write(query->packet, rr->rdata, 6);
   2344 	buffer_write(query->packet, dname_name(dname), dname->name_size);
   2345 }
   2346 
   2347 int
   2348 print_srv_rdata(struct buffer *output, const struct rr *rr)
   2349 {
   2350 	uint16_t length = 6;
   2351 	assert(rr->rdlength > length);
   2352 	buffer_printf(
   2353 		output, "%" PRIu16 " %" PRIu16 " %" PRIu16 " ",
   2354 		read_uint16(rr->rdata), read_uint16(rr->rdata+2),
   2355 		read_uint16(rr->rdata+4));
   2356 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   2357 		return 0;
   2358 	assert(rr->rdlength == length);
   2359 	return 1;
   2360 }
   2361 
   2362 int
   2363 print_atma_rdata(struct buffer *output, const struct rr *rr)
   2364 {
   2365 	uint8_t format;
   2366 	if(rr->rdlength < 1)
   2367 		return 0;
   2368 	format = rr->rdata[0];
   2369 	if(format == 0) {
   2370 		/* AESA format (ATM End System Address). */
   2371 		uint16_t length = 1;
   2372 		if (!print_base16(output, rr->rdlength, rr->rdata, &length))
   2373 			return 0;
   2374 		if(rr->rdlength != length)
   2375 			return 0;
   2376 		return 1;
   2377 	} else if(format == 1) {
   2378 		/* E.164 format. */
   2379 		/* '+' and then digits '0'-'9' from the rdata string. */
   2380 		buffer_printf(output, "+");
   2381 		for (size_t i = 1; i < rr->rdlength; i++) {
   2382 			char ch = (char)rr->rdata[i];
   2383 			if(!isdigit((unsigned char)ch))
   2384 				return 0;
   2385 			buffer_printf(output, "%c", ch);
   2386 		}
   2387 		return 1;
   2388 	}
   2389 	/* Unknown format. */
   2390 	return 0;
   2391 }
   2392 
   2393 int32_t
   2394 read_naptr_rdata(struct domain_table *domains, uint16_t rdlength,
   2395 	struct buffer *packet, struct rr **rr)
   2396 {
   2397 	struct domain *domain;
   2398 	struct dname_buffer dname;
   2399 	uint16_t length = 4;
   2400 	size_t size;
   2401 	const size_t mark = buffer_position(packet);
   2402 
   2403 	/* short + short + text + text + text + name */
   2404 	if (buffer_remaining(packet) < rdlength ||
   2405 	    rdlength < length)
   2406 		return MALFORMED;
   2407 	buffer_skip(packet, 4);
   2408 	if(skip_string(packet, rdlength, &length) < 0 ||
   2409 	   skip_string(packet, rdlength, &length) < 0 ||
   2410 	   skip_string(packet, rdlength, &length) < 0 ||
   2411 	   !dname_make_from_packet_buffered(&dname, packet, 1, 1) ||
   2412 	   rdlength != buffer_position(packet) - mark)
   2413 		return MALFORMED;
   2414 
   2415 	size = sizeof(**rr) + length + sizeof(void*);
   2416 	if (!(*rr = region_alloc(domains->region, size)))
   2417 		return TRUNCATED;
   2418 	domain = domain_table_insert(domains, (void*)&dname);
   2419 	domain->usage++;
   2420 	buffer_read_at(packet, mark, (*rr)->rdata, length);
   2421 	memcpy((*rr)->rdata + length, &domain, sizeof(void*));
   2422 	(*rr)->rdlength = length + sizeof(void*);
   2423 	return rdlength;
   2424 }
   2425 
   2426 void
   2427 write_naptr_rdata(struct query *query, const struct rr *rr)
   2428 {
   2429 	struct domain *domain;
   2430 	const struct dname *dname;
   2431 	uint16_t length;
   2432 
   2433 	/* short + short + string + string + string + uncompressed name */
   2434 	assert(rr->rdlength >= 7 + sizeof(void*));
   2435 	length = rr->rdlength - sizeof(void*);
   2436 	memcpy(&domain, rr->rdata + length, sizeof(void*));
   2437 	dname = domain_dname(domain);
   2438 	buffer_write(query->packet, rr->rdata, length);
   2439 	buffer_write(query->packet, dname_name(dname), dname->name_size);
   2440 }
   2441 
   2442 int
   2443 print_naptr_rdata(struct buffer *output, const struct rr *rr)
   2444 {
   2445 	uint16_t length = 4;
   2446 
   2447 	assert(rr->rdlength >= 7 + sizeof(void*));
   2448 	buffer_printf(
   2449 		output, "%" PRIu16 " %" PRIu16 " ",
   2450 		read_uint16(rr->rdata), read_uint16(rr->rdata+2));
   2451 	if (!print_string(output, rr->rdlength, rr->rdata, &length))
   2452 		return 0;
   2453 	buffer_printf(output, " ");
   2454 	if (!print_string(output, rr->rdlength, rr->rdata, &length))
   2455 		return 0;
   2456 	buffer_printf(output, " ");
   2457 	if (!print_string(output, rr->rdlength, rr->rdata, &length))
   2458 		return 0;
   2459 	buffer_printf(output, " ");
   2460 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   2461 		return 0;
   2462 	assert(rr->rdlength == length);
   2463 	return 1;
   2464 }
   2465 
   2466 int32_t
   2467 read_kx_rdata(struct domain_table *domains, uint16_t rdlength,
   2468 	struct buffer *packet, struct rr **rr)
   2469 {
   2470 	struct domain *domain;
   2471 	struct dname_buffer dname;
   2472 	const size_t mark = buffer_position(packet);
   2473 	size_t size;
   2474 
   2475 	/* short + uncompressed name */
   2476 	if(buffer_remaining(packet) < rdlength || rdlength < 2)
   2477 		return MALFORMED;
   2478 	buffer_skip(packet, 2);
   2479 	if(!dname_make_from_packet_buffered(&dname, packet,
   2480 		1 /* lenient */, 1) ||
   2481 	    rdlength != buffer_position(packet) - mark)
   2482 		return MALFORMED;
   2483 
   2484 	size = sizeof(**rr) + 2 + sizeof(void*);
   2485 	if (!(*rr = region_alloc(domains->region, size)))
   2486 		return TRUNCATED;
   2487 	domain = domain_table_insert(domains, (void*)&dname);
   2488 	domain->usage++;
   2489 	buffer_read_at(packet, mark, (*rr)->rdata, 2);
   2490 	memcpy((*rr)->rdata + 2, &domain, sizeof(void*));
   2491 	(*rr)->rdlength = 2 + sizeof(void*);
   2492 	return rdlength;
   2493 }
   2494 
   2495 void
   2496 write_kx_rdata(struct query *query, const struct rr *rr)
   2497 {
   2498 	struct domain *domain;
   2499 	const struct dname *dname;
   2500 
   2501 	/* short + uncompressed name */
   2502 	assert(rr->rdlength == 2 + sizeof(void*));
   2503 	memcpy(&domain, rr->rdata + 2, sizeof(void*));
   2504 	dname = domain_dname(domain);
   2505 	buffer_write(query->packet, rr->rdata, 2);
   2506 	buffer_write(query->packet, dname_name(dname), dname->name_size);
   2507 }
   2508 
   2509 int32_t
   2510 read_cert_rdata(struct domain_table *domains, uint16_t rdlength,
   2511 	struct buffer *packet, struct rr **rr)
   2512 {
   2513 	/* short + short + byte + binary */
   2514 	if (rdlength < 5)
   2515 		return MALFORMED;
   2516 	return read_rdata(domains, rdlength, packet, rr);
   2517 }
   2518 
   2519 int
   2520 print_cert_rdata(struct buffer *output, const struct rr *rr)
   2521 {
   2522 	uint16_t length = 0;
   2523 	if(rr->rdlength < 5)
   2524 		return 0;
   2525 	if(!print_certificate_type(output, rr->rdlength, rr->rdata, &length))
   2526 		return 0;
   2527 	buffer_printf(output, " %" PRIu16 " %" PRIu8 " ",
   2528 		read_uint16(rr->rdata+2), rr->rdata[4]);
   2529 	length += 3;
   2530 	if (!print_base64(output, rr->rdlength, rr->rdata, &length))
   2531 		return 0;
   2532 	if(rr->rdlength != length)
   2533 		return 0;
   2534 	return 1;
   2535 }
   2536 
   2537 int
   2538 print_sink_rdata(struct buffer *output, const struct rr *rr)
   2539 {
   2540 	uint16_t length = 2;
   2541 	if(rr->rdlength < 2)
   2542 		return 0;
   2543 	buffer_printf(output, "%" PRIu8 " %" PRIu8 " ",
   2544 		rr->rdata[0], rr->rdata[1]);
   2545 	if (!print_base64(output, rr->rdlength, rr->rdata, &length))
   2546 		return 0;
   2547 	if(rr->rdlength != length)
   2548 		return 0;
   2549 	return 1;
   2550 }
   2551 
   2552 int32_t
   2553 read_apl_rdata(struct domain_table *domains, uint16_t rdlength,
   2554 	struct buffer *packet, struct rr **rr)
   2555 {
   2556 	uint16_t length = 0;
   2557 	const uint8_t *rdata = buffer_current(packet);
   2558 
   2559 	if (buffer_remaining(packet) < rdlength)
   2560 		return MALFORMED;
   2561 	while (rdlength - length >= 4) {
   2562 		uint8_t afdlength = rdata[length + 3] & APL_LENGTH_MASK;
   2563 		if (rdlength - (length + 4) < afdlength)
   2564 			return MALFORMED;
   2565 		length += 4 + afdlength;
   2566 	}
   2567 
   2568 	if (length != rdlength)
   2569 		return MALFORMED;
   2570 	return read_rdata(domains, rdlength, packet, rr);
   2571 }
   2572 
   2573 /*
   2574  * Print one APL field.
   2575  * @param output: string is printed to the buffer.
   2576  * @param rdlength: length of rdata.
   2577  * @param rdata: the rdata
   2578  * @param offset: on input the current position, adjusted on output to
   2579  *	increment for the rdata used.
   2580  * @return false on failure.
   2581  */
   2582 static int
   2583 print_apl(struct buffer *output, size_t rdlength, const uint8_t *rdata,
   2584 	uint16_t *offset)
   2585 {
   2586 	size_t size = rdlength - *offset;
   2587 	uint16_t address_family;
   2588 	uint8_t prefix, length, negated;
   2589 	int af;
   2590 	char text_address[INET6_ADDRSTRLEN + 1];
   2591 	uint8_t address[16];
   2592 
   2593 	if (size < 4)
   2594 		return 0;
   2595 
   2596 	address_family = read_uint16(rdata + *offset);
   2597 	prefix = rdata[*offset + 2];
   2598 	length = rdata[*offset + 3] & APL_LENGTH_MASK;
   2599 	negated = rdata[*offset + 3] & APL_NEGATION_MASK;
   2600 	af = -1;
   2601 
   2602 	switch (address_family) {
   2603 	case 1: af = AF_INET; break;
   2604 	case 2: af = AF_INET6; break;
   2605 	}
   2606 
   2607 	if (af == -1 || size - 4 < length)
   2608 		return 0;
   2609 
   2610 	memset(address, 0, sizeof(address));
   2611 	memmove(address, rdata + *offset + 4, length);
   2612 
   2613 	if (!inet_ntop(af, address, text_address, sizeof(text_address)))
   2614 		return 0;
   2615 
   2616 	buffer_printf(
   2617 		output, "%s%" PRIu16 ":%s/%" PRIu8,
   2618 		(negated ? "!" : ""), address_family, text_address, prefix);
   2619 	*offset += 4 + length;
   2620 	return 1;
   2621 }
   2622 
   2623 int
   2624 print_apl_rdata(struct buffer *output, const struct rr *rr)
   2625 {
   2626 	uint16_t length = 0;
   2627 
   2628 	while (length < rr->rdlength) {
   2629 		if(length != 0)
   2630 			buffer_printf(output, " ");
   2631 		if (!print_apl(output, rr->rdlength, rr->rdata, &length))
   2632 			return 0;
   2633 	}
   2634 	if(rr->rdlength != length)
   2635 		return 0;
   2636 	return 1;
   2637 }
   2638 
   2639 int32_t
   2640 read_ds_rdata(struct domain_table *domains, uint16_t rdlength,
   2641 	struct buffer *packet, struct rr **rr)
   2642 {
   2643 	/* short + byte + byte + binary */
   2644 	if (rdlength < 4)
   2645 		return MALFORMED;
   2646 	return read_rdata(domains, rdlength, packet, rr);
   2647 }
   2648 
   2649 int
   2650 print_ds_rdata(struct buffer *output, const struct rr *rr)
   2651 {
   2652 	uint16_t length = 4;
   2653 
   2654 	if(rr->rdlength < length)
   2655 		return 0;
   2656 	buffer_printf(
   2657 		output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ",
   2658 		read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]);
   2659 	if (!print_base16(output, rr->rdlength, rr->rdata, &length))
   2660 		return 0;
   2661 	if(rr->rdlength != length)
   2662 		return 0;
   2663 	return 1;
   2664 }
   2665 
   2666 int32_t
   2667 read_sshfp_rdata(struct domain_table *domains, uint16_t rdlength,
   2668 	struct buffer *packet, struct rr **rr)
   2669 {
   2670 	/* byte + byte + binary */
   2671 	if (rdlength < 2)
   2672 		return MALFORMED;
   2673 	return read_rdata(domains, rdlength, packet, rr);
   2674 }
   2675 
   2676 int
   2677 print_sshfp_rdata(struct buffer *output, const struct rr *rr)
   2678 {
   2679 	uint16_t length = 2;
   2680 	uint8_t algorithm, ftype;
   2681 
   2682 	if(rr->rdlength < length)
   2683 		return 0;
   2684 	algorithm = rr->rdata[0];
   2685 	ftype = rr->rdata[1];
   2686 
   2687 	buffer_printf(output, "%" PRIu8 " %" PRIu8 " ", algorithm, ftype);
   2688 	if (!print_base16(output, rr->rdlength, rr->rdata, &length))
   2689 		return 0;
   2690 	if(rr->rdlength != length)
   2691 		return 0;
   2692 	return 1;
   2693 }
   2694 
   2695 int32_t
   2696 read_ipseckey_rdata(struct domain_table *domains, uint16_t rdlength,
   2697 	struct buffer *packet, struct rr **rr)
   2698 {
   2699 	struct dname_buffer gateway;
   2700 	const uint8_t *gateway_rdata;
   2701 	uint8_t gateway_length = 0;
   2702 	const size_t mark = buffer_position(packet);
   2703 	uint16_t keylen;
   2704 
   2705 	/* byte + byte + byte + gateway + binary */
   2706 	if (buffer_remaining(packet) < rdlength || rdlength < 3)
   2707 		return MALFORMED;
   2708 
   2709 	buffer_skip(packet, 3);
   2710 
   2711 	switch (buffer_read_u8_at(packet, mark + 1)) {
   2712 	case IPSECKEY_NOGATEWAY:
   2713 		gateway_length = 0;
   2714 		gateway_rdata = NULL;
   2715 		break;
   2716 	case IPSECKEY_IP4:
   2717 		gateway_length = 4;
   2718 		gateway_rdata = buffer_current(packet);
   2719 		if (rdlength < 3 + gateway_length)
   2720 			return MALFORMED;
   2721 		buffer_skip(packet, gateway_length);
   2722 		break;
   2723 	case IPSECKEY_IP6:
   2724 		gateway_length = 16;
   2725 		gateway_rdata = buffer_current(packet);
   2726 		if (rdlength < 3 + gateway_length)
   2727 			return MALFORMED;
   2728 		buffer_skip(packet, gateway_length);
   2729 		break;
   2730 	case IPSECKEY_DNAME:
   2731 		/* The dname is stored as literal dname. On the wire
   2732 		 * skip possibly compressed format, in the rdata there
   2733 		 * is an uncompressed wire format. */
   2734 		if (!dname_make_from_packet_buffered(&gateway, packet,
   2735 			1 /* lenient */, 1))
   2736 			return MALFORMED;
   2737 		if(rdlength < buffer_position(packet) - mark)
   2738 			return MALFORMED;
   2739 		gateway_length = gateway.dname.name_size;
   2740 		gateway_rdata = dname_name((void*)&gateway);
   2741 		break;
   2742 	default:
   2743 		return MALFORMED;
   2744 	}
   2745 	keylen = rdlength - (buffer_position(packet)-mark);
   2746 
   2747 	if (!(*rr = region_alloc(domains->region,
   2748 		sizeof(**rr) + 3 + gateway_length + keylen)))
   2749 		return TRUNCATED;
   2750 
   2751 	buffer_read_at(packet, mark, (*rr)->rdata, 3);
   2752 	if(gateway_rdata)
   2753 		memcpy((*rr)->rdata + 3, gateway_rdata, gateway_length);
   2754 	if(keylen != 0)
   2755 		buffer_read(packet, (*rr)->rdata + 3 + gateway_length, keylen);
   2756 	(*rr)->rdlength = 3 + gateway_length + keylen;
   2757 	return rdlength;
   2758 }
   2759 
   2760 int
   2761 print_ipseckey_rdata(struct buffer *output, const struct rr *rr)
   2762 {
   2763 	uint16_t length = 3;
   2764 	uint8_t gateway_type;
   2765 
   2766 	if(rr->rdlength < length)
   2767 		return 0;
   2768 	buffer_printf(
   2769 		output, "%" PRIu8 " %" PRIu8 " %" PRIu8 " ",
   2770 		rr->rdata[0], rr->rdata[1], rr->rdata[2]);
   2771 	gateway_type = rr->rdata[1];
   2772 	switch (gateway_type) {
   2773 	case IPSECKEY_NOGATEWAY:
   2774 		buffer_printf(output, ".");
   2775 		break;
   2776 	case IPSECKEY_IP4:
   2777 		if (!print_ip4(output, rr->rdlength, rr->rdata, &length))
   2778 			return 0;
   2779 		break;
   2780 	case IPSECKEY_IP6:
   2781 		if (!print_ip6(output, rr->rdlength, rr->rdata, &length))
   2782 			return 0;
   2783 		break;
   2784 	case IPSECKEY_DNAME:
   2785 		if (!print_name_literal(output, rr->rdlength, rr->rdata,
   2786 			&length))
   2787 			return 0;
   2788 		break;
   2789 	default:
   2790 		return 0;
   2791 	}
   2792 
   2793 	if(rr->rdlength > length) {
   2794 		/* Print key field in base64. */
   2795 		buffer_printf(output, " ");
   2796 		if (!print_base64(output, rr->rdlength, rr->rdata, &length))
   2797 			return 0;
   2798 	}
   2799 	if(rr->rdlength != length)
   2800 		return 0;
   2801 	return 1;
   2802 }
   2803 
   2804 int32_t
   2805 ipseckey_gateway_length(uint16_t rdlength, const uint8_t *rdata,
   2806 	uint16_t offset, struct domain** domain)
   2807 {
   2808 	/* The ipseckey gateway length depends only on earlier bytes, so both
   2809 	 * the in-memory and uncompressed wireformat refer to the same
   2810 	 * earlier bytes. Also the domain name is stored literally, so it
   2811 	 * does not need to return a reference. */
   2812 	uint8_t gateway_type;
   2813 	*domain = NULL;
   2814 	/* Calculate the gateway length, based on the gateway type.
   2815 	 * That is stored in an earlier field. */
   2816 	if(rdlength < 3 || offset < 3)
   2817 		return -1; /* too short */
   2818 	gateway_type = rdata[1];
   2819 	switch(gateway_type) {
   2820 	case IPSECKEY_NOGATEWAY:
   2821 		return 0;
   2822 	case IPSECKEY_IP4:
   2823 		return 4;
   2824 	case IPSECKEY_IP6:
   2825 		return 16;
   2826 	case IPSECKEY_DNAME:
   2827 		return buf_dname_length(rdata+offset, rdlength-offset);
   2828 	default:
   2829 		/* Unknown gateway type. */
   2830 		break;
   2831 	}
   2832 	return -1;
   2833 }
   2834 
   2835 int32_t
   2836 read_rrsig_rdata(struct domain_table *domains, uint16_t rdlength,
   2837 	struct buffer *packet, struct rr **rr)
   2838 {
   2839 	struct dname_buffer signer;
   2840 	const size_t mark = buffer_position(packet);
   2841 	uint16_t memrdlen, b64len;
   2842 
   2843 	/* short + byte + byte + uint32 + uint32 + uint32 + short */
   2844 	if (buffer_remaining(packet) < rdlength || rdlength < 18)
   2845 		return MALFORMED;
   2846 	buffer_skip(packet, 18);
   2847 	if (!dname_make_from_packet_buffered(&signer, packet,
   2848 		1 /* lenient */, 1))
   2849 		return MALFORMED;
   2850 	if (rdlength < buffer_position(packet) - mark)
   2851 		return MALFORMED;
   2852 	memrdlen = 18 + signer.dname.name_size;
   2853 	b64len = rdlength - (buffer_position(packet) - mark);
   2854 	if (!(*rr = region_alloc(domains->region, sizeof(**rr) + memrdlen + b64len)))
   2855 		return TRUNCATED;
   2856 	buffer_read_at(packet, mark, (*rr)->rdata, 18);
   2857 	memcpy((*rr)->rdata + 18, dname_name((void*)&signer),
   2858 		signer.dname.name_size);
   2859 	if(b64len != 0)
   2860 		buffer_read(packet, (*rr)->rdata+memrdlen, b64len);
   2861 	(*rr)->rdlength = memrdlen + b64len;
   2862 	return rdlength;
   2863 }
   2864 
   2865 int
   2866 print_rrsig_rdata(struct buffer *output, const struct rr *rr)
   2867 {
   2868 	uint16_t length = 8;
   2869 
   2870 	if(rr->rdlength < 18)
   2871 		return 0;
   2872 	buffer_printf(
   2873 		output, "%s %" PRIu8 " %" PRIu8 " %" PRIu32 " ",
   2874 		rrtype_to_string(read_uint16(rr->rdata)), rr->rdata[2],
   2875 		rr->rdata[3], read_uint32(rr->rdata+4));
   2876 	if (!print_time(output, rr->rdlength, rr->rdata, &length))
   2877 		return 0;
   2878 	buffer_printf(output, " ");
   2879 	if (!print_time(output, rr->rdlength, rr->rdata, &length))
   2880 		return 0;
   2881 
   2882 	buffer_printf(output, " %" PRIu16 " ", read_uint16(rr->rdata+length));
   2883 	length += 2;
   2884 
   2885 	if (!print_name_literal(output, rr->rdlength, rr->rdata, &length))
   2886 		return 0;
   2887 	buffer_printf(output, " ");
   2888 	if (!print_base64(output, rr->rdlength, rr->rdata, &length))
   2889 		return 0;
   2890 	if(rr->rdlength != length)
   2891 		return 0;
   2892 	return 1;
   2893 }
   2894 
   2895 int32_t
   2896 read_nsec_rdata(struct domain_table *domains, uint16_t rdlength,
   2897 	struct buffer *packet, struct rr **rr)
   2898 {
   2899 	struct dname_buffer next;
   2900 	uint16_t length, memrdlen, bitmaplen;
   2901 	size_t bitmapmark;
   2902 	const size_t mark = buffer_position(packet);
   2903 
   2904 	/* uncompressed name + nsec */
   2905 	if(buffer_remaining(packet) < rdlength ||
   2906 	   !dname_make_from_packet_buffered(&next, packet,
   2907 		1 /* lenient */, 1) ||
   2908 	   rdlength < buffer_position(packet) - mark)
   2909 		return MALFORMED;
   2910 
   2911 	bitmapmark = buffer_position(packet);
   2912 	length = bitmapmark - mark;
   2913 	if (skip_nsec(packet, rdlength, &length) < 0
   2914 		|| rdlength != length)
   2915 		return MALFORMED;
   2916 	bitmaplen = buffer_position(packet) - bitmapmark;
   2917 	memrdlen = next.dname.name_size + bitmaplen;
   2918 	if (!(*rr = region_alloc(domains->region, sizeof(**rr) + memrdlen)))
   2919 		return TRUNCATED;
   2920 	memcpy((*rr)->rdata, dname_name((void*)&next), next.dname.name_size);
   2921 	if(bitmaplen != 0)
   2922 		buffer_read_at(packet, bitmapmark,
   2923 			(*rr)->rdata + next.dname.name_size, bitmaplen);
   2924 	(*rr)->rdlength = memrdlen;
   2925 	return rdlength;
   2926 }
   2927 
   2928 int
   2929 print_nsec_rdata(struct buffer *output, const struct rr *rr)
   2930 {
   2931 	uint16_t length = 0;
   2932 
   2933 	if (!print_name_literal(output, rr->rdlength, rr->rdata, &length))
   2934 		return 0;
   2935 	buffer_printf(output, " ");
   2936 	if (!print_nsec_bitmap(output, rr->rdlength, rr->rdata, &length))
   2937 		return 0;
   2938 	if(rr->rdlength != length)
   2939 		return 0;
   2940 	return 1;
   2941 }
   2942 
   2943 int32_t
   2944 read_dnskey_rdata(struct domain_table *domains, uint16_t rdlength,
   2945 	struct buffer *packet, struct rr **rr)
   2946 {
   2947 	/* short + byte + byte + binary of remainder */
   2948 	if (rdlength < 4)
   2949 		return MALFORMED;
   2950 	return read_rdata(domains, rdlength, packet, rr);
   2951 }
   2952 
   2953 int
   2954 print_dnskey_rdata(struct buffer *output, const struct rr *rr)
   2955 {
   2956 	uint16_t length = 4;
   2957 
   2958 	if(rr->rdlength < length)
   2959 		return 0;
   2960 	buffer_printf(
   2961 		output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ",
   2962 		read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]);
   2963 	if (!print_base64(output, rr->rdlength, rr->rdata, &length))
   2964 		return 0;
   2965 	if(rr->rdlength != length)
   2966 		return 0;
   2967 	return 1;
   2968 }
   2969 
   2970 int32_t
   2971 read_dhcid_rdata(struct domain_table *domains, uint16_t rdlength,
   2972 	struct buffer *packet, struct rr **rr)
   2973 {
   2974 	/* short + byte + digest */
   2975 	if (rdlength < 3)
   2976 		return MALFORMED;
   2977 	return read_rdata(domains, rdlength, packet, rr);
   2978 }
   2979 
   2980 int
   2981 print_dhcid_rdata(struct buffer *output, const struct rr *rr)
   2982 {
   2983 	uint16_t length = 0;
   2984 
   2985 	if (!print_base64(output, rr->rdlength, rr->rdata, &length))
   2986 		return 0;
   2987 	if(rr->rdlength != length)
   2988 		return 0;
   2989 	return 1;
   2990 }
   2991 
   2992 int32_t
   2993 read_nsec3_rdata(struct domain_table *domains, uint16_t rdlength,
   2994 	struct buffer *packet, struct rr **rr)
   2995 {
   2996 	uint16_t length = 4;
   2997 	/* byte + byte + short + string + string + binary */
   2998 	const size_t mark = buffer_position(packet);
   2999 
   3000 	if (buffer_remaining(packet) < rdlength || rdlength < length)
   3001 		return MALFORMED;
   3002 	buffer_skip(packet, length);
   3003 	if (skip_string(packet, rdlength, &length) < 0 ||
   3004 			skip_string(packet, rdlength, &length) < 0 ||
   3005 			skip_nsec(packet, rdlength, &length) < 0 ||
   3006 			rdlength != length)
   3007 		return MALFORMED;
   3008 	buffer_set_position(packet, mark);
   3009 	return read_rdata(domains, rdlength, packet, rr);
   3010 }
   3011 
   3012 int
   3013 print_nsec3_rdata(struct buffer *output, const struct rr *rr)
   3014 {
   3015 	uint16_t length = 4;
   3016 
   3017 	if(rr->rdlength < length)
   3018 		return 0;
   3019 	buffer_printf(
   3020 		output, "%" PRIu8 " %" PRIu8 " %" PRIu16 " ",
   3021 		rr->rdata[0], rr->rdata[1], read_uint16(rr->rdata + 2));
   3022 	if (!print_salt(output, rr->rdlength, rr->rdata, &length))
   3023 		return 0;
   3024 	buffer_printf(output, " ");
   3025 	if (!print_base32(output, rr->rdlength, rr->rdata, &length))
   3026 		return 0;
   3027 	buffer_printf(output, " ");
   3028 	if (!print_nsec_bitmap(output, rr->rdlength, rr->rdata, &length))
   3029 		return 0;
   3030 	if(rr->rdlength != length)
   3031 		return 0;
   3032 	return 1;
   3033 }
   3034 
   3035 int32_t
   3036 read_nsec3param_rdata(struct domain_table *domains, uint16_t rdlength,
   3037 	struct buffer *packet, struct rr **rr)
   3038 {
   3039 	uint16_t length = 4;
   3040 	/* byte + byte + short + string */
   3041 	const size_t mark = buffer_position(packet);
   3042 
   3043 	if (buffer_remaining(packet) < rdlength || rdlength < length)
   3044 		return MALFORMED;
   3045 	buffer_skip(packet, length);
   3046 	if (skip_string(packet, rdlength, &length) < 0 ||
   3047 	    rdlength != length)
   3048 		return MALFORMED;
   3049 	buffer_set_position(packet, mark);
   3050 	return read_rdata(domains, rdlength, packet, rr);
   3051 }
   3052 
   3053 int
   3054 print_nsec3param_rdata(struct buffer *output, const struct rr *rr)
   3055 {
   3056 	uint16_t length = 4;
   3057 
   3058 	if(rr->rdlength < length)
   3059 		return 0;
   3060 	buffer_printf(
   3061 		output, "%" PRIu8 " %" PRIu8 " %" PRIu16 " ",
   3062 		rr->rdata[0], rr->rdata[1], read_uint16(rr->rdata + 2));
   3063 
   3064 	if (!print_salt(output, rr->rdlength, rr->rdata, &length))
   3065 		return 0;
   3066 	if(rr->rdlength != length)
   3067 		return 0;
   3068 	return 1;
   3069 }
   3070 
   3071 int32_t
   3072 read_tlsa_rdata(struct domain_table *domains, uint16_t rdlength,
   3073 	struct buffer *packet, struct rr **rr)
   3074 {
   3075 	/* byte + byte + byte + binary */
   3076 	if (rdlength < 3)
   3077 		return MALFORMED;
   3078 	return read_rdata(domains, rdlength, packet, rr);
   3079 }
   3080 
   3081 int
   3082 print_tlsa_rdata(struct buffer *output, const struct rr *rr)
   3083 {
   3084 	uint16_t length = 3;
   3085 
   3086 	if(rr->rdlength < length)
   3087 		return 0;
   3088 	buffer_printf(
   3089 		output, "%" PRIu8 " %" PRIu8 " %" PRIu8 " ",
   3090 		rr->rdata[0], rr->rdata[1], rr->rdata[2]);
   3091 
   3092 	if (!print_base16(output, rr->rdlength, rr->rdata, &length))
   3093 		return 0;
   3094 	if(rr->rdlength != length)
   3095 		return 0;
   3096 	return 1;
   3097 }
   3098 
   3099 int32_t
   3100 read_hip_rdata(struct domain_table *domains, uint16_t rdlength,
   3101 	struct buffer *packet, struct rr **rr)
   3102 {
   3103 	/* byte (hit length) + byte (PK algorithm) + short (PK length) +
   3104 	 * HIT(hex) + pubkey(base64) + rendezvous servers(literal dnames) */
   3105 	if (rdlength < 4)
   3106 		return MALFORMED;
   3107 	return read_rdata(domains, rdlength, packet, rr);
   3108 }
   3109 
   3110 int
   3111 print_hip_rdata(struct buffer *output, const struct rr *rr)
   3112 {
   3113 	/* byte (hit length) + byte (PK algorithm) + short (PK length) +
   3114 	 * HIT(hex) + pubkey(base64) + rendezvous servers(literal dnames) */
   3115 	uint8_t hit_length, pk_algorithm;
   3116 	uint16_t pk_length;
   3117 	uint16_t length = 4;
   3118 
   3119 	if(rr->rdlength < length)
   3120 		return 0;
   3121 	hit_length = rr->rdata[0];
   3122 	pk_algorithm = rr->rdata[1];
   3123 	pk_length = read_uint16(rr->rdata+2);
   3124 	buffer_printf(output, "%" PRIu8 " ", pk_algorithm);
   3125 	if(!print_base16(output, length+hit_length, rr->rdata, &length))
   3126 		return 0;
   3127 	buffer_printf(output, " ");
   3128 	if(!print_base64(output, length+pk_length, rr->rdata, &length))
   3129 		return 0;
   3130 	while(length < rr->rdlength) {
   3131 		buffer_printf(output, " ");
   3132 		if(!print_name_literal(output, rr->rdlength, rr->rdata,
   3133 			&length))
   3134 			return 0;
   3135 	}
   3136 	if(rr->rdlength != length)
   3137 		return 0;
   3138 	return 1;
   3139 }
   3140 
   3141 int32_t
   3142 read_rkey_rdata(struct domain_table *domains, uint16_t rdlength,
   3143 	struct buffer *packet, struct rr **rr)
   3144 {
   3145 	/* short + byte + byte + binary of remainder */
   3146 	if (rdlength < 4)
   3147 		return MALFORMED;
   3148 	return read_rdata(domains, rdlength, packet, rr);
   3149 }
   3150 
   3151 int
   3152 print_rkey_rdata(struct buffer *output, const struct rr *rr)
   3153 {
   3154 	uint16_t length = 4;
   3155 
   3156 	if(rr->rdlength < length)
   3157 		return 0;
   3158 	buffer_printf(
   3159 		output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ",
   3160 		read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]);
   3161 	if (!print_base64(output, rr->rdlength, rr->rdata, &length))
   3162 		return 0;
   3163 	if(rr->rdlength != length)
   3164 		return 0;
   3165 	return 1;
   3166 }
   3167 
   3168 int32_t
   3169 read_talink_rdata(struct domain_table *domains, uint16_t rdlength,
   3170 	struct buffer *packet, struct rr **rr)
   3171 {
   3172 	struct dname_buffer prev, next;
   3173 	const size_t mark = buffer_position(packet);
   3174 	if(!buffer_available(packet, rdlength))
   3175 		return MALFORMED;
   3176 	if(!dname_make_from_packet_buffered(&prev, packet,
   3177 		1 /* lenient */, 1))
   3178 		return MALFORMED;
   3179 	if(buffer_position(packet)-mark > rdlength)
   3180 		return MALFORMED;
   3181 	if(!dname_make_from_packet_buffered(&next, packet,
   3182 		1 /* lenient */, 1))
   3183 		return MALFORMED;
   3184 	if(buffer_position(packet)-mark != rdlength)
   3185 		return MALFORMED;
   3186 	if (!(*rr = region_alloc(domains->region,
   3187 		sizeof(**rr) + prev.dname.name_size + next.dname.name_size)))
   3188 		return TRUNCATED;
   3189 	memcpy((*rr)->rdata, dname_name((void*)&prev), prev.dname.name_size);
   3190 	memcpy((*rr)->rdata + prev.dname.name_size, dname_name((void*)&next),
   3191 		next.dname.name_size);
   3192 	(*rr)->rdlength = prev.dname.name_size + next.dname.name_size;
   3193 	return rdlength;
   3194 }
   3195 
   3196 int
   3197 print_talink_rdata(struct buffer *output, const struct rr *rr)
   3198 {
   3199 	uint16_t length = 0;
   3200 	if(!print_name_literal(output, rr->rdlength, rr->rdata, &length))
   3201 		return 0;
   3202 	buffer_printf(output, " ");
   3203 	if(!print_name_literal(output, rr->rdlength, rr->rdata, &length))
   3204 		return 0;
   3205 	if(rr->rdlength != length)
   3206 		return 0;
   3207 	return 1;
   3208 }
   3209 
   3210 int
   3211 print_openpgpkey_rdata(struct buffer *output, const struct rr *rr)
   3212 {
   3213 	uint16_t length = 0;
   3214 
   3215 	if (!print_base64(output, rr->rdlength, rr->rdata, &length))
   3216 		return 0;
   3217 	if(rr->rdlength != length)
   3218 		return 0;
   3219 	return 1;
   3220 }
   3221 
   3222 int32_t
   3223 read_csync_rdata(struct domain_table *domains, uint16_t rdlength,
   3224 	struct buffer *packet, struct rr **rr)
   3225 {
   3226 	/* long + short + binary bitmap in remainder */
   3227 	if (rdlength < 6)
   3228 		return MALFORMED;
   3229 	return read_rdata(domains, rdlength, packet, rr);
   3230 }
   3231 
   3232 int
   3233 print_csync_rdata(struct buffer *output, const struct rr *rr)
   3234 {
   3235 	uint16_t length = 6;
   3236 
   3237 	if(rr->rdlength < length)
   3238 		return 0;
   3239 	buffer_printf(
   3240 		output, "%" PRIu32 " %" PRIu16 " ",
   3241 		read_uint32(rr->rdata), read_uint16(rr->rdata + 4));
   3242 	if (!print_nsec_bitmap(output, rr->rdlength, rr->rdata, &length))
   3243 		return 0;
   3244 	if(rr->rdlength != length)
   3245 		return 0;
   3246 	return 1;
   3247 }
   3248 
   3249 int32_t
   3250 read_zonemd_rdata(struct domain_table *domains, uint16_t rdlength,
   3251 	struct buffer *packet, struct rr **rr)
   3252 {
   3253 	/* long + byte + byte + binary */
   3254 	if (rdlength < 6)
   3255 		return MALFORMED;
   3256 	return read_rdata(domains, rdlength, packet, rr);
   3257 }
   3258 
   3259 int
   3260 print_zonemd_rdata(struct buffer *output, const struct rr *rr)
   3261 {
   3262 	uint16_t length = 6;
   3263 
   3264 	if(rr->rdlength < length)
   3265 		return 0;
   3266 	buffer_printf(
   3267 		output, "%" PRIu32 " %" PRIu8 " %" PRIu8 " ",
   3268 		read_uint32(rr->rdata), rr->rdata[4], rr->rdata[5]);
   3269 	if (!print_base16(output, rr->rdlength, rr->rdata, &length))
   3270 		return 0;
   3271 	if(rr->rdlength != length)
   3272 		return 0;
   3273 	return 1;
   3274 }
   3275 
   3276 int32_t
   3277 read_svcb_rdata(struct domain_table *domains, uint16_t rdlength,
   3278 	struct buffer *packet, struct rr **rr)
   3279 {
   3280 	struct domain *domain;
   3281 	struct dname_buffer target;
   3282 	uint16_t length = 2, svcparams_length = 0;
   3283 	uint16_t size;
   3284 	const size_t mark = buffer_position(packet);
   3285 
   3286 	/* short + name + svc_params */
   3287 	if (buffer_remaining(packet) < rdlength || rdlength < length)
   3288 		return MALFORMED;
   3289 	buffer_skip(packet, length);
   3290 	if (!dname_make_from_packet_buffered(&target, packet,
   3291 		1 /* lenient */, 1))
   3292 		return MALFORMED;
   3293 	if(rdlength < buffer_position(packet) - mark)
   3294 		return MALFORMED;
   3295 	length = buffer_position(packet)-mark;
   3296 	/* For secondary, the server should accept the wireformat more
   3297 	 * leniently. So this check is skipped. */
   3298 	/*
   3299 	if(!skip_svcparams(packet, rdlength-length))
   3300 		return MALFORMED;
   3301 	if(rdlength < buffer_position(packet) - mark)
   3302 		return MALFORMED;
   3303 	*/
   3304 	svcparams_length = rdlength - length;
   3305 	buffer_skip(packet, svcparams_length);
   3306 
   3307 	size = sizeof(**rr) + 2 + sizeof(void*) + svcparams_length;
   3308 	if (!(*rr = region_alloc(domains->region, size)))
   3309 		return TRUNCATED;
   3310 	domain = domain_table_insert(domains, (void*)&target);
   3311 	domain->usage++;
   3312 	buffer_read_at(packet, mark, (*rr)->rdata, 2);
   3313 	memcpy((*rr)->rdata + 2, &domain, sizeof(void*));
   3314 	if(svcparams_length != 0)
   3315 		buffer_read_at(packet, mark + length,
   3316 			(*rr)->rdata + 2 + sizeof(void*), svcparams_length);
   3317 	(*rr)->rdlength = 2 + sizeof(void*) + svcparams_length;
   3318 	return rdlength;
   3319 }
   3320 
   3321 void
   3322 write_svcb_rdata(struct query *query, const struct rr *rr)
   3323 {
   3324 	struct domain *domain;
   3325 	const struct dname *target;
   3326 	uint8_t length;
   3327 
   3328 	assert(rr->rdlength >= 2 + sizeof(void*));
   3329 	memcpy(&domain, rr->rdata + 2, sizeof(void*));
   3330 	target = domain_dname(domain);
   3331 	buffer_write(query->packet, rr->rdata, 2);
   3332 	buffer_write(query->packet, dname_name(target), target->name_size);
   3333 	length = 2 + sizeof(void*);
   3334 	if(rr->rdlength > length)
   3335 		buffer_write(query->packet, rr->rdata + length,
   3336 			rr->rdlength - length);
   3337 }
   3338 
   3339 int
   3340 print_svcb_rdata(struct buffer *output, const struct rr *rr)
   3341 {
   3342 	uint16_t length = 2;
   3343 
   3344 	assert(rr->rdlength > length); /* It has 2+sizeof(void*) at least. */
   3345 	buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
   3346 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   3347 		return 0;
   3348 	while (length < rr->rdlength) {
   3349 		buffer_printf(output, " ");
   3350 		if (!print_svcparam(output, rr->rdlength, rr->rdata, &length))
   3351 			return 0;
   3352 	}
   3353 	if(rr->rdlength != length)
   3354 		return 0;
   3355 	return 1;
   3356 }
   3357 
   3358 int32_t
   3359 read_dsync_rdata(struct domain_table *domains, uint16_t rdlength,
   3360 	struct buffer *packet, struct rr **rr)
   3361 {
   3362 	struct dname_buffer target;
   3363 	uint16_t length = 5;
   3364 	const size_t mark = buffer_position(packet);
   3365 
   3366 	/* type + byte + short + literaldname */
   3367 	if (buffer_remaining(packet) < rdlength || rdlength < length)
   3368 		return MALFORMED;
   3369 	buffer_skip(packet, length);
   3370 	if(!dname_make_from_packet_buffered(&target, packet,
   3371 		1 /* lenient */, 1) ||
   3372 	   rdlength != buffer_position(packet) - mark)
   3373 		return MALFORMED;
   3374 	length += target.dname.name_size;
   3375 
   3376 	if (!(*rr = region_alloc(domains->region, sizeof(**rr)+length)))
   3377 		return TRUNCATED;
   3378 	buffer_read_at(packet, mark, (*rr)->rdata, 5);
   3379 	memcpy((*rr)->rdata + 5, dname_name((void*)&target),
   3380 		target.dname.name_size);
   3381 	(*rr)->rdlength = length;
   3382 	return rdlength;
   3383 }
   3384 
   3385 int
   3386 print_dsync_rdata(struct buffer *output, const struct rr *rr)
   3387 {
   3388 	uint16_t length = 5;
   3389 	if(rr->rdlength < length)
   3390 		return 0;
   3391 	buffer_printf(output, "%s %" PRIu8 " %" PRIu16 " ",
   3392 		rrtype_to_string(read_uint16(rr->rdata)), rr->rdata[2],
   3393 		read_uint16(rr->rdata+3));
   3394 	if(!print_name_literal(output, rr->rdlength, rr->rdata, &length))
   3395 		return 0;
   3396 	if(rr->rdlength != length)
   3397 		return 0;
   3398 	return 1;
   3399 }
   3400 
   3401 int32_t
   3402 read_nid_rdata(struct domain_table *domains, uint16_t rdlength,
   3403 	struct buffer *packet, struct rr **rr)
   3404 {
   3405 	if (rdlength != 10)
   3406 		return MALFORMED;
   3407 	return read_rdata(domains, rdlength, packet, rr);
   3408 }
   3409 
   3410 int
   3411 print_nid_rdata(struct buffer *output, const struct rr *rr)
   3412 {
   3413 	uint16_t length = 2;
   3414 
   3415 	if(rr->rdlength != 10)
   3416 		return 0;
   3417 	buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
   3418 	if (!print_ilnp64(output, rr->rdlength, rr->rdata, &length))
   3419 		return 0;
   3420 	if(rr->rdlength != length)
   3421 		return 0;
   3422 	return 1;
   3423 }
   3424 
   3425 int32_t
   3426 read_l32_rdata(struct domain_table *domains, uint16_t rdlength,
   3427 	struct buffer *packet, struct rr **rr)
   3428 {
   3429 	if (rdlength != 6)
   3430 		return MALFORMED;
   3431 	return read_rdata(domains, rdlength, packet, rr);
   3432 }
   3433 
   3434 int
   3435 print_l32_rdata(struct buffer *output, const struct rr *rr)
   3436 {
   3437 	uint16_t length = 2;
   3438 
   3439 	if(rr->rdlength != 6)
   3440 		return 0;
   3441 	buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
   3442 	if (!print_ip4(output, rr->rdlength, rr->rdata, &length))
   3443 		return 0;
   3444 	if(rr->rdlength != length)
   3445 		return 0;
   3446 	return 1;
   3447 }
   3448 
   3449 int32_t
   3450 read_l64_rdata(struct domain_table *domains, uint16_t rdlength,
   3451 	struct buffer *packet, struct rr **rr)
   3452 {
   3453 	if (rdlength != 10)
   3454 		return MALFORMED;
   3455 	return read_rdata(domains, rdlength, packet, rr);
   3456 }
   3457 
   3458 int
   3459 print_l64_rdata(struct buffer *output, const struct rr *rr)
   3460 {
   3461 	uint16_t length = 2;
   3462 
   3463 	if(rr->rdlength != 10)
   3464 		return 0;
   3465 	buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
   3466 	if (!print_ilnp64(output, rr->rdlength, rr->rdata, &length))
   3467 		return 0;
   3468 	if(rr->rdlength != length)
   3469 		return 0;
   3470 	return 1;
   3471 }
   3472 
   3473 int32_t
   3474 read_lp_rdata(struct domain_table *domains, uint16_t rdlength,
   3475 	struct buffer *packet, struct rr **rr)
   3476 {
   3477 	struct domain *domain;
   3478 	struct dname_buffer target;
   3479 	size_t size;
   3480 	/* short + name */
   3481 	const size_t mark = buffer_position(packet);
   3482 
   3483 	if (buffer_remaining(packet) < rdlength || rdlength < 2)
   3484 		return MALFORMED;
   3485 	buffer_skip(packet, 2);
   3486 	if (!dname_make_from_packet_buffered(&target, packet,
   3487 		1 /* lenient */, 1) ||
   3488 	    rdlength != buffer_position(packet) - mark)
   3489 		return MALFORMED;
   3490 	size = sizeof(**rr) + 2 + sizeof(void*);
   3491 	if (!(*rr = region_alloc(domains->region, size)))
   3492 		return TRUNCATED;
   3493 	domain = domain_table_insert(domains, (void*)&target);
   3494 	domain->usage++;
   3495 	buffer_read_at(packet, mark, (*rr)->rdata, 2);
   3496 	memcpy((*rr)->rdata + 2, &domain, sizeof(void*));
   3497 	(*rr)->rdlength = 2 + sizeof(void*);
   3498 	return rdlength;
   3499 }
   3500 
   3501 void
   3502 write_lp_rdata(struct query *query, const struct rr *rr)
   3503 {
   3504 	struct domain *domain;
   3505 	const struct dname *dname;
   3506 
   3507 	/* short + uncompressed name */
   3508 	assert(rr->rdlength == 2 + sizeof(void*));
   3509 	memcpy(&domain, rr->rdata + 2, sizeof(void*));
   3510 	dname = domain_dname(domain);
   3511 	buffer_write(query->packet, rr->rdata, 2);
   3512 	buffer_write(query->packet, dname_name(dname), dname->name_size);
   3513 }
   3514 
   3515 int
   3516 print_lp_rdata(struct buffer *output, const struct rr *rr)
   3517 {
   3518 	uint16_t length = 2;
   3519 
   3520 	assert(rr->rdlength == 2 + sizeof(void*));
   3521 	buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata));
   3522 	if (!print_domain(output, rr->rdlength, rr->rdata, &length))
   3523 		return 0;
   3524 	assert(rr->rdlength == length);
   3525 	return 1;
   3526 }
   3527 
   3528 int32_t
   3529 read_eui48_rdata(struct domain_table *domains, uint16_t rdlength,
   3530 	struct buffer *packet, struct rr **rr)
   3531 {
   3532 	if (rdlength != 6)
   3533 		return MALFORMED;
   3534 	return read_rdata(domains, rdlength, packet, rr);
   3535 }
   3536 
   3537 int
   3538 print_eui48_rdata(struct buffer *output, const struct rr *rr)
   3539 {
   3540 	const uint8_t *x = rr->rdata;
   3541 	if(rr->rdlength != 6)
   3542 		return 0;
   3543 	buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
   3544 		x[0], x[1], x[2], x[3], x[4], x[5]);
   3545 	return 1;
   3546 }
   3547 
   3548 int32_t
   3549 read_eui64_rdata(struct domain_table *domains, uint16_t rdlength,
   3550 	struct buffer *packet, struct rr **rr)
   3551 {
   3552 	if (rdlength != 8)
   3553 		return MALFORMED;
   3554 	return read_rdata(domains, rdlength, packet, rr);
   3555 }
   3556 
   3557 int
   3558 print_eui64_rdata(struct buffer *output, const struct rr *rr)
   3559 {
   3560 	const uint8_t *x = rr->rdata;
   3561 	if(rr->rdlength != 8)
   3562 		return 0;
   3563 	buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
   3564 		x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]);
   3565 	return 1;
   3566 }
   3567 
   3568 int32_t
   3569 read_uri_rdata(struct domain_table *domains, uint16_t rdlength,
   3570 	struct buffer *packet, struct rr **rr)
   3571 {
   3572 	/* short + short + long string */
   3573 	if (rdlength < 4)
   3574 		return MALFORMED;
   3575 	return read_rdata(domains, rdlength, packet, rr);
   3576 }
   3577 
   3578 int
   3579 print_uri_rdata(struct buffer *output, const struct rr *rr)
   3580 {
   3581 	uint16_t length = 4;
   3582 
   3583 	if(rr->rdlength < length)
   3584 		return 0;
   3585 	buffer_printf(
   3586 		output, "%" PRIu16 " %" PRIu16 " ",
   3587 		read_uint16(rr->rdata), read_uint16(rr->rdata + 2));
   3588 	if(!print_text(output, rr->rdlength, rr->rdata, &length))
   3589 		return 0;
   3590 	if(rr->rdlength != length)
   3591 		return 0;
   3592 	return 1;
   3593 }
   3594 
   3595 int
   3596 print_resinfo_rdata(struct buffer *output, const struct rr *rr)
   3597 {
   3598 	uint16_t length = 0;
   3599 	if(!print_unquoteds(output, rr->rdlength, rr->rdata, &length))
   3600 		return 0;
   3601 	if(rr->rdlength != length)
   3602 		return 0;
   3603 	return 1;
   3604 }
   3605 
   3606 int32_t
   3607 read_caa_rdata(struct domain_table *domains, uint16_t rdlength,
   3608 	struct buffer *packet, struct rr **rr)
   3609 {
   3610 	const size_t mark = buffer_position(packet);
   3611 	uint16_t length = 1;
   3612 
   3613 	/* byte + string + long string */
   3614 	if (buffer_remaining(packet) < rdlength || rdlength < 2)
   3615 		return MALFORMED;
   3616 	buffer_skip(packet, 1);
   3617 	if (skip_string(packet, rdlength, &length) < 0 || rdlength < length)
   3618 		return MALFORMED;
   3619 	buffer_set_position(packet, mark);
   3620 	return read_rdata(domains, rdlength, packet, rr);
   3621 }
   3622 
   3623 int
   3624 print_caa_rdata(struct buffer *output, const struct rr *rr)
   3625 {
   3626 	uint16_t length = 1;
   3627 
   3628 	if(rr->rdlength < 2)
   3629 		return 0;
   3630 	buffer_printf(output, "%" PRIu8 " ", rr->rdata[0]);
   3631 
   3632 	length = 2 + rr->rdata[1];
   3633 	if (rr->rdlength < length)
   3634 		return 0;
   3635 
   3636 	for (uint16_t i = 2; i < length; ++i) {
   3637 		char ch = (char) rr->rdata[i];
   3638 		if (isdigit((unsigned char)ch) || islower((unsigned char)ch))
   3639 			buffer_printf(output, "%c", ch);
   3640 		else	return 0;
   3641 	}
   3642 
   3643 	buffer_printf(output, " ");
   3644 	if (!print_text(output, rr->rdlength, rr->rdata, &length))
   3645 		return 0;
   3646 	if(rr->rdlength != length)
   3647 		return 0;
   3648 	return 1;
   3649 }
   3650 
   3651 int
   3652 print_doa_rdata(struct buffer *output, const struct rr *rr)
   3653 {
   3654 	uint16_t length = 9;
   3655 	if(rr->rdlength < length)
   3656 		return 0;
   3657 	buffer_printf(output, "%" PRIu32 " %" PRIu32 " %" PRIu8 " ",
   3658 		read_uint32(rr->rdata), read_uint32(rr->rdata+4),
   3659 		rr->rdata[8]);
   3660 	if(!print_string(output, rr->rdlength, rr->rdata, &length))
   3661 		return 0;
   3662 	buffer_printf(output, " ");
   3663 	if(rr->rdlength == length) {
   3664 		/* The base64 string is empty, and DOA uses '-' for that. */
   3665 		buffer_printf(output, "-");
   3666 	} else {
   3667 		if(!print_base64(output, rr->rdlength, rr->rdata, &length))
   3668 			return 0;
   3669 	}
   3670 	if(rr->rdlength != length)
   3671 		return 0;
   3672 	return 1;
   3673 }
   3674 
   3675 int32_t
   3676 read_amtrelay_rdata(struct domain_table *domains, uint16_t rdlength,
   3677 	struct buffer *packet, struct rr **rr)
   3678 {
   3679 	struct dname_buffer relay;
   3680 	const uint8_t *relay_rdata;
   3681 	uint8_t relay_length = 0;
   3682 	const size_t mark = buffer_position(packet);
   3683 
   3684 	/* byte + byte + relay */
   3685 	if (buffer_remaining(packet) < rdlength || rdlength < 2)
   3686 		return MALFORMED;
   3687 
   3688 	buffer_skip(packet, 2);
   3689 
   3690 	switch (buffer_read_u8_at(packet, mark + 1)&AMTRELAY_TYPE_MASK) {
   3691 	case AMTRELAY_NOGATEWAY:
   3692 		relay_length = 0;
   3693 		relay_rdata = NULL;
   3694 		break;
   3695 	case AMTRELAY_IP4:
   3696 		relay_length = 4;
   3697 		relay_rdata = buffer_current(packet);
   3698 		if (rdlength < 2 + relay_length)
   3699 			return MALFORMED;
   3700 		buffer_skip(packet, relay_length);
   3701 		break;
   3702 	case AMTRELAY_IP6:
   3703 		relay_length = 16;
   3704 		relay_rdata = buffer_current(packet);
   3705 		if (rdlength < 2 + relay_length)
   3706 			return MALFORMED;
   3707 		buffer_skip(packet, relay_length);
   3708 		break;
   3709 	case AMTRELAY_DNAME:
   3710 		/* The dname is stored as literal dname. On the wire
   3711 		 * skip possibly compressed format, in the rdata there
   3712 		 * is an uncompressed wire format. */
   3713 		if(!dname_make_from_packet_buffered(&relay, packet,
   3714 			1 /* lenient */, 1))
   3715 			return MALFORMED;
   3716 		if(rdlength < buffer_position(packet) - mark)
   3717 			return MALFORMED;
   3718 		relay_length = relay.dname.name_size;
   3719 		relay_rdata = dname_name((void*)&relay);
   3720 		break;
   3721 	default:
   3722 		return MALFORMED;
   3723 	}
   3724 	if(rdlength != buffer_position(packet) - mark)
   3725 		return MALFORMED; /* trailing bytes */
   3726 
   3727 	if (!(*rr = region_alloc(domains->region,
   3728 		sizeof(**rr) + 2 + relay_length)))
   3729 		return TRUNCATED;
   3730 
   3731 	buffer_read_at(packet, mark, (*rr)->rdata, 2);
   3732 	if(relay_rdata)
   3733 		memcpy((*rr)->rdata + 2, relay_rdata, relay_length);
   3734 	(*rr)->rdlength = 2 + relay_length;
   3735 	return rdlength;
   3736 }
   3737 
   3738 int
   3739 print_amtrelay_rdata(struct buffer *output, const struct rr *rr)
   3740 {
   3741 	uint16_t length = 2;
   3742 	uint8_t relay_type;
   3743 
   3744 	if(rr->rdlength < length)
   3745 		return 0;
   3746 	relay_type = rr->rdata[1]&AMTRELAY_TYPE_MASK;
   3747 	buffer_printf(output, "%" PRIu8 " %c %" PRIu8,
   3748 		rr->rdata[0],
   3749 		(rr->rdata[1] & AMTRELAY_DISCOVERY_OPTIONAL_MASK ? '1' : '0'),
   3750 		relay_type);
   3751 	switch(relay_type) {
   3752 	case AMTRELAY_NOGATEWAY:
   3753 		buffer_printf(output, " .");
   3754 		break;
   3755 	case AMTRELAY_IP4:
   3756 		buffer_printf(output, " ");
   3757 		if(!print_ip4(output, rr->rdlength, rr->rdata, &length))
   3758 			return 0;
   3759 		break;
   3760 	case AMTRELAY_IP6:
   3761 		buffer_printf(output, " ");
   3762 		if(!print_ip6(output, rr->rdlength, rr->rdata, &length))
   3763 			return 0;
   3764 		break;
   3765 	case AMTRELAY_DNAME:
   3766 		buffer_printf(output, " ");
   3767 		if(!print_name_literal(output, rr->rdlength, rr->rdata,
   3768 			&length))
   3769 			return 0;
   3770 		break;
   3771 	default:
   3772 		return 0;
   3773 	}
   3774 
   3775 	if(rr->rdlength != length)
   3776 		return 0;
   3777 	return 1;
   3778 }
   3779 
   3780 int32_t
   3781 amtrelay_relay_length(uint16_t rdlength, const uint8_t *rdata, uint16_t offset,
   3782 	struct domain** domain)
   3783 {
   3784 	/* The amtrelay relay length depends only on earlier bytes, so both
   3785 	 * the in-memory and uncompressed wireformat refer to the same
   3786 	 * earlier bytes. Also the domain name is stored literally, so it
   3787 	 * does not need to return a reference. */
   3788 	uint8_t relay_type;
   3789 	*domain = NULL;
   3790 	/* Calculate the relay length, based on the relay type.
   3791 	 * That is stored in an earlier field. */
   3792 	if(rdlength < 2 || offset < 2)
   3793 		return -1; /* too short */
   3794 	relay_type = rdata[1]&AMTRELAY_TYPE_MASK;
   3795 	switch(relay_type) {
   3796 	case AMTRELAY_NOGATEWAY:
   3797 		return 0;
   3798 	case AMTRELAY_IP4:
   3799 		return 4;
   3800 	case AMTRELAY_IP6:
   3801 		return 16;
   3802 	case AMTRELAY_DNAME:
   3803 		return buf_dname_length(rdata+offset, rdlength-offset);
   3804 	default:
   3805 		/* Unknown relay type. */
   3806 		break;
   3807 	}
   3808 	return -1;
   3809 }
   3810 
   3811 int
   3812 print_ipn_rdata(struct buffer *output, const struct rr *rr)
   3813 {
   3814 	uint64_t data;
   3815 
   3816 	if(rr->rdlength < sizeof(data))
   3817 		return 0;
   3818 	data = read_uint64(rr->rdata);
   3819 	buffer_printf(output, "%llu", (unsigned long long) data);
   3820 	return 1;
   3821 }
   3822 
   3823 int32_t
   3824 read_dlv_rdata(struct domain_table *domains, uint16_t rdlength,
   3825 	struct buffer *packet, struct rr **rr)
   3826 {
   3827 	/* short + byte + byte + binary */
   3828 	if (rdlength < 4)
   3829 		return MALFORMED;
   3830 	return read_rdata(domains, rdlength, packet, rr);
   3831 }
   3832 
   3833 int
   3834 print_dlv_rdata(struct buffer *output, const struct rr *rr)
   3835 {
   3836 	uint16_t length = 4;
   3837 
   3838 	if(rr->rdlength < length)
   3839 		return 0;
   3840 	buffer_printf(
   3841 		output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ",
   3842 		read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]);
   3843 	if (!print_base16(output, rr->rdlength, rr->rdata, &length))
   3844 		return 0;
   3845 	if(rr->rdlength != length)
   3846 		return 0;
   3847 	return 1;
   3848 }
   3849 
   3850 int
   3851 print_rdata(buffer_type *output, const nsd_type_descriptor_type *descriptor,
   3852 	const rr_type *rr)
   3853 {
   3854 	size_t saved_position = buffer_position(output);
   3855 	/* If print_rdata is going to print "", omit the tab printout. */
   3856 	if(!(rr->type == TYPE_APL && rr->rdlength == 0))
   3857 		buffer_printf(output, "\t");
   3858 	if(!descriptor->print_rdata(output, rr)) {
   3859 		buffer_set_position(output, saved_position);
   3860 		return 0;
   3861 	}
   3862 	return 1;
   3863 }
   3864 
   3865 /*
   3866  * Compare two wireformat byte strings. In canonical order for this comparison.
   3867  * Sorts equal as equal, and if there is a prefix match, the shorter one is
   3868  * before the longer one; so it sorts like normalized domain names,
   3869  * ab ac acd ace ad ae af.  And ab < abc , abc < ac .
   3870  * @param b1: byte string1.
   3871  * @param len1: length of b1.
   3872  * @param b2: byte string2.
   3873  * @param len2: length of b2
   3874  * @return comparison, -1, 0, 1.
   3875  */
   3876 static int
   3877 compare_bytestring(const uint8_t* b1, uint16_t len1, const uint8_t* b2,
   3878 	uint16_t len2)
   3879 {
   3880 	uint16_t blen;
   3881 	int res;
   3882 
   3883 	if(len1 == 0 && len2 == 0)
   3884 		return 0;
   3885 	if(len1 == 0 && len2 != 0)
   3886 		return -1;
   3887 	if(len1 != 0 && len2 == 0)
   3888 		return 1;
   3889 	blen = len1;
   3890 	if(len2 < blen)
   3891 		blen = len2;
   3892 	res = memcmp(b1, b2, blen);
   3893 	if(res != 0)
   3894 		return res;
   3895 	if(len1 < len2)
   3896 		return -1;
   3897 	if(len1 > len2)
   3898 		return 1;
   3899 	/* len1 == len2 and equal. */
   3900 	return 0;
   3901 }
   3902 
   3903 int
   3904 equal_rr_rdata(const nsd_type_descriptor_type *descriptor,
   3905 	const struct rr *rr1, const struct rr *rr2)
   3906 {
   3907 	size_t i;
   3908 	uint16_t offset = 0;
   3909 	int res;
   3910 
   3911 	if(!descriptor->has_references) {
   3912 		/* Compare the wireformat of the rdata. */
   3913 		res = compare_bytestring(rr1->rdata, rr1->rdlength,
   3914 			rr2->rdata, rr2->rdlength);
   3915 		if(res != 0)
   3916 			return 0;
   3917 		return 1;
   3918 	}
   3919 
   3920 	for(i=0; i < descriptor->rdata.length; i++) {
   3921 		uint16_t field_len1, field_len2;
   3922 		struct domain* domain1, *domain2;
   3923 		int malf1 = 0, malf2 = 0;
   3924 		/* The fields are equal up to this point. */
   3925 		if((rr1->rdlength == offset || rr2->rdlength == offset) &&
   3926 			descriptor->rdata.fields[i].is_optional) {
   3927 			/* There are no more rdata fields. */
   3928 			/* Check lengths. */
   3929 			if(rr1->rdlength == rr2->rdlength)
   3930 				return 1;
   3931 			else
   3932 				return 0;
   3933 		}
   3934 		if(!lookup_rdata_field_entry(descriptor, i, rr1, offset,
   3935 			&field_len1, &domain1))
   3936 			malf1 = 1; /* malformed rdata buffer */
   3937 		if(!lookup_rdata_field_entry(descriptor, i, rr2, offset,
   3938 			&field_len2, &domain2))
   3939 			malf2 = 1; /* malformed rdata buffer */
   3940 		if(malf1 || malf2) {
   3941 			/* Malformed entries sort last, and are sorted
   3942 			 * equal with other malformed entries. */
   3943 			if(malf1 && malf2)
   3944 				return 1;
   3945 			else
   3946 				return 0;
   3947 		}
   3948 		/* Compare the two fields. */
   3949 		/* If they have a different type field, they are not the
   3950 		 * same. */
   3951 		if(domain1 && !domain2)
   3952 			return 0;
   3953 		if(!domain1 && domain2)
   3954 			return 0;
   3955 		if(domain1 && domain2) {
   3956 			/* Handle RDATA_COMPRESSED_DNAME and
   3957 			 * RDATA_UNCOMPRESSED_DNAME fields. */
   3958 			res = dname_compare(domain_dname(domain1),
   3959 				domain_dname(domain2));
   3960 			if(res != 0)
   3961 				return 0;
   3962 		} else {
   3963 			res = compare_bytestring(rr1->rdata + offset,
   3964 				field_len1, rr2->rdata + offset, field_len2);
   3965 			if(res != 0)
   3966 				return 0;
   3967 		}
   3968 		/* The fields are equal, field_len1 == field_len2. */
   3969 		offset += field_len1;
   3970 	}
   3971 	return 1;
   3972 }
   3973 
   3974 int
   3975 equal_rr_rdata_uncompressed_wire(const nsd_type_descriptor_type *descriptor,
   3976 	const struct rr *rr1, const uint8_t* rr2_rdata, uint16_t rr2_rdlen)
   3977 {
   3978 	size_t i;
   3979 	uint16_t offset1 = 0, offset2 = 0;
   3980 	int res;
   3981 
   3982 	if(!descriptor->has_references) {
   3983 		/* Compare the wireformat of the rdata. */
   3984 		res = compare_bytestring(rr1->rdata, rr1->rdlength,
   3985 			rr2_rdata, rr2_rdlen);
   3986 		if(res != 0)
   3987 			return 0;
   3988 		return 1;
   3989 	}
   3990 
   3991 	for(i=0; i < descriptor->rdata.length; i++) {
   3992 		uint16_t field_len1, field_len2;
   3993 		struct domain* domain1, *domain2;
   3994 		int malf1 = 0, malf2 = 0;
   3995 		/* The fields are equal up to this point. */
   3996 		if((rr1->rdlength == offset1 || rr2_rdlen == offset2) &&
   3997 			descriptor->rdata.fields[i].is_optional) {
   3998 			/* There are no more rdata fields. */
   3999 			/* Check lengths. */
   4000 			int remain1 = rr1->rdlength - offset1;
   4001 			int remain2 = rr2_rdlen - offset2;
   4002 			if(remain1 < remain2)
   4003 				return 0;
   4004 			if(remain1 > remain2)
   4005 				return 0;
   4006 			/* It is equal. */
   4007 			return 1;
   4008 		}
   4009 		if(!lookup_rdata_field_entry(descriptor, i, rr1, offset1,
   4010 			&field_len1, &domain1))
   4011 			malf1 = 1; /* malformed rdata buffer */
   4012 		if(!lookup_rdata_field_entry_uncompressed_wire(descriptor, i,
   4013 			rr2_rdata, rr2_rdlen, offset2, &field_len2, &domain2))
   4014 			malf2 = 1; /* malformed rdata buffer */
   4015 		if(malf1 || malf2) {
   4016 			/* Malformed entries sort last, and are sorted
   4017 			 * equal with other malformed entries. */
   4018 			if(!malf1 && malf2)
   4019 				return 0;
   4020 			if(malf1 && !malf2)
   4021 				return 0;
   4022 			return 1;
   4023 		}
   4024 		/* Compare the two fields. */
   4025 		/* If they have a different type field, they are not the
   4026 		 * same. */
   4027 		if(domain1) {
   4028 			if(domain2) {
   4029 				/* Handle RDATA_COMPRESSED_DNAME and
   4030 				 * RDATA_UNCOMPRESSED_DNAME fields. */
   4031 				res = dname_compare(domain_dname(domain1),
   4032 					domain_dname(domain2));
   4033 				if(res != 0)
   4034 					return 0;
   4035 			} else {
   4036 				uint16_t dname_len2 = buf_dname_length(
   4037 					rr2_rdata+offset2,
   4038 					rr2_rdlen-offset2);
   4039 				if(domain_dname(domain1)->name_size !=
   4040 					dname_len2) {
   4041 					/* not the same length dnames. */
   4042 					return 0;
   4043 				}
   4044 				if(!dname_equal_nocase(
   4045 					(uint8_t*)dname_name(domain_dname(
   4046 						domain1)),
   4047 					(uint8_t*)rr2_rdata+offset2,
   4048 					dname_len2)) {
   4049 					/* name comparison not equal. */
   4050 					return 0;
   4051 				}
   4052 			}
   4053 		} else {
   4054 			if(domain2) {
   4055 				uint16_t dname_len1 = buf_dname_length(
   4056 					rr1->rdata + offset1,
   4057 					rr1->rdlength-offset1);
   4058 				if(dname_len1 !=
   4059 					domain_dname(domain2)->name_size) {
   4060 					/* not the same length dnames. */
   4061 					return 0;
   4062 				}
   4063 				if(!dname_equal_nocase(
   4064 					(uint8_t*)rr1->rdata+offset1,
   4065 					(uint8_t*)dname_name(domain_dname(
   4066 						domain2)),
   4067 					dname_len1)) {
   4068 					/* name comparison not equal. */
   4069 					return 0;
   4070 				}
   4071 			} else {
   4072 				res = compare_bytestring(rr1->rdata + offset1,
   4073 					field_len1, rr2_rdata + offset2,
   4074 					field_len2);
   4075 				if(res != 0)
   4076 					return 0;
   4077 			}
   4078 		}
   4079 		offset1 += field_len1;
   4080 		offset2 += field_len2;
   4081 	}
   4082 	return 1;
   4083 }
   4084 
   4085 struct domain*
   4086 retrieve_rdata_ref_domain_offset(const struct rr* rr, uint16_t offset)
   4087 {
   4088 	struct domain *domain;
   4089 	if(rr->rdlength < offset+sizeof(void*))
   4090 		return NULL;
   4091 	memcpy(&domain, rr->rdata+offset, sizeof(void*));
   4092 	return domain;
   4093 }
   4094 
   4095 struct domain*
   4096 retrieve_rdata_ref_domain(const struct rr* rr)
   4097 {
   4098 	struct domain *domain;
   4099 	if(rr->rdlength < sizeof(void*))
   4100 		return NULL;
   4101 	memcpy(&domain, rr->rdata, sizeof(void*));
   4102 	return domain;
   4103 }
   4104 
   4105 struct domain*
   4106 retrieve_ns_ref_domain(const struct rr* rr)
   4107 {
   4108 	assert(rr->type == TYPE_NS);
   4109 	return retrieve_rdata_ref_domain(rr);
   4110 }
   4111 
   4112 struct domain*
   4113 retrieve_cname_ref_domain(const struct rr* rr)
   4114 {
   4115 	assert(rr->type == TYPE_CNAME);
   4116 	return retrieve_rdata_ref_domain(rr);
   4117 }
   4118 
   4119 struct domain*
   4120 retrieve_dname_ref_domain(const struct rr* rr)
   4121 {
   4122 	assert(rr->type == TYPE_DNAME);
   4123 	return retrieve_rdata_ref_domain(rr);
   4124 }
   4125 
   4126 struct domain*
   4127 retrieve_mb_ref_domain(const struct rr* rr)
   4128 {
   4129 	assert(rr->type == TYPE_MB);
   4130 	return retrieve_rdata_ref_domain(rr);
   4131 }
   4132 
   4133 struct domain*
   4134 retrieve_mx_ref_domain(const struct rr* rr)
   4135 {
   4136 	assert(rr->type == TYPE_MX);
   4137 	return retrieve_rdata_ref_domain_offset(rr, 2);
   4138 }
   4139 
   4140 struct domain*
   4141 retrieve_kx_ref_domain(const struct rr* rr)
   4142 {
   4143 	assert(rr->type == TYPE_KX);
   4144 	return retrieve_rdata_ref_domain_offset(rr, 2);
   4145 }
   4146 
   4147 struct domain*
   4148 retrieve_rt_ref_domain(const struct rr* rr)
   4149 {
   4150 	assert(rr->type == TYPE_RT);
   4151 	return retrieve_rdata_ref_domain_offset(rr, 2);
   4152 }
   4153 
   4154 struct domain*
   4155 retrieve_srv_ref_domain(const struct rr* rr)
   4156 {
   4157 	assert(rr->type == TYPE_SRV);
   4158 	return retrieve_rdata_ref_domain_offset(rr, 6);
   4159 }
   4160 
   4161 struct domain*
   4162 retrieve_ptr_ref_domain(const struct rr* rr)
   4163 {
   4164 	assert(rr->type == TYPE_PTR);
   4165 	return retrieve_rdata_ref_domain(rr);
   4166 }
   4167 
   4168 int
   4169 retrieve_soa_rdata_serial(const struct rr* rr, uint32_t* serial)
   4170 {
   4171 	assert(rr->type == TYPE_SOA);
   4172 	if(rr->rdlength < 20 + 2*sizeof(void*))
   4173 		return 0;
   4174 	/* primary mail serial[4] refresh[4] retry[4] expire[4] minimum[4] */
   4175 	*serial = read_uint32(rr->rdata+2*sizeof(void*));
   4176 	return 1;
   4177 }
   4178 
   4179 int
   4180 retrieve_soa_rdata_minttl(const struct rr* rr, uint32_t* minttl)
   4181 {
   4182 	assert(rr->type == TYPE_SOA);
   4183 	if(rr->rdlength < 20 + 2*sizeof(void*))
   4184 		return 0;
   4185 	/* primary mail serial[4] refresh[4] retry[4] expire[4] minimum[4] */
   4186 	*minttl = read_uint32(rr->rdata+2*sizeof(void*)+16);
   4187 	return 1;
   4188 }
   4189 
   4190 struct dname* retrieve_cname_ref_dname(const struct rr* rr)
   4191 {
   4192 	struct domain* domain;
   4193 	assert(rr->type == TYPE_CNAME);
   4194 	domain = retrieve_rdata_ref_domain(rr);
   4195 	if(!domain)
   4196 		return NULL;
   4197 	return domain_dname(domain);
   4198 }
   4199 
   4200 void
   4201 rr_lower_usage(namedb_type* db, rr_type* rr)
   4202 {
   4203 	const nsd_type_descriptor_type *descriptor =
   4204 		nsd_type_descriptor(rr->type);
   4205 	uint16_t offset = 0;
   4206 	size_t i;
   4207 	for(i=0; i<descriptor->rdata.length; i++) {
   4208 		uint16_t field_len;
   4209 		struct domain* domain;
   4210 		if(rr->rdlength == offset &&
   4211 			descriptor->rdata.fields[i].is_optional)
   4212 			break;
   4213 		if(!lookup_rdata_field_entry(descriptor, i, rr, offset,
   4214 			&field_len, &domain))
   4215 			break;
   4216 		if(domain) {
   4217 			assert(domain->usage > 0);
   4218 			domain->usage --;
   4219 			if(domain->usage == 0)
   4220 				domain_table_deldomain(db,
   4221 					domain);
   4222 		}
   4223 		offset += field_len;
   4224 	}
   4225 }
   4226 
   4227 const char*
   4228 read_rdata_fail_str(int32_t code)
   4229 {
   4230 	switch(code) {
   4231 	case TRUNCATED:
   4232 		return "out of memory";
   4233 	case MALFORMED:
   4234 		return "malformed rdata fields";
   4235 	default:
   4236 		break;
   4237 	}
   4238 	return "failed to read rdata fields";
   4239 }
   4240