PageRenderTime 246ms CodeModel.GetById 120ms app.highlight 113ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/bind9/lib/dns/rdata.c

https://bitbucket.org/freebsd/freebsd-head/
C | 1921 lines | 1446 code | 320 blank | 155 comment | 362 complexity | 2d127660783b6d128692f4d916a053ff MD5 | raw file
   1/*
   2 * Copyright (C) 2004-2012  Internet Systems Consortium, Inc. ("ISC")
   3 * Copyright (C) 1998-2003  Internet Software Consortium.
   4 *
   5 * Permission to use, copy, modify, and/or distribute this software for any
   6 * purpose with or without fee is hereby granted, provided that the above
   7 * copyright notice and this permission notice appear in all copies.
   8 *
   9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  11 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15 * PERFORMANCE OF THIS SOFTWARE.
  16 */
  17
  18/* $Id$ */
  19
  20/*! \file */
  21
  22#include <config.h>
  23#include <ctype.h>
  24
  25#include <isc/base64.h>
  26#include <isc/hex.h>
  27#include <isc/lex.h>
  28#include <isc/mem.h>
  29#include <isc/parseint.h>
  30#include <isc/print.h>
  31#include <isc/string.h>
  32#include <isc/stdlib.h>
  33#include <isc/util.h>
  34
  35#include <dns/callbacks.h>
  36#include <dns/cert.h>
  37#include <dns/compress.h>
  38#include <dns/enumtype.h>
  39#include <dns/keyflags.h>
  40#include <dns/keyvalues.h>
  41#include <dns/message.h>
  42#include <dns/rcode.h>
  43#include <dns/rdata.h>
  44#include <dns/rdataclass.h>
  45#include <dns/rdatastruct.h>
  46#include <dns/rdatatype.h>
  47#include <dns/result.h>
  48#include <dns/secalg.h>
  49#include <dns/secproto.h>
  50#include <dns/time.h>
  51#include <dns/ttl.h>
  52
  53#define RETERR(x) \
  54	do { \
  55		isc_result_t _r = (x); \
  56		if (_r != ISC_R_SUCCESS) \
  57			return (_r); \
  58	} while (0)
  59
  60#define RETTOK(x) \
  61	do { \
  62		isc_result_t _r = (x); \
  63		if (_r != ISC_R_SUCCESS) { \
  64			isc_lex_ungettoken(lexer, &token); \
  65			return (_r); \
  66		} \
  67	} while (0)
  68
  69#define DNS_AS_STR(t) ((t).value.as_textregion.base)
  70
  71#define ARGS_FROMTEXT	int rdclass, dns_rdatatype_t type, \
  72			isc_lex_t *lexer, dns_name_t *origin, \
  73			unsigned int options, isc_buffer_t *target, \
  74			dns_rdatacallbacks_t *callbacks
  75
  76#define ARGS_TOTEXT	dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, \
  77			isc_buffer_t *target
  78
  79#define ARGS_FROMWIRE	int rdclass, dns_rdatatype_t type, \
  80			isc_buffer_t *source, dns_decompress_t *dctx, \
  81			unsigned int options, isc_buffer_t *target
  82
  83#define ARGS_TOWIRE	dns_rdata_t *rdata, dns_compress_t *cctx, \
  84			isc_buffer_t *target
  85
  86#define ARGS_COMPARE	const dns_rdata_t *rdata1, const dns_rdata_t *rdata2
  87
  88#define ARGS_FROMSTRUCT	int rdclass, dns_rdatatype_t type, \
  89			void *source, isc_buffer_t *target
  90
  91#define ARGS_TOSTRUCT	dns_rdata_t *rdata, void *target, isc_mem_t *mctx
  92
  93#define ARGS_FREESTRUCT void *source
  94
  95#define ARGS_ADDLDATA	dns_rdata_t *rdata, dns_additionaldatafunc_t add, \
  96			void *arg
  97
  98#define ARGS_DIGEST	dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg
  99
 100#define ARGS_CHECKOWNER dns_name_t *name, dns_rdataclass_t rdclass, \
 101			dns_rdatatype_t type, isc_boolean_t wildcard
 102
 103#define ARGS_CHECKNAMES dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad
 104
 105
 106/*%
 107 * Context structure for the totext_ functions.
 108 * Contains formatting options for rdata-to-text
 109 * conversion.
 110 */
 111typedef struct dns_rdata_textctx {
 112	dns_name_t *origin;	/*%< Current origin, or NULL. */
 113	unsigned int flags;	/*%< DNS_STYLEFLAG_*  */
 114	unsigned int width;	/*%< Width of rdata column. */
 115	const char *linebreak;	/*%< Line break string. */
 116} dns_rdata_textctx_t;
 117
 118static isc_result_t
 119txt_totext(isc_region_t *source, isc_buffer_t *target);
 120
 121static isc_result_t
 122txt_fromtext(isc_textregion_t *source, isc_buffer_t *target);
 123
 124static isc_result_t
 125txt_fromwire(isc_buffer_t *source, isc_buffer_t *target);
 126
 127static isc_boolean_t
 128name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target);
 129
 130static unsigned int
 131name_length(dns_name_t *name);
 132
 133static isc_result_t
 134str_totext(const char *source, isc_buffer_t *target);
 135
 136static isc_result_t
 137inet_totext(int af, isc_region_t *src, isc_buffer_t *target);
 138
 139static isc_boolean_t
 140buffer_empty(isc_buffer_t *source);
 141
 142static void
 143buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region);
 144
 145static isc_result_t
 146uint32_tobuffer(isc_uint32_t, isc_buffer_t *target);
 147
 148static isc_result_t
 149uint16_tobuffer(isc_uint32_t, isc_buffer_t *target);
 150
 151static isc_result_t
 152uint8_tobuffer(isc_uint32_t, isc_buffer_t *target);
 153
 154static isc_result_t
 155name_tobuffer(dns_name_t *name, isc_buffer_t *target);
 156
 157static isc_uint32_t
 158uint32_fromregion(isc_region_t *region);
 159
 160static isc_uint16_t
 161uint16_fromregion(isc_region_t *region);
 162
 163static isc_uint8_t
 164uint8_fromregion(isc_region_t *region);
 165
 166static isc_uint8_t
 167uint8_consume_fromregion(isc_region_t *region);
 168
 169static isc_result_t
 170mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);
 171
 172static int
 173hexvalue(char value);
 174
 175static int
 176decvalue(char value);
 177
 178static isc_result_t
 179btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target);
 180
 181static isc_result_t
 182atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target);
 183
 184static void
 185default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *, ...)
 186     ISC_FORMAT_PRINTF(2, 3);
 187
 188static void
 189fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...),
 190	       dns_rdatacallbacks_t *callbacks, const char *name,
 191	       unsigned long line, isc_token_t *token, isc_result_t result);
 192
 193static void
 194fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks);
 195
 196static isc_result_t
 197rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
 198	     isc_buffer_t *target);
 199
 200static void
 201warn_badname(dns_name_t *name, isc_lex_t *lexer,
 202	     dns_rdatacallbacks_t *callbacks);
 203
 204static void
 205warn_badmx(isc_token_t *token, isc_lex_t *lexer,
 206	   dns_rdatacallbacks_t *callbacks);
 207
 208static isc_uint16_t
 209uint16_consume_fromregion(isc_region_t *region);
 210
 211static isc_result_t
 212unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
 213	       isc_buffer_t *target);
 214
 215static inline int
 216getquad(const void *src, struct in_addr *dst,
 217	isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks)
 218{
 219	int result;
 220	struct in_addr *tmp;
 221
 222	result = inet_aton(src, dst);
 223	if (result == 1 && callbacks != NULL &&
 224	    inet_pton(AF_INET, src, &tmp) != 1) {
 225		const char *name = isc_lex_getsourcename(lexer);
 226		if (name == NULL)
 227			name = "UNKNOWN";
 228		(*callbacks->warn)(callbacks, "%s:%lu: \"%s\" "
 229				   "is not a decimal dotted quad", name,
 230				   isc_lex_getsourceline(lexer), src);
 231	}
 232	return (result);
 233}
 234
 235static inline isc_result_t
 236name_duporclone(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) {
 237
 238	if (mctx != NULL)
 239		return (dns_name_dup(source, mctx, target));
 240	dns_name_clone(source, target);
 241	return (ISC_R_SUCCESS);
 242}
 243
 244static inline void *
 245mem_maybedup(isc_mem_t *mctx, void *source, size_t length) {
 246	void *new;
 247
 248	if (mctx == NULL)
 249		return (source);
 250	new = isc_mem_allocate(mctx, length);
 251	if (new != NULL)
 252		memcpy(new, source, length);
 253
 254	return (new);
 255}
 256
 257static const char hexdigits[] = "0123456789abcdef";
 258static const char decdigits[] = "0123456789";
 259
 260#include "code.h"
 261
 262#define META 0x0001
 263#define RESERVED 0x0002
 264
 265/***
 266 *** Initialization
 267 ***/
 268
 269void
 270dns_rdata_init(dns_rdata_t *rdata) {
 271
 272	REQUIRE(rdata != NULL);
 273
 274	rdata->data = NULL;
 275	rdata->length = 0;
 276	rdata->rdclass = 0;
 277	rdata->type = 0;
 278	rdata->flags = 0;
 279	ISC_LINK_INIT(rdata, link);
 280	/* ISC_LIST_INIT(rdata->list); */
 281}
 282
 283void
 284dns_rdata_reset(dns_rdata_t *rdata) {
 285
 286	REQUIRE(rdata != NULL);
 287
 288	REQUIRE(!ISC_LINK_LINKED(rdata, link));
 289	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
 290
 291	rdata->data = NULL;
 292	rdata->length = 0;
 293	rdata->rdclass = 0;
 294	rdata->type = 0;
 295	rdata->flags = 0;
 296}
 297
 298/***
 299 ***
 300 ***/
 301
 302void
 303dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target) {
 304
 305	REQUIRE(src != NULL);
 306	REQUIRE(target != NULL);
 307
 308	REQUIRE(DNS_RDATA_INITIALIZED(target));
 309
 310	REQUIRE(DNS_RDATA_VALIDFLAGS(src));
 311	REQUIRE(DNS_RDATA_VALIDFLAGS(target));
 312
 313	target->data = src->data;
 314	target->length = src->length;
 315	target->rdclass = src->rdclass;
 316	target->type = src->type;
 317	target->flags = src->flags;
 318}
 319
 320
 321/***
 322 *** Comparisons
 323 ***/
 324
 325int
 326dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) {
 327	int result = 0;
 328	isc_boolean_t use_default = ISC_FALSE;
 329
 330	REQUIRE(rdata1 != NULL);
 331	REQUIRE(rdata2 != NULL);
 332	REQUIRE(rdata1->length == 0 || rdata1->data != NULL);
 333	REQUIRE(rdata2->length == 0 || rdata2->data != NULL);
 334	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1));
 335	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2));
 336
 337	if (rdata1->rdclass != rdata2->rdclass)
 338		return (rdata1->rdclass < rdata2->rdclass ? -1 : 1);
 339
 340	if (rdata1->type != rdata2->type)
 341		return (rdata1->type < rdata2->type ? -1 : 1);
 342
 343	COMPARESWITCH
 344
 345	if (use_default) {
 346		isc_region_t r1;
 347		isc_region_t r2;
 348
 349		dns_rdata_toregion(rdata1, &r1);
 350		dns_rdata_toregion(rdata2, &r2);
 351		result = isc_region_compare(&r1, &r2);
 352	}
 353	return (result);
 354}
 355
 356int
 357dns_rdata_casecompare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) {
 358	int result = 0;
 359	isc_boolean_t use_default = ISC_FALSE;
 360
 361	REQUIRE(rdata1 != NULL);
 362	REQUIRE(rdata2 != NULL);
 363	REQUIRE(rdata1->length == 0 || rdata1->data != NULL);
 364	REQUIRE(rdata2->length == 0 || rdata2->data != NULL);
 365	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1));
 366	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2));
 367
 368	if (rdata1->rdclass != rdata2->rdclass)
 369		return (rdata1->rdclass < rdata2->rdclass ? -1 : 1);
 370
 371	if (rdata1->type != rdata2->type)
 372		return (rdata1->type < rdata2->type ? -1 : 1);
 373
 374	CASECOMPARESWITCH
 375
 376	if (use_default) {
 377		isc_region_t r1;
 378		isc_region_t r2;
 379
 380		dns_rdata_toregion(rdata1, &r1);
 381		dns_rdata_toregion(rdata2, &r2);
 382		result = isc_region_compare(&r1, &r2);
 383	}
 384	return (result);
 385}
 386
 387/***
 388 *** Conversions
 389 ***/
 390
 391void
 392dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
 393		     dns_rdatatype_t type, isc_region_t *r)
 394{
 395
 396	REQUIRE(rdata != NULL);
 397	REQUIRE(DNS_RDATA_INITIALIZED(rdata));
 398	REQUIRE(r != NULL);
 399
 400	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
 401
 402	rdata->data = r->base;
 403	rdata->length = r->length;
 404	rdata->rdclass = rdclass;
 405	rdata->type = type;
 406	rdata->flags = 0;
 407}
 408
 409void
 410dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r) {
 411
 412	REQUIRE(rdata != NULL);
 413	REQUIRE(r != NULL);
 414	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
 415
 416	r->base = rdata->data;
 417	r->length = rdata->length;
 418}
 419
 420isc_result_t
 421dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
 422		   dns_rdatatype_t type, isc_buffer_t *source,
 423		   dns_decompress_t *dctx, unsigned int options,
 424		   isc_buffer_t *target)
 425{
 426	isc_result_t result = ISC_R_NOTIMPLEMENTED;
 427	isc_region_t region;
 428	isc_buffer_t ss;
 429	isc_buffer_t st;
 430	isc_boolean_t use_default = ISC_FALSE;
 431	isc_uint32_t activelength;
 432	size_t length;
 433
 434	REQUIRE(dctx != NULL);
 435	if (rdata != NULL) {
 436		REQUIRE(DNS_RDATA_INITIALIZED(rdata));
 437		REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
 438	}
 439
 440	if (type == 0)
 441		return (DNS_R_FORMERR);
 442
 443	ss = *source;
 444	st = *target;
 445
 446	activelength = isc_buffer_activelength(source);
 447	INSIST(activelength < 65536);
 448
 449	FROMWIRESWITCH
 450
 451	if (use_default) {
 452		if (activelength > isc_buffer_availablelength(target))
 453			result = ISC_R_NOSPACE;
 454		else {
 455			isc_buffer_putmem(target, isc_buffer_current(source),
 456					  activelength);
 457			isc_buffer_forward(source, activelength);
 458			result = ISC_R_SUCCESS;
 459		}
 460	}
 461
 462	/*
 463	 * Reject any rdata that expands out to more than DNS_RDATA_MAXLENGTH
 464	 * as we cannot transmit it.
 465	 */
 466	length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st);
 467	if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH)
 468		result = DNS_R_FORMERR;
 469
 470	/*
 471	 * We should have consumed all of our buffer.
 472	 */
 473	if (result == ISC_R_SUCCESS && !buffer_empty(source))
 474		result = DNS_R_EXTRADATA;
 475
 476	if (rdata != NULL && result == ISC_R_SUCCESS) {
 477		region.base = isc_buffer_used(&st);
 478		region.length = length;
 479		dns_rdata_fromregion(rdata, rdclass, type, &region);
 480	}
 481
 482	if (result != ISC_R_SUCCESS) {
 483		*source = ss;
 484		*target = st;
 485	}
 486	return (result);
 487}
 488
 489isc_result_t
 490dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
 491		 isc_buffer_t *target)
 492{
 493	isc_result_t result = ISC_R_NOTIMPLEMENTED;
 494	isc_boolean_t use_default = ISC_FALSE;
 495	isc_region_t tr;
 496	isc_buffer_t st;
 497
 498	REQUIRE(rdata != NULL);
 499	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
 500
 501	/*
 502	 * Some DynDNS meta-RRs have empty rdata.
 503	 */
 504	if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
 505		INSIST(rdata->length == 0);
 506		return (ISC_R_SUCCESS);
 507	}
 508
 509	st = *target;
 510
 511	TOWIRESWITCH
 512
 513	if (use_default) {
 514		isc_buffer_availableregion(target, &tr);
 515		if (tr.length < rdata->length)
 516			return (ISC_R_NOSPACE);
 517		memcpy(tr.base, rdata->data, rdata->length);
 518		isc_buffer_add(target, rdata->length);
 519		return (ISC_R_SUCCESS);
 520	}
 521	if (result != ISC_R_SUCCESS) {
 522		*target = st;
 523		INSIST(target->used < 65536);
 524		dns_compress_rollback(cctx, (isc_uint16_t)target->used);
 525	}
 526	return (result);
 527}
 528
 529/*
 530 * If the binary data in 'src' is valid uncompressed wire format
 531 * rdata of class 'rdclass' and type 'type', return ISC_R_SUCCESS
 532 * and copy the validated rdata to 'dest'.  Otherwise return an error.
 533 */
 534static isc_result_t
 535rdata_validate(isc_buffer_t *src, isc_buffer_t *dest, dns_rdataclass_t rdclass,
 536	    dns_rdatatype_t type)
 537{
 538	dns_decompress_t dctx;
 539	dns_rdata_t rdata = DNS_RDATA_INIT;
 540	isc_result_t result;
 541
 542	dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
 543	isc_buffer_setactive(src, isc_buffer_usedlength(src));
 544	result = dns_rdata_fromwire(&rdata, rdclass, type, src,
 545				    &dctx, 0, dest);
 546	dns_decompress_invalidate(&dctx);
 547
 548	return (result);
 549}
 550
 551static isc_result_t
 552unknown_fromtext(dns_rdataclass_t rdclass, dns_rdatatype_t type,
 553		 isc_lex_t *lexer, isc_mem_t *mctx, isc_buffer_t *target)
 554{
 555	isc_result_t result;
 556	isc_buffer_t *buf = NULL;
 557	isc_token_t token;
 558
 559	if (type == 0 || dns_rdatatype_ismeta(type))
 560		return (DNS_R_METATYPE);
 561
 562	result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
 563					ISC_FALSE);
 564	if (result == ISC_R_SUCCESS && token.value.as_ulong > 65535U)
 565		return (ISC_R_RANGE);
 566	result = isc_buffer_allocate(mctx, &buf, token.value.as_ulong);
 567	if (result != ISC_R_SUCCESS)
 568		return (result);
 569
 570	result = isc_hex_tobuffer(lexer, buf,
 571				  (unsigned int)token.value.as_ulong);
 572	if (result != ISC_R_SUCCESS)
 573	       goto failure;
 574	if (isc_buffer_usedlength(buf) != token.value.as_ulong) {
 575		result = ISC_R_UNEXPECTEDEND;
 576		goto failure;
 577	}
 578
 579	if (dns_rdatatype_isknown(type)) {
 580		result = rdata_validate(buf, target, rdclass, type);
 581	} else {
 582		isc_region_t r;
 583		isc_buffer_usedregion(buf, &r);
 584		result = isc_buffer_copyregion(target, &r);
 585	}
 586	if (result != ISC_R_SUCCESS)
 587		goto failure;
 588
 589	isc_buffer_free(&buf);
 590	return (ISC_R_SUCCESS);
 591
 592 failure:
 593	isc_buffer_free(&buf);
 594	return (result);
 595}
 596
 597isc_result_t
 598dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
 599		   dns_rdatatype_t type, isc_lex_t *lexer,
 600		   dns_name_t *origin, unsigned int options, isc_mem_t *mctx,
 601		   isc_buffer_t *target, dns_rdatacallbacks_t *callbacks)
 602{
 603	isc_result_t result = ISC_R_NOTIMPLEMENTED;
 604	isc_region_t region;
 605	isc_buffer_t st;
 606	isc_token_t token;
 607	unsigned int lexoptions = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
 608				  ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE;
 609	char *name;
 610	unsigned long line;
 611	void (*callback)(dns_rdatacallbacks_t *, const char *, ...);
 612	isc_result_t tresult;
 613	size_t length;
 614
 615	REQUIRE(origin == NULL || dns_name_isabsolute(origin) == ISC_TRUE);
 616	if (rdata != NULL) {
 617		REQUIRE(DNS_RDATA_INITIALIZED(rdata));
 618		REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
 619	}
 620	if (callbacks != NULL) {
 621		REQUIRE(callbacks->warn != NULL);
 622		REQUIRE(callbacks->error != NULL);
 623	}
 624
 625	st = *target;
 626
 627	if (callbacks != NULL)
 628		callback = callbacks->error;
 629	else
 630		callback = default_fromtext_callback;
 631
 632	result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
 633					ISC_FALSE);
 634	if (result != ISC_R_SUCCESS) {
 635		name = isc_lex_getsourcename(lexer);
 636		line = isc_lex_getsourceline(lexer);
 637		fromtext_error(callback, callbacks, name, line, NULL, result);
 638		return (result);
 639	}
 640
 641	if (strcmp(DNS_AS_STR(token), "\\#") == 0)
 642		result = unknown_fromtext(rdclass, type, lexer, mctx, target);
 643	else {
 644		isc_lex_ungettoken(lexer, &token);
 645
 646		FROMTEXTSWITCH
 647	}
 648
 649	/*
 650	 * Consume to end of line / file.
 651	 * If not at end of line initially set error code.
 652	 * Call callback via fromtext_error once if there was an error.
 653	 */
 654	do {
 655		name = isc_lex_getsourcename(lexer);
 656		line = isc_lex_getsourceline(lexer);
 657		tresult = isc_lex_gettoken(lexer, lexoptions, &token);
 658		if (tresult != ISC_R_SUCCESS) {
 659			if (result == ISC_R_SUCCESS)
 660				result = tresult;
 661			if (callback != NULL)
 662				fromtext_error(callback, callbacks, name,
 663					       line, NULL, result);
 664			break;
 665		} else if (token.type != isc_tokentype_eol &&
 666			   token.type != isc_tokentype_eof) {
 667			if (result == ISC_R_SUCCESS)
 668				result = DNS_R_EXTRATOKEN;
 669			if (callback != NULL) {
 670				fromtext_error(callback, callbacks, name,
 671					       line, &token, result);
 672				callback = NULL;
 673			}
 674		} else if (result != ISC_R_SUCCESS && callback != NULL) {
 675			fromtext_error(callback, callbacks, name, line,
 676				       &token, result);
 677			break;
 678		} else {
 679			if (token.type == isc_tokentype_eof)
 680				fromtext_warneof(lexer, callbacks);
 681			break;
 682		}
 683	} while (1);
 684
 685	length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st);
 686	if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH)
 687		result = ISC_R_NOSPACE;
 688
 689	if (rdata != NULL && result == ISC_R_SUCCESS) {
 690		region.base = isc_buffer_used(&st);
 691		region.length = length;
 692		dns_rdata_fromregion(rdata, rdclass, type, &region);
 693	}
 694	if (result != ISC_R_SUCCESS) {
 695		*target = st;
 696	}
 697	return (result);
 698}
 699
 700static isc_result_t
 701unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
 702	       isc_buffer_t *target)
 703{
 704	isc_result_t result;
 705	char buf[sizeof("65535")];
 706	isc_region_t sr;
 707
 708	strlcpy(buf, "\\# ", sizeof(buf));
 709	result = str_totext(buf, target);
 710	if (result != ISC_R_SUCCESS)
 711		return (result);
 712
 713	dns_rdata_toregion(rdata, &sr);
 714	INSIST(sr.length < 65536);
 715	snprintf(buf, sizeof(buf), "%u", sr.length);
 716	result = str_totext(buf, target);
 717	if (result != ISC_R_SUCCESS)
 718		return (result);
 719
 720	if (sr.length != 0U) {
 721		if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
 722			result = str_totext(" ( ", target);
 723		else
 724			result = str_totext(" ", target);
 725
 726		if (result != ISC_R_SUCCESS)
 727			return (result);
 728
 729		if (tctx->width == 0) /* No splitting */
 730			result = isc_hex_totext(&sr, 0, "", target);
 731		else
 732			result = isc_hex_totext(&sr, tctx->width - 2,
 733						tctx->linebreak,
 734						target);
 735		if (result == ISC_R_SUCCESS &&
 736		    (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
 737			result = str_totext(" )", target);
 738	}
 739	return (result);
 740}
 741
 742static isc_result_t
 743rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
 744	     isc_buffer_t *target)
 745{
 746	isc_result_t result = ISC_R_NOTIMPLEMENTED;
 747	isc_boolean_t use_default = ISC_FALSE;
 748
 749	REQUIRE(rdata != NULL);
 750	REQUIRE(tctx->origin == NULL ||
 751		dns_name_isabsolute(tctx->origin) == ISC_TRUE);
 752
 753	/*
 754	 * Some DynDNS meta-RRs have empty rdata.
 755	 */
 756	if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
 757		INSIST(rdata->length == 0);
 758		return (ISC_R_SUCCESS);
 759	}
 760
 761	TOTEXTSWITCH
 762
 763	if (use_default)
 764		result = unknown_totext(rdata, tctx, target);
 765
 766	return (result);
 767}
 768
 769isc_result_t
 770dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target)
 771{
 772	dns_rdata_textctx_t tctx;
 773
 774	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
 775
 776	/*
 777	 * Set up formatting options for single-line output.
 778	 */
 779	tctx.origin = origin;
 780	tctx.flags = 0;
 781	tctx.width = 60;
 782	tctx.linebreak = " ";
 783	return (rdata_totext(rdata, &tctx, target));
 784}
 785
 786isc_result_t
 787dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin,
 788		    unsigned int flags, unsigned int width,
 789		    const char *linebreak, isc_buffer_t *target)
 790{
 791	dns_rdata_textctx_t tctx;
 792
 793	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
 794
 795	/*
 796	 * Set up formatting options for formatted output.
 797	 */
 798	tctx.origin = origin;
 799	tctx.flags = flags;
 800	if ((flags & DNS_STYLEFLAG_MULTILINE) != 0) {
 801		tctx.width = width;
 802		tctx.linebreak = linebreak;
 803	} else {
 804		tctx.width = 60; /* Used for hex word length only. */
 805		tctx.linebreak = " ";
 806	}
 807	return (rdata_totext(rdata, &tctx, target));
 808}
 809
 810isc_result_t
 811dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
 812		     dns_rdatatype_t type, void *source,
 813		     isc_buffer_t *target)
 814{
 815	isc_result_t result = ISC_R_NOTIMPLEMENTED;
 816	isc_buffer_t st;
 817	isc_region_t region;
 818	isc_boolean_t use_default = ISC_FALSE;
 819	size_t length;
 820
 821	REQUIRE(source != NULL);
 822	if (rdata != NULL) {
 823		REQUIRE(DNS_RDATA_INITIALIZED(rdata));
 824		REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
 825	}
 826
 827	st = *target;
 828
 829	FROMSTRUCTSWITCH
 830
 831	if (use_default)
 832		(void)NULL;
 833
 834	length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st);
 835	if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH)
 836		result = ISC_R_NOSPACE;
 837
 838	if (rdata != NULL && result == ISC_R_SUCCESS) {
 839		region.base = isc_buffer_used(&st);
 840		region.length = length;
 841		dns_rdata_fromregion(rdata, rdclass, type, &region);
 842	}
 843	if (result != ISC_R_SUCCESS)
 844		*target = st;
 845	return (result);
 846}
 847
 848isc_result_t
 849dns_rdata_tostruct(dns_rdata_t *rdata, void *target, isc_mem_t *mctx) {
 850	isc_result_t result = ISC_R_NOTIMPLEMENTED;
 851	isc_boolean_t use_default = ISC_FALSE;
 852
 853	REQUIRE(rdata != NULL);
 854	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
 855
 856	TOSTRUCTSWITCH
 857
 858	if (use_default)
 859		(void)NULL;
 860
 861	return (result);
 862}
 863
 864void
 865dns_rdata_freestruct(void *source) {
 866	dns_rdatacommon_t *common = source;
 867	REQUIRE(source != NULL);
 868
 869	FREESTRUCTSWITCH
 870}
 871
 872isc_result_t
 873dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add,
 874			 void *arg)
 875{
 876	isc_result_t result = ISC_R_NOTIMPLEMENTED;
 877	isc_boolean_t use_default = ISC_FALSE;
 878
 879	/*
 880	 * Call 'add' for each name and type from 'rdata' which is subject to
 881	 * additional section processing.
 882	 */
 883
 884	REQUIRE(rdata != NULL);
 885	REQUIRE(add != NULL);
 886	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
 887
 888	ADDITIONALDATASWITCH
 889
 890	/* No additional processing for unknown types */
 891	if (use_default)
 892		result = ISC_R_SUCCESS;
 893
 894	return (result);
 895}
 896
 897isc_result_t
 898dns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg) {
 899	isc_result_t result = ISC_R_NOTIMPLEMENTED;
 900	isc_boolean_t use_default = ISC_FALSE;
 901	isc_region_t r;
 902
 903	/*
 904	 * Send 'rdata' in DNSSEC canonical form to 'digest'.
 905	 */
 906
 907	REQUIRE(rdata != NULL);
 908	REQUIRE(digest != NULL);
 909	REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
 910
 911	DIGESTSWITCH
 912
 913	if (use_default) {
 914		dns_rdata_toregion(rdata, &r);
 915		result = (digest)(arg, &r);
 916	}
 917
 918	return (result);
 919}
 920
 921isc_boolean_t
 922dns_rdata_checkowner(dns_name_t *name, dns_rdataclass_t rdclass,
 923		     dns_rdatatype_t type, isc_boolean_t wildcard)
 924{
 925	isc_boolean_t result;
 926
 927	CHECKOWNERSWITCH
 928	return (result);
 929}
 930
 931isc_boolean_t
 932dns_rdata_checknames(dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad)
 933{
 934	isc_boolean_t result;
 935
 936	CHECKNAMESSWITCH
 937	return (result);
 938}
 939
 940unsigned int
 941dns_rdatatype_attributes(dns_rdatatype_t type)
 942{
 943	RDATATYPE_ATTRIBUTE_SW
 944	if (type >= (dns_rdatatype_t)128 && type < (dns_rdatatype_t)255)
 945		return (DNS_RDATATYPEATTR_UNKNOWN | DNS_RDATATYPEATTR_META);
 946	return (DNS_RDATATYPEATTR_UNKNOWN);
 947}
 948
 949isc_result_t
 950dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) {
 951	unsigned int hash;
 952	unsigned int n;
 953	unsigned char a, b;
 954
 955	n = source->length;
 956
 957	if (n == 0)
 958		return (DNS_R_UNKNOWN);
 959
 960	a = tolower((unsigned char)source->base[0]);
 961	b = tolower((unsigned char)source->base[n - 1]);
 962
 963	hash = ((a + n) * b) % 256;
 964
 965	/*
 966	 * This switch block is inlined via \#define, and will use "return"
 967	 * to return a result to the caller if it is a valid (known)
 968	 * rdatatype name.
 969	 */
 970	RDATATYPE_FROMTEXT_SW(hash, source->base, n, typep);
 971
 972	if (source->length > 4 && source->length < (4 + sizeof("65000")) &&
 973	    strncasecmp("type", source->base, 4) == 0) {
 974		char buf[sizeof("65000")];
 975		char *endp;
 976		unsigned int val;
 977
 978		strncpy(buf, source->base + 4, source->length - 4);
 979		buf[source->length - 4] = '\0';
 980		val = strtoul(buf, &endp, 10);
 981		if (*endp == '\0' && val <= 0xffff) {
 982			*typep = (dns_rdatatype_t)val;
 983			return (ISC_R_SUCCESS);
 984		}
 985	}
 986
 987	return (DNS_R_UNKNOWN);
 988}
 989
 990isc_result_t
 991dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) {
 992	char buf[sizeof("TYPE65535")];
 993
 994	RDATATYPE_TOTEXT_SW
 995	snprintf(buf, sizeof(buf), "TYPE%u", type);
 996	return (str_totext(buf, target));
 997}
 998
 999void
1000dns_rdatatype_format(dns_rdatatype_t rdtype,
1001		     char *array, unsigned int size)
1002{
1003	isc_result_t result;
1004	isc_buffer_t buf;
1005
1006	if (size == 0U)
1007		return;
1008
1009	isc_buffer_init(&buf, array, size);
1010	result = dns_rdatatype_totext(rdtype, &buf);
1011	/*
1012	 * Null terminate.
1013	 */
1014	if (result == ISC_R_SUCCESS) {
1015		if (isc_buffer_availablelength(&buf) >= 1)
1016			isc_buffer_putuint8(&buf, 0);
1017		else
1018			result = ISC_R_NOSPACE;
1019	}
1020	if (result != ISC_R_SUCCESS)
1021		strlcpy(array, "<unknown>", size);
1022}
1023
1024/*
1025 * Private function.
1026 */
1027
1028static unsigned int
1029name_length(dns_name_t *name) {
1030	return (name->length);
1031}
1032
1033static isc_result_t
1034txt_totext(isc_region_t *source, isc_buffer_t *target) {
1035	unsigned int tl;
1036	unsigned int n;
1037	unsigned char *sp;
1038	char *tp;
1039	isc_region_t region;
1040
1041	isc_buffer_availableregion(target, &region);
1042	sp = source->base;
1043	tp = (char *)region.base;
1044	tl = region.length;
1045
1046	n = *sp++;
1047
1048	REQUIRE(n + 1 <= source->length);
1049
1050	if (tl < 1)
1051		return (ISC_R_NOSPACE);
1052	*tp++ = '"';
1053	tl--;
1054	while (n--) {
1055		if (*sp < 0x20 || *sp >= 0x7f) {
1056			if (tl < 4)
1057				return (ISC_R_NOSPACE);
1058			*tp++ = 0x5c;
1059			*tp++ = 0x30 + ((*sp / 100) % 10);
1060			*tp++ = 0x30 + ((*sp / 10) % 10);
1061			*tp++ = 0x30 + (*sp % 10);
1062			sp++;
1063			tl -= 4;
1064			continue;
1065		}
1066		/* double quote, semi-colon, backslash */
1067		if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) {
1068			if (tl < 2)
1069				return (ISC_R_NOSPACE);
1070			*tp++ = '\\';
1071			tl--;
1072		}
1073		if (tl < 1)
1074			return (ISC_R_NOSPACE);
1075		*tp++ = *sp++;
1076		tl--;
1077	}
1078	if (tl < 1)
1079		return (ISC_R_NOSPACE);
1080	*tp++ = '"';
1081	tl--;
1082	isc_buffer_add(target, tp - (char *)region.base);
1083	isc_region_consume(source, *source->base + 1);
1084	return (ISC_R_SUCCESS);
1085}
1086
1087static isc_result_t
1088txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
1089	isc_region_t tregion;
1090	isc_boolean_t escape;
1091	unsigned int n, nrem;
1092	char *s;
1093	unsigned char *t;
1094	int d;
1095	int c;
1096
1097	isc_buffer_availableregion(target, &tregion);
1098	s = source->base;
1099	n = source->length;
1100	t = tregion.base;
1101	nrem = tregion.length;
1102	escape = ISC_FALSE;
1103	if (nrem < 1)
1104		return (ISC_R_NOSPACE);
1105	/*
1106	 * Length byte.
1107	 */
1108	nrem--;
1109	t++;
1110	/*
1111	 * Maximum text string length.
1112	 */
1113	if (nrem > 255)
1114		nrem = 255;
1115	while (n-- != 0) {
1116		c = (*s++) & 0xff;
1117		if (escape && (d = decvalue((char)c)) != -1) {
1118			c = d;
1119			if (n == 0)
1120				return (DNS_R_SYNTAX);
1121			n--;
1122			if ((d = decvalue(*s++)) != -1)
1123				c = c * 10 + d;
1124			else
1125				return (DNS_R_SYNTAX);
1126			if (n == 0)
1127				return (DNS_R_SYNTAX);
1128			n--;
1129			if ((d = decvalue(*s++)) != -1)
1130				c = c * 10 + d;
1131			else
1132				return (DNS_R_SYNTAX);
1133			if (c > 255)
1134				return (DNS_R_SYNTAX);
1135		} else if (!escape && c == '\\') {
1136			escape = ISC_TRUE;
1137			continue;
1138		}
1139		escape = ISC_FALSE;
1140		if (nrem == 0)
1141			return ((tregion.length <= 256U) ?
1142				ISC_R_NOSPACE : DNS_R_SYNTAX);
1143		*t++ = c;
1144		nrem--;
1145	}
1146	if (escape)
1147		return (DNS_R_SYNTAX);
1148	*tregion.base = t - tregion.base - 1;
1149	isc_buffer_add(target, *tregion.base + 1);
1150	return (ISC_R_SUCCESS);
1151}
1152
1153static isc_result_t
1154txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
1155	unsigned int n;
1156	isc_region_t sregion;
1157	isc_region_t tregion;
1158
1159	isc_buffer_activeregion(source, &sregion);
1160	if (sregion.length == 0)
1161		return(ISC_R_UNEXPECTEDEND);
1162	n = *sregion.base + 1;
1163	if (n > sregion.length)
1164		return (ISC_R_UNEXPECTEDEND);
1165
1166	isc_buffer_availableregion(target, &tregion);
1167	if (n > tregion.length)
1168		return (ISC_R_NOSPACE);
1169
1170	memcpy(tregion.base, sregion.base, n);
1171	isc_buffer_forward(source, n);
1172	isc_buffer_add(target, n);
1173	return (ISC_R_SUCCESS);
1174}
1175
1176static isc_boolean_t
1177name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) {
1178	int l1, l2;
1179
1180	if (origin == NULL)
1181		goto return_false;
1182
1183	if (dns_name_compare(origin, dns_rootname) == 0)
1184		goto return_false;
1185
1186	if (!dns_name_issubdomain(name, origin))
1187		goto return_false;
1188
1189	l1 = dns_name_countlabels(name);
1190	l2 = dns_name_countlabels(origin);
1191
1192	if (l1 == l2)
1193		goto return_false;
1194
1195	/* Master files should be case preserving. */
1196	dns_name_getlabelsequence(name, l1 - l2, l2, target);
1197	if (!dns_name_caseequal(origin, target))
1198		goto return_false;
1199
1200	dns_name_getlabelsequence(name, 0, l1 - l2, target);
1201	return (ISC_TRUE);
1202
1203return_false:
1204	*target = *name;
1205	return (ISC_FALSE);
1206}
1207
1208static isc_result_t
1209str_totext(const char *source, isc_buffer_t *target) {
1210	unsigned int l;
1211	isc_region_t region;
1212
1213	isc_buffer_availableregion(target, &region);
1214	l = strlen(source);
1215
1216	if (l > region.length)
1217		return (ISC_R_NOSPACE);
1218
1219	memcpy(region.base, source, l);
1220	isc_buffer_add(target, l);
1221	return (ISC_R_SUCCESS);
1222}
1223
1224static isc_result_t
1225inet_totext(int af, isc_region_t *src, isc_buffer_t *target) {
1226	char tmpbuf[64];
1227
1228	/* Note - inet_ntop doesn't do size checking on its input. */
1229	if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL)
1230		return (ISC_R_NOSPACE);
1231	if (strlen(tmpbuf) > isc_buffer_availablelength(target))
1232		return (ISC_R_NOSPACE);
1233	isc_buffer_putstr(target, tmpbuf);
1234	return (ISC_R_SUCCESS);
1235}
1236
1237static isc_boolean_t
1238buffer_empty(isc_buffer_t *source) {
1239	return((source->current == source->active) ? ISC_TRUE : ISC_FALSE);
1240}
1241
1242static void
1243buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region) {
1244	isc_buffer_init(buffer, region->base, region->length);
1245	isc_buffer_add(buffer, region->length);
1246	isc_buffer_setactive(buffer, region->length);
1247}
1248
1249static isc_result_t
1250uint32_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
1251	isc_region_t region;
1252
1253	isc_buffer_availableregion(target, &region);
1254	if (region.length < 4)
1255		return (ISC_R_NOSPACE);
1256	isc_buffer_putuint32(target, value);
1257	return (ISC_R_SUCCESS);
1258}
1259
1260static isc_result_t
1261uint16_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
1262	isc_region_t region;
1263
1264	if (value > 0xffff)
1265		return (ISC_R_RANGE);
1266	isc_buffer_availableregion(target, &region);
1267	if (region.length < 2)
1268		return (ISC_R_NOSPACE);
1269	isc_buffer_putuint16(target, (isc_uint16_t)value);
1270	return (ISC_R_SUCCESS);
1271}
1272
1273static isc_result_t
1274uint8_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
1275	isc_region_t region;
1276
1277	if (value > 0xff)
1278		return (ISC_R_RANGE);
1279	isc_buffer_availableregion(target, &region);
1280	if (region.length < 1)
1281		return (ISC_R_NOSPACE);
1282	isc_buffer_putuint8(target, (isc_uint8_t)value);
1283	return (ISC_R_SUCCESS);
1284}
1285
1286static isc_result_t
1287name_tobuffer(dns_name_t *name, isc_buffer_t *target) {
1288	isc_region_t r;
1289	dns_name_toregion(name, &r);
1290	return (isc_buffer_copyregion(target, &r));
1291}
1292
1293static isc_uint32_t
1294uint32_fromregion(isc_region_t *region) {
1295	isc_uint32_t value;
1296
1297	REQUIRE(region->length >= 4);
1298	value = region->base[0] << 24;
1299	value |= region->base[1] << 16;
1300	value |= region->base[2] << 8;
1301	value |= region->base[3];
1302	return(value);
1303}
1304
1305static isc_uint16_t
1306uint16_consume_fromregion(isc_region_t *region) {
1307	isc_uint16_t r = uint16_fromregion(region);
1308
1309	isc_region_consume(region, 2);
1310	return r;
1311}
1312
1313static isc_uint16_t
1314uint16_fromregion(isc_region_t *region) {
1315
1316	REQUIRE(region->length >= 2);
1317
1318	return ((region->base[0] << 8) | region->base[1]);
1319}
1320
1321static isc_uint8_t
1322uint8_fromregion(isc_region_t *region) {
1323
1324	REQUIRE(region->length >= 1);
1325
1326	return (region->base[0]);
1327}
1328
1329static isc_uint8_t
1330uint8_consume_fromregion(isc_region_t *region) {
1331	isc_uint8_t r = uint8_fromregion(region);
1332
1333	isc_region_consume(region, 1);
1334	return r;
1335}
1336
1337static isc_result_t
1338mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
1339	isc_region_t tr;
1340
1341	isc_buffer_availableregion(target, &tr);
1342	if (length > tr.length)
1343		return (ISC_R_NOSPACE);
1344	memcpy(tr.base, base, length);
1345	isc_buffer_add(target, length);
1346	return (ISC_R_SUCCESS);
1347}
1348
1349static int
1350hexvalue(char value) {
1351	char *s;
1352	unsigned char c;
1353
1354	c = (unsigned char)value;
1355
1356	if (!isascii(c))
1357		return (-1);
1358	if (isupper(c))
1359		c = tolower(c);
1360	if ((s = strchr(hexdigits, c)) == NULL)
1361		return (-1);
1362	return (s - hexdigits);
1363}
1364
1365static int
1366decvalue(char value) {
1367	char *s;
1368
1369	/*
1370	 * isascii() is valid for full range of int values, no need to
1371	 * mask or cast.
1372	 */
1373	if (!isascii(value))
1374		return (-1);
1375	if ((s = strchr(decdigits, value)) == NULL)
1376		return (-1);
1377	return (s - decdigits);
1378}
1379
1380static const char atob_digits[86] =
1381	"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \
1382	"abcdefghijklmnopqrstu";
1383/*
1384 * Subroutines to convert between 8 bit binary bytes and printable ASCII.
1385 * Computes the number of bytes, and three kinds of simple checksums.
1386 * Incoming bytes are collected into 32-bit words, then printed in base 85:
1387 *	exp(85,5) > exp(2,32)
1388 * The ASCII characters used are between '!' and 'u';
1389 * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data.
1390 *
1391 * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for
1392 * the atob/btoa programs, released with the compress program, in mod.sources.
1393 * Modified by Mike Schwartz 8/19/86 for use in BIND.
1394 * Modified to be re-entrant 3/2/99.
1395 */
1396
1397
1398struct state {
1399	isc_int32_t Ceor;
1400	isc_int32_t Csum;
1401	isc_int32_t Crot;
1402	isc_int32_t word;
1403	isc_int32_t bcount;
1404};
1405
1406#define Ceor state->Ceor
1407#define Csum state->Csum
1408#define Crot state->Crot
1409#define word state->word
1410#define bcount state->bcount
1411
1412#define times85(x)	((((((x<<2)+x)<<2)+x)<<2)+x)
1413
1414static isc_result_t	byte_atob(int c, isc_buffer_t *target,
1415				  struct state *state);
1416static isc_result_t	putbyte(int c, isc_buffer_t *, struct state *state);
1417static isc_result_t	byte_btoa(int c, isc_buffer_t *, struct state *state);
1418
1419/*
1420 * Decode ASCII-encoded byte c into binary representation and
1421 * place into *bufp, advancing bufp.
1422 */
1423static isc_result_t
1424byte_atob(int c, isc_buffer_t *target, struct state *state) {
1425	char *s;
1426	if (c == 'z') {
1427		if (bcount != 0)
1428			return(DNS_R_SYNTAX);
1429		else {
1430			RETERR(putbyte(0, target, state));
1431			RETERR(putbyte(0, target, state));
1432			RETERR(putbyte(0, target, state));
1433			RETERR(putbyte(0, target, state));
1434		}
1435	} else if ((s = strchr(atob_digits, c)) != NULL) {
1436		if (bcount == 0) {
1437			word = s - atob_digits;
1438			++bcount;
1439		} else if (bcount < 4) {
1440			word = times85(word);
1441			word += s - atob_digits;
1442			++bcount;
1443		} else {
1444			word = times85(word);
1445			word += s - atob_digits;
1446			RETERR(putbyte((word >> 24) & 0xff, target, state));
1447			RETERR(putbyte((word >> 16) & 0xff, target, state));
1448			RETERR(putbyte((word >> 8) & 0xff, target, state));
1449			RETERR(putbyte(word & 0xff, target, state));
1450			word = 0;
1451			bcount = 0;
1452		}
1453	} else
1454		return(DNS_R_SYNTAX);
1455	return(ISC_R_SUCCESS);
1456}
1457
1458/*
1459 * Compute checksum info and place c into target.
1460 */
1461static isc_result_t
1462putbyte(int c, isc_buffer_t *target, struct state *state) {
1463	isc_region_t tr;
1464
1465	Ceor ^= c;
1466	Csum += c;
1467	Csum += 1;
1468	if ((Crot & 0x80000000)) {
1469		Crot <<= 1;
1470		Crot += 1;
1471	} else {
1472		Crot <<= 1;
1473	}
1474	Crot += c;
1475	isc_buffer_availableregion(target, &tr);
1476	if (tr.length < 1)
1477		return (ISC_R_NOSPACE);
1478	tr.base[0] = c;
1479	isc_buffer_add(target, 1);
1480	return (ISC_R_SUCCESS);
1481}
1482
1483/*
1484 * Read the ASCII-encoded data from inbuf, of length inbuflen, and convert
1485 * it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes;
1486 * outbuflen must be divisible by 4.  (Note: this is because outbuf is filled
1487 * in 4 bytes at a time.  If the actual data doesn't end on an even 4-byte
1488 * boundary, there will be no problem...it will be padded with 0 bytes, and
1489 * numbytes will indicate the correct number of bytes.  The main point is
1490 * that since the buffer is filled in 4 bytes at a time, even if there is
1491 * not a full 4 bytes of data at the end, there has to be room to 0-pad the
1492 * data, so the buffer must be of size divisible by 4).  Place the number of
1493 * output bytes in numbytes, and return a failure/success status.
1494 */
1495
1496static isc_result_t
1497atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target) {
1498	long oeor, osum, orot;
1499	struct state statebuf, *state= &statebuf;
1500	isc_token_t token;
1501	char c;
1502	char *e;
1503
1504	Ceor = Csum = Crot = word = bcount = 0;
1505
1506	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
1507				      ISC_FALSE));
1508	while (token.value.as_textregion.length != 0) {
1509		if ((c = token.value.as_textregion.base[0]) == 'x') {
1510			break;
1511		} else
1512			RETERR(byte_atob(c, target, state));
1513		isc_textregion_consume(&token.value.as_textregion, 1);
1514	}
1515
1516	/*
1517	 * Number of bytes.
1518	 */
1519	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
1520				      ISC_FALSE));
1521	if ((token.value.as_ulong % 4) != 0U)
1522		isc_buffer_subtract(target,  4 - (token.value.as_ulong % 4));
1523
1524	/*
1525	 * Checksum.
1526	 */
1527	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
1528				      ISC_FALSE));
1529	oeor = strtol(DNS_AS_STR(token), &e, 16);
1530	if (*e != 0)
1531		return (DNS_R_SYNTAX);
1532
1533	/*
1534	 * Checksum.
1535	 */
1536	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
1537				      ISC_FALSE));
1538	osum = strtol(DNS_AS_STR(token), &e, 16);
1539	if (*e != 0)
1540		return (DNS_R_SYNTAX);
1541
1542	/*
1543	 * Checksum.
1544	 */
1545	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
1546				      ISC_FALSE));
1547	orot = strtol(DNS_AS_STR(token), &e, 16);
1548	if (*e != 0)
1549		return (DNS_R_SYNTAX);
1550
1551	if ((oeor != Ceor) || (osum != Csum) || (orot != Crot))
1552		return(DNS_R_BADCKSUM);
1553	return (ISC_R_SUCCESS);
1554}
1555
1556/*
1557 * Encode binary byte c into ASCII representation and place into *bufp,
1558 * advancing bufp.
1559 */
1560static isc_result_t
1561byte_btoa(int c, isc_buffer_t *target, struct state *state) {
1562	isc_region_t tr;
1563
1564	isc_buffer_availableregion(target, &tr);
1565	Ceor ^= c;
1566	Csum += c;
1567	Csum += 1;
1568	if ((Crot & 0x80000000)) {
1569		Crot <<= 1;
1570		Crot += 1;
1571	} else {
1572		Crot <<= 1;
1573	}
1574	Crot += c;
1575
1576	word <<= 8;
1577	word |= c;
1578	if (bcount == 3) {
1579		if (word == 0) {
1580			if (tr.length < 1)
1581				return (ISC_R_NOSPACE);
1582			tr.base[0] = 'z';
1583			isc_buffer_add(target, 1);
1584		} else {
1585		    register int tmp = 0;
1586		    register isc_int32_t tmpword = word;
1587
1588		    if (tmpword < 0) {
1589			   /*
1590			    * Because some don't support u_long.
1591			    */
1592			tmp = 32;
1593			tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32);
1594		    }
1595		    if (tmpword < 0) {
1596			tmp = 64;
1597			tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32);
1598		    }
1599			if (tr.length < 5)
1600				return (ISC_R_NOSPACE);
1601			tr.base[0] = atob_digits[(tmpword /
1602					      (isc_int32_t)(85 * 85 * 85 * 85))
1603						+ tmp];
1604			tmpword %= (isc_int32_t)(85 * 85 * 85 * 85);
1605			tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)];
1606			tmpword %= (85 * 85 * 85);
1607			tr.base[2] = atob_digits[tmpword / (85 * 85)];
1608			tmpword %= (85 * 85);
1609			tr.base[3] = atob_digits[tmpword / 85];
1610			tmpword %= 85;
1611			tr.base[4] = atob_digits[tmpword];
1612			isc_buffer_add(target, 5);
1613		}
1614		bcount = 0;
1615	} else {
1616		bcount += 1;
1617	}
1618	return (ISC_R_SUCCESS);
1619}
1620
1621
1622/*
1623 * Encode the binary data from inbuf, of length inbuflen, into a
1624 * target.  Return success/failure status
1625 */
1626static isc_result_t
1627btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) {
1628	int inc;
1629	struct state statebuf, *state = &statebuf;
1630	char buf[sizeof("x 2000000000 ffffffff ffffffff ffffffff")];
1631
1632	Ceor = Csum = Crot = word = bcount = 0;
1633	for (inc = 0; inc < inbuflen; inbuf++, inc++)
1634		RETERR(byte_btoa(*inbuf, target, state));
1635
1636	while (bcount != 0)
1637		RETERR(byte_btoa(0, target, state));
1638
1639	/*
1640	 * Put byte count and checksum information at end of buffer,
1641	 * delimited by 'x'
1642	 */
1643	snprintf(buf, sizeof(buf), "x %d %x %x %x", inbuflen, Ceor, Csum, Crot);
1644	return (str_totext(buf, target));
1645}
1646
1647
1648static void
1649default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *fmt,
1650			  ...)
1651{
1652	va_list ap;
1653
1654	UNUSED(callbacks);
1655
1656	va_start(ap, fmt);
1657	vfprintf(stderr, fmt, ap);
1658	va_end(ap);
1659	fprintf(stderr, "\n");
1660}
1661
1662static void
1663fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) {
1664	if (isc_lex_isfile(lexer) && callbacks != NULL) {
1665		const char *name = isc_lex_getsourcename(lexer);
1666		if (name == NULL)
1667			name = "UNKNOWN";
1668		(*callbacks->warn)(callbacks,
1669				   "%s:%lu: file does not end with newline",
1670				   name, isc_lex_getsourceline(lexer));
1671	}
1672}
1673
1674static void
1675warn_badmx(isc_token_t *token, isc_lex_t *lexer,
1676	   dns_rdatacallbacks_t *callbacks)
1677{
1678	const char *file;
1679	unsigned long line;
1680
1681	if (lexer != NULL) {
1682		file = isc_lex_getsourcename(lexer);
1683		line = isc_lex_getsourceline(lexer);
1684		(*callbacks->warn)(callbacks, "%s:%u: warning: '%s': %s",
1685				   file, line, DNS_AS_STR(*token),
1686				   dns_result_totext(DNS_R_MXISADDRESS));
1687	}
1688}
1689
1690static void
1691warn_badname(dns_name_t *name, isc_lex_t *lexer,
1692	     dns_rdatacallbacks_t *callbacks)
1693{
1694	const char *file;
1695	unsigned long line;
1696	char namebuf[DNS_NAME_FORMATSIZE];
1697
1698	if (lexer != NULL) {
1699		file = isc_lex_getsourcename(lexer);
1700		line = isc_lex_getsourceline(lexer);
1701		dns_name_format(name, namebuf, sizeof(namebuf));
1702		(*callbacks->warn)(callbacks, "%s:%u: warning: %s: %s",
1703				   file, line, namebuf,
1704				   dns_result_totext(DNS_R_BADNAME));
1705	}
1706}
1707
1708static void
1709fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...),
1710	       dns_rdatacallbacks_t *callbacks, const char *name,
1711	       unsigned long line, isc_token_t *token, isc_result_t result)
1712{
1713	if (name == NULL)
1714		name = "UNKNOWN";
1715
1716	if (token != NULL) {
1717		switch (token->type) {
1718		case isc_tokentype_eol:
1719			(*callback)(callbacks, "%s: %s:%lu: near eol: %s",
1720				    "dns_rdata_fromtext", name, line,
1721				    dns_result_totext(result));
1722			break;
1723		case isc_tokentype_eof:
1724			(*callback)(callbacks, "%s: %s:%lu: near eof: %s",
1725				    "dns_rdata_fromtext", name, line,
1726				    dns_result_totext(result));
1727			break;
1728		case isc_tokentype_number:
1729			(*callback)(callbacks, "%s: %s:%lu: near %lu: %s",
1730				    "dns_rdata_fromtext", name, line,
1731				    token->value.as_ulong,
1732				    dns_result_totext(result));
1733			break;
1734		case isc_tokentype_string:
1735		case isc_tokentype_qstring:
1736			(*callback)(callbacks, "%s: %s:%lu: near '%s': %s",
1737				    "dns_rdata_fromtext", name, line,
1738				    DNS_AS_STR(*token),
1739				    dns_result_totext(result));
1740			break;
1741		default:
1742			(*callback)(callbacks, "%s: %s:%lu: %s",
1743				    "dns_rdata_fromtext", name, line,
1744				    dns_result_totext(result));
1745			break;
1746		}
1747	} else {
1748		(*callback)(callbacks, "dns_rdata_fromtext: %s:%lu: %s",
1749			    name, line, dns_result_totext(result));
1750	}
1751}
1752
1753dns_rdatatype_t
1754dns_rdata_covers(dns_rdata_t *rdata) {
1755	if (rdata->type == 46)
1756		return (covers_rrsig(rdata));
1757	return (covers_sig(rdata));
1758}
1759
1760isc_boolean_t
1761dns_rdatatype_ismeta(dns_rdatatype_t type) {
1762	if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_META) != 0)
1763		return (ISC_TRUE);
1764	return (ISC_FALSE);
1765}
1766
1767isc_boolean_t
1768dns_rdatatype_issingleton(dns_rdatatype_t type) {
1769	if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_SINGLETON)
1770	    != 0)
1771		return (ISC_TRUE);
1772	return (ISC_FALSE);
1773}
1774
1775isc_boolean_t
1776dns_rdatatype_notquestion(dns_rdatatype_t type) {
1777	if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_NOTQUESTION)
1778	    != 0)
1779		return (ISC_TRUE);
1780	return (ISC_FALSE);
1781}
1782
1783isc_boolean_t
1784dns_rdatatype_questiononly(dns_rdatatype_t type) {
1785	if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_QUESTIONONLY)
1786	    != 0)
1787		return (ISC_TRUE);
1788	return (ISC_FALSE);
1789}
1790
1791isc_boolean_t
1792dns_rdatatype_atparent(dns_rdatatype_t type) {
1793	if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_ATPARENT) != 0)
1794		return (ISC_TRUE);
1795	return (ISC_FALSE);
1796}
1797
1798isc_boolean_t
1799dns_rdataclass_ismeta(dns_rdataclass_t rdclass) {
1800
1801	if (rdclass == dns_rdataclass_reserved0
1802	    || rdclass == dns_rdataclass_none
1803	    || rdclass == dns_rdataclass_any)
1804		return (ISC_TRUE);
1805
1806	return (ISC_FALSE);  /* Assume it is not a meta class. */
1807}
1808
1809isc_boolean_t
1810dns_rdatatype_isdnssec(dns_rdatatype_t type) {
1811	if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_DNSSEC) != 0)
1812		return (ISC_TRUE);
1813	return (ISC_FALSE);
1814}
1815
1816isc_boolean_t
1817dns_rdatatype_iszonecutauth(dns_rdatatype_t type) {
1818	if ((dns_rdatatype_attributes(type)
1819	     & (DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH))
1820	    != 0)
1821		return (ISC_TRUE);
1822	return (ISC_FALSE);
1823}
1824
1825isc_boolean_t
1826dns_rdatatype_isknown(dns_rdatatype_t type) {
1827	if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_UNKNOWN)
1828	    == 0)
1829		return (ISC_TRUE);
1830	return (ISC_FALSE);
1831}
1832
1833void
1834dns_rdata_exists(dns_rdata_t *rdata, dns_rdatatype_t type) {
1835
1836	REQUIRE(rdata != NULL);
1837	REQUIRE(DNS_RDATA_INITIALIZED(rdata));
1838
1839	rdata->data = NULL;
1840	rdata->length = 0;
1841	rdata->flags = DNS_RDATA_UPDATE;
1842	rdata->type = type;
1843	rdata->rdclass = dns_rdataclass_any;
1844}
1845
1846void
1847dns_rdata_notexist(dns_rdata_t *rdata, dns_rdatatype_t type) {
1848
1849	REQUIRE(rdata != NULL);
1850	REQUIRE(DNS_RDATA_INITIALIZED(rdata));
1851
1852	rdata->data = NULL;
1853	rdata->length = 0;
1854	rdata->flags = DNS_RDATA_UPDATE;
1855	rdata->type = type;
1856	rdata->rdclass = dns_rdataclass_none;
1857}
1858
1859void
1860dns_rdata_deleterrset(dns_rdata_t *rdata, dns_rdatatype_t type) {
1861
1862	REQUIRE(rdata != NULL);
1863	REQUIRE(DNS_RDATA_INITIALIZED(rdata));
1864
1865	rdata->data = NULL;
1866	rdata->length = 0;
1867	rdata->flags = DNS_RDATA_UPDATE;
1868	rdata->type = type;
1869	rdata->rdclass = dns_rdataclass_any;
1870}
1871
1872void
1873dns_rdata_makedelete(dns_rdata_t *rdata) {
1874	REQUIRE(rdata != NULL);
1875
1876	rdata->rdclass = dns_rdataclass_none;
1877}
1878
1879const char *
1880dns_rdata_updateop(dns_rdata_t *rdata, dns_section_t section) {
1881
1882	REQUIRE(rdata != NULL);
1883	REQUIRE(DNS_RDATA_INITIALIZED(rdata));
1884
1885	switch (section) {
1886	case DNS_SECTION_PREREQUISITE:
1887		switch (rdata->rdclass) {
1888		case dns_rdataclass_none:
1889			switch (rdata->type) {
1890			case dns_rdatatype_any:
1891				return ("domain doesn't exist");
1892			default:
1893				return ("rrset doesn't exist");
1894			}
1895		case dns_rdataclass_any:
1896			switch (rdata->type) {
1897			case dns_rdatatype_any:
1898				return ("domain exists");
1899			default:
1900				return ("rrset exists (value independent)");
1901			}
1902		default:
1903			return ("rrset exists (value dependent)");
1904		}
1905	case DNS_SECTION_UPDATE:
1906		switch (rdata->rdclass) {
1907		case dns_rdataclass_none:
1908			return ("delete");
1909		case dns_rdataclass_any:
1910			switch (rdata->type) {
1911			case dns_rdatatype_any:
1912				return ("delete all rrsets");
1913			default:
1914				return ("delete rrset");
1915			}
1916		default:
1917			return ("add");
1918		}
1919	}
1920	return ("invalid");
1921}