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