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