rdata.c revision 165071
1/* 2 * Copyright (C) 2004-2006 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.22 2006/07/21 02:05:56 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 *tp++ = 0x5c; 990 *tp++ = 0x30 + ((*sp / 100) % 10); 991 *tp++ = 0x30 + ((*sp / 10) % 10); 992 *tp++ = 0x30 + (*sp % 10); 993 sp++; 994 tl -= 4; 995 continue; 996 } 997 /* double quote, semi-colon, backslash */ 998 if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) { 999 if (tl < 2) 1000 return (ISC_R_NOSPACE); 1001 *tp++ = '\\'; 1002 tl--; 1003 } 1004 if (tl < 1) 1005 return (ISC_R_NOSPACE); 1006 *tp++ = *sp++; 1007 tl--; 1008 } 1009 if (tl < 1) 1010 return (ISC_R_NOSPACE); 1011 *tp++ = '"'; 1012 tl--; 1013 isc_buffer_add(target, tp - (char *)region.base); 1014 isc_region_consume(source, *source->base + 1); 1015 return (ISC_R_SUCCESS); 1016} 1017 1018static isc_result_t 1019txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) { 1020 isc_region_t tregion; 1021 isc_boolean_t escape; 1022 unsigned int n, nrem; 1023 char *s; 1024 unsigned char *t; 1025 int d; 1026 int c; 1027 1028 isc_buffer_availableregion(target, &tregion); 1029 s = source->base; 1030 n = source->length; 1031 t = tregion.base; 1032 nrem = tregion.length; 1033 escape = ISC_FALSE; 1034 if (nrem < 1) 1035 return (ISC_R_NOSPACE); 1036 /* 1037 * Length byte. 1038 */ 1039 nrem--; 1040 t++; 1041 /* 1042 * Maximum text string length. 1043 */ 1044 if (nrem > 255) 1045 nrem = 255; 1046 while (n-- != 0) { 1047 c = (*s++) & 0xff; 1048 if (escape && (d = decvalue((char)c)) != -1) { 1049 c = d; 1050 if (n == 0) 1051 return (DNS_R_SYNTAX); 1052 n--; 1053 if ((d = decvalue(*s++)) != -1) 1054 c = c * 10 + d; 1055 else 1056 return (DNS_R_SYNTAX); 1057 if (n == 0) 1058 return (DNS_R_SYNTAX); 1059 n--; 1060 if ((d = decvalue(*s++)) != -1) 1061 c = c * 10 + d; 1062 else 1063 return (DNS_R_SYNTAX); 1064 if (c > 255) 1065 return (DNS_R_SYNTAX); 1066 } else if (!escape && c == '\\') { 1067 escape = ISC_TRUE; 1068 continue; 1069 } 1070 escape = ISC_FALSE; 1071 if (nrem == 0) 1072 return (ISC_R_NOSPACE); 1073 *t++ = c; 1074 nrem--; 1075 } 1076 if (escape) 1077 return (DNS_R_SYNTAX); 1078 *tregion.base = t - tregion.base - 1; 1079 isc_buffer_add(target, *tregion.base + 1); 1080 return (ISC_R_SUCCESS); 1081} 1082 1083static isc_result_t 1084txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { 1085 unsigned int n; 1086 isc_region_t sregion; 1087 isc_region_t tregion; 1088 1089 isc_buffer_activeregion(source, &sregion); 1090 if (sregion.length == 0) 1091 return(ISC_R_UNEXPECTEDEND); 1092 n = *sregion.base + 1; 1093 if (n > sregion.length) 1094 return (ISC_R_UNEXPECTEDEND); 1095 1096 isc_buffer_availableregion(target, &tregion); 1097 if (n > tregion.length) 1098 return (ISC_R_NOSPACE); 1099 1100 memcpy(tregion.base, sregion.base, n); 1101 isc_buffer_forward(source, n); 1102 isc_buffer_add(target, n); 1103 return (ISC_R_SUCCESS); 1104} 1105 1106static isc_boolean_t 1107name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) { 1108 int l1, l2; 1109 1110 if (origin == NULL) 1111 goto return_false; 1112 1113 if (dns_name_compare(origin, dns_rootname) == 0) 1114 goto return_false; 1115 1116 if (!dns_name_issubdomain(name, origin)) 1117 goto return_false; 1118 1119 l1 = dns_name_countlabels(name); 1120 l2 = dns_name_countlabels(origin); 1121 1122 if (l1 == l2) 1123 goto return_false; 1124 1125 dns_name_getlabelsequence(name, 0, l1 - l2, target); 1126 return (ISC_TRUE); 1127 1128return_false: 1129 *target = *name; 1130 return (ISC_FALSE); 1131} 1132 1133static isc_result_t 1134str_totext(const char *source, isc_buffer_t *target) { 1135 unsigned int l; 1136 isc_region_t region; 1137 1138 isc_buffer_availableregion(target, ®ion); 1139 l = strlen(source); 1140 1141 if (l > region.length) 1142 return (ISC_R_NOSPACE); 1143 1144 memcpy(region.base, source, l); 1145 isc_buffer_add(target, l); 1146 return (ISC_R_SUCCESS); 1147} 1148 1149static isc_result_t 1150inet_totext(int af, isc_region_t *src, isc_buffer_t *target) { 1151 char tmpbuf[64]; 1152 1153 /* Note - inet_ntop doesn't do size checking on its input. */ 1154 if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL) 1155 return (ISC_R_NOSPACE); 1156 if (strlen(tmpbuf) > isc_buffer_availablelength(target)) 1157 return (ISC_R_NOSPACE); 1158 isc_buffer_putstr(target, tmpbuf); 1159 return (ISC_R_SUCCESS); 1160} 1161 1162static isc_boolean_t 1163buffer_empty(isc_buffer_t *source) { 1164 return((source->current == source->active) ? ISC_TRUE : ISC_FALSE); 1165} 1166 1167static void 1168buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region) { 1169 isc_buffer_init(buffer, region->base, region->length); 1170 isc_buffer_add(buffer, region->length); 1171 isc_buffer_setactive(buffer, region->length); 1172} 1173 1174static isc_result_t 1175uint32_tobuffer(isc_uint32_t value, isc_buffer_t *target) { 1176 isc_region_t region; 1177 1178 isc_buffer_availableregion(target, ®ion); 1179 if (region.length < 4) 1180 return (ISC_R_NOSPACE); 1181 isc_buffer_putuint32(target, value); 1182 return (ISC_R_SUCCESS); 1183} 1184 1185static isc_result_t 1186uint16_tobuffer(isc_uint32_t value, isc_buffer_t *target) { 1187 isc_region_t region; 1188 1189 if (value > 0xffff) 1190 return (ISC_R_RANGE); 1191 isc_buffer_availableregion(target, ®ion); 1192 if (region.length < 2) 1193 return (ISC_R_NOSPACE); 1194 isc_buffer_putuint16(target, (isc_uint16_t)value); 1195 return (ISC_R_SUCCESS); 1196} 1197 1198static isc_result_t 1199uint8_tobuffer(isc_uint32_t value, isc_buffer_t *target) { 1200 isc_region_t region; 1201 1202 if (value > 0xff) 1203 return (ISC_R_RANGE); 1204 isc_buffer_availableregion(target, ®ion); 1205 if (region.length < 1) 1206 return (ISC_R_NOSPACE); 1207 isc_buffer_putuint8(target, (isc_uint8_t)value); 1208 return (ISC_R_SUCCESS); 1209} 1210 1211static isc_result_t 1212name_tobuffer(dns_name_t *name, isc_buffer_t *target) { 1213 isc_region_t r; 1214 dns_name_toregion(name, &r); 1215 return (isc_buffer_copyregion(target, &r)); 1216} 1217 1218static isc_uint32_t 1219uint32_fromregion(isc_region_t *region) { 1220 isc_uint32_t value; 1221 1222 REQUIRE(region->length >= 4); 1223 value = region->base[0] << 24; 1224 value |= region->base[1] << 16; 1225 value |= region->base[2] << 8; 1226 value |= region->base[3]; 1227 return(value); 1228} 1229 1230static isc_uint16_t 1231uint16_fromregion(isc_region_t *region) { 1232 1233 REQUIRE(region->length >= 2); 1234 1235 return ((region->base[0] << 8) | region->base[1]); 1236} 1237 1238static isc_uint8_t 1239uint8_fromregion(isc_region_t *region) { 1240 1241 REQUIRE(region->length >= 1); 1242 1243 return (region->base[0]); 1244} 1245 1246static isc_result_t 1247mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { 1248 isc_region_t tr; 1249 1250 isc_buffer_availableregion(target, &tr); 1251 if (length > tr.length) 1252 return (ISC_R_NOSPACE); 1253 memcpy(tr.base, base, length); 1254 isc_buffer_add(target, length); 1255 return (ISC_R_SUCCESS); 1256} 1257 1258static int 1259hexvalue(char value) { 1260 char *s; 1261 unsigned char c; 1262 1263 c = (unsigned char)value; 1264 1265 if (!isascii(c)) 1266 return (-1); 1267 if (isupper(c)) 1268 c = tolower(c); 1269 if ((s = strchr(hexdigits, c)) == NULL) 1270 return (-1); 1271 return (s - hexdigits); 1272} 1273 1274static int 1275decvalue(char value) { 1276 char *s; 1277 1278 /* 1279 * isascii() is valid for full range of int values, no need to 1280 * mask or cast. 1281 */ 1282 if (!isascii(value)) 1283 return (-1); 1284 if ((s = strchr(decdigits, value)) == NULL) 1285 return (-1); 1286 return (s - decdigits); 1287} 1288 1289static const char atob_digits[86] = 1290 "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \ 1291 "abcdefghijklmnopqrstu"; 1292/* 1293 * Subroutines to convert between 8 bit binary bytes and printable ASCII. 1294 * Computes the number of bytes, and three kinds of simple checksums. 1295 * Incoming bytes are collected into 32-bit words, then printed in base 85: 1296 * exp(85,5) > exp(2,32) 1297 * The ASCII characters used are between '!' and 'u'; 1298 * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data. 1299 * 1300 * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for 1301 * the atob/btoa programs, released with the compress program, in mod.sources. 1302 * Modified by Mike Schwartz 8/19/86 for use in BIND. 1303 * Modified to be re-entrant 3/2/99. 1304 */ 1305 1306 1307struct state { 1308 isc_int32_t Ceor; 1309 isc_int32_t Csum; 1310 isc_int32_t Crot; 1311 isc_int32_t word; 1312 isc_int32_t bcount; 1313}; 1314 1315#define Ceor state->Ceor 1316#define Csum state->Csum 1317#define Crot state->Crot 1318#define word state->word 1319#define bcount state->bcount 1320 1321#define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x) 1322 1323static isc_result_t byte_atob(int c, isc_buffer_t *target, 1324 struct state *state); 1325static isc_result_t putbyte(int c, isc_buffer_t *, struct state *state); 1326static isc_result_t byte_btoa(int c, isc_buffer_t *, struct state *state); 1327 1328/* 1329 * Decode ASCII-encoded byte c into binary representation and 1330 * place into *bufp, advancing bufp. 1331 */ 1332static isc_result_t 1333byte_atob(int c, isc_buffer_t *target, struct state *state) { 1334 char *s; 1335 if (c == 'z') { 1336 if (bcount != 0) 1337 return(DNS_R_SYNTAX); 1338 else { 1339 RETERR(putbyte(0, target, state)); 1340 RETERR(putbyte(0, target, state)); 1341 RETERR(putbyte(0, target, state)); 1342 RETERR(putbyte(0, target, state)); 1343 } 1344 } else if ((s = strchr(atob_digits, c)) != NULL) { 1345 if (bcount == 0) { 1346 word = s - atob_digits; 1347 ++bcount; 1348 } else if (bcount < 4) { 1349 word = times85(word); 1350 word += s - atob_digits; 1351 ++bcount; 1352 } else { 1353 word = times85(word); 1354 word += s - atob_digits; 1355 RETERR(putbyte((word >> 24) & 0xff, target, state)); 1356 RETERR(putbyte((word >> 16) & 0xff, target, state)); 1357 RETERR(putbyte((word >> 8) & 0xff, target, state)); 1358 RETERR(putbyte(word & 0xff, target, state)); 1359 word = 0; 1360 bcount = 0; 1361 } 1362 } else 1363 return(DNS_R_SYNTAX); 1364 return(ISC_R_SUCCESS); 1365} 1366 1367/* 1368 * Compute checksum info and place c into target. 1369 */ 1370static isc_result_t 1371putbyte(int c, isc_buffer_t *target, struct state *state) { 1372 isc_region_t tr; 1373 1374 Ceor ^= c; 1375 Csum += c; 1376 Csum += 1; 1377 if ((Crot & 0x80000000)) { 1378 Crot <<= 1; 1379 Crot += 1; 1380 } else { 1381 Crot <<= 1; 1382 } 1383 Crot += c; 1384 isc_buffer_availableregion(target, &tr); 1385 if (tr.length < 1) 1386 return (ISC_R_NOSPACE); 1387 tr.base[0] = c; 1388 isc_buffer_add(target, 1); 1389 return (ISC_R_SUCCESS); 1390} 1391 1392/* 1393 * Read the ASCII-encoded data from inbuf, of length inbuflen, and convert 1394 * it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes; 1395 * outbuflen must be divisible by 4. (Note: this is because outbuf is filled 1396 * in 4 bytes at a time. If the actual data doesn't end on an even 4-byte 1397 * boundary, there will be no problem...it will be padded with 0 bytes, and 1398 * numbytes will indicate the correct number of bytes. The main point is 1399 * that since the buffer is filled in 4 bytes at a time, even if there is 1400 * not a full 4 bytes of data at the end, there has to be room to 0-pad the 1401 * data, so the buffer must be of size divisible by 4). Place the number of 1402 * output bytes in numbytes, and return a failure/success status. 1403 */ 1404 1405static isc_result_t 1406atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target) { 1407 long oeor, osum, orot; 1408 struct state statebuf, *state= &statebuf; 1409 isc_token_t token; 1410 char c; 1411 char *e; 1412 1413 Ceor = Csum = Crot = word = bcount = 0; 1414 1415 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 1416 ISC_FALSE)); 1417 while (token.value.as_textregion.length != 0) { 1418 if ((c = token.value.as_textregion.base[0]) == 'x') { 1419 break; 1420 } else 1421 RETERR(byte_atob(c, target, state)); 1422 isc_textregion_consume(&token.value.as_textregion, 1); 1423 } 1424 1425 /* 1426 * Number of bytes. 1427 */ 1428 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 1429 ISC_FALSE)); 1430 if ((token.value.as_ulong % 4) != 0U) 1431 isc_buffer_subtract(target, 4 - (token.value.as_ulong % 4)); 1432 1433 /* 1434 * Checksum. 1435 */ 1436 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 1437 ISC_FALSE)); 1438 oeor = strtol(DNS_AS_STR(token), &e, 16); 1439 if (*e != 0) 1440 return (DNS_R_SYNTAX); 1441 1442 /* 1443 * Checksum. 1444 */ 1445 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 1446 ISC_FALSE)); 1447 osum = strtol(DNS_AS_STR(token), &e, 16); 1448 if (*e != 0) 1449 return (DNS_R_SYNTAX); 1450 1451 /* 1452 * Checksum. 1453 */ 1454 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 1455 ISC_FALSE)); 1456 orot = strtol(DNS_AS_STR(token), &e, 16); 1457 if (*e != 0) 1458 return (DNS_R_SYNTAX); 1459 1460 if ((oeor != Ceor) || (osum != Csum) || (orot != Crot)) 1461 return(DNS_R_BADCKSUM); 1462 return (ISC_R_SUCCESS); 1463} 1464 1465/* 1466 * Encode binary byte c into ASCII representation and place into *bufp, 1467 * advancing bufp. 1468 */ 1469static isc_result_t 1470byte_btoa(int c, isc_buffer_t *target, struct state *state) { 1471 isc_region_t tr; 1472 1473 isc_buffer_availableregion(target, &tr); 1474 Ceor ^= c; 1475 Csum += c; 1476 Csum += 1; 1477 if ((Crot & 0x80000000)) { 1478 Crot <<= 1; 1479 Crot += 1; 1480 } else { 1481 Crot <<= 1; 1482 } 1483 Crot += c; 1484 1485 word <<= 8; 1486 word |= c; 1487 if (bcount == 3) { 1488 if (word == 0) { 1489 if (tr.length < 1) 1490 return (ISC_R_NOSPACE); 1491 tr.base[0] = 'z'; 1492 isc_buffer_add(target, 1); 1493 } else { 1494 register int tmp = 0; 1495 register isc_int32_t tmpword = word; 1496 1497 if (tmpword < 0) { 1498 /* 1499 * Because some don't support u_long. 1500 */ 1501 tmp = 32; 1502 tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32); 1503 } 1504 if (tmpword < 0) { 1505 tmp = 64; 1506 tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32); 1507 } 1508 if (tr.length < 5) 1509 return (ISC_R_NOSPACE); 1510 tr.base[0] = atob_digits[(tmpword / 1511 (isc_int32_t)(85 * 85 * 85 * 85)) 1512 + tmp]; 1513 tmpword %= (isc_int32_t)(85 * 85 * 85 * 85); 1514 tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)]; 1515 tmpword %= (85 * 85 * 85); 1516 tr.base[2] = atob_digits[tmpword / (85 * 85)]; 1517 tmpword %= (85 * 85); 1518 tr.base[3] = atob_digits[tmpword / 85]; 1519 tmpword %= 85; 1520 tr.base[4] = atob_digits[tmpword]; 1521 isc_buffer_add(target, 5); 1522 } 1523 bcount = 0; 1524 } else { 1525 bcount += 1; 1526 } 1527 return (ISC_R_SUCCESS); 1528} 1529 1530 1531/* 1532 * Encode the binary data from inbuf, of length inbuflen, into a 1533 * target. Return success/failure status 1534 */ 1535static isc_result_t 1536btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) { 1537 int inc; 1538 struct state statebuf, *state = &statebuf; 1539 char buf[sizeof("x 2000000000 ffffffff ffffffff ffffffff")]; 1540 1541 Ceor = Csum = Crot = word = bcount = 0; 1542 for (inc = 0; inc < inbuflen; inbuf++, inc++) 1543 RETERR(byte_btoa(*inbuf, target, state)); 1544 1545 while (bcount != 0) 1546 RETERR(byte_btoa(0, target, state)); 1547 1548 /* 1549 * Put byte count and checksum information at end of buffer, 1550 * delimited by 'x' 1551 */ 1552 snprintf(buf, sizeof(buf), "x %d %x %x %x", inbuflen, Ceor, Csum, Crot); 1553 return (str_totext(buf, target)); 1554} 1555 1556 1557static void 1558default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, 1559 ...) 1560{ 1561 va_list ap; 1562 1563 UNUSED(callbacks); 1564 1565 va_start(ap, fmt); 1566 vfprintf(stderr, fmt, ap); 1567 va_end(ap); 1568 fprintf(stderr, "\n"); 1569} 1570 1571static void 1572fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) { 1573 if (isc_lex_isfile(lexer) && callbacks != NULL) { 1574 const char *name = isc_lex_getsourcename(lexer); 1575 if (name == NULL) 1576 name = "UNKNOWN"; 1577 (*callbacks->warn)(callbacks, 1578 "%s:%lu: file does not end with newline", 1579 name, isc_lex_getsourceline(lexer)); 1580 } 1581} 1582 1583static void 1584warn_badname(dns_name_t *name, isc_lex_t *lexer, 1585 dns_rdatacallbacks_t *callbacks) 1586{ 1587 const char *file; 1588 unsigned long line; 1589 char namebuf[DNS_NAME_FORMATSIZE]; 1590 1591 if (lexer != NULL) { 1592 file = isc_lex_getsourcename(lexer); 1593 line = isc_lex_getsourceline(lexer); 1594 dns_name_format(name, namebuf, sizeof(namebuf)); 1595 (*callbacks->warn)(callbacks, "%s:%u: warning: %s: %s", 1596 file, line, namebuf, 1597 dns_result_totext(DNS_R_BADNAME)); 1598 } 1599} 1600 1601static void 1602fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...), 1603 dns_rdatacallbacks_t *callbacks, const char *name, 1604 unsigned long line, isc_token_t *token, isc_result_t result) 1605{ 1606 if (name == NULL) 1607 name = "UNKNOWN"; 1608 1609 if (token != NULL) { 1610 switch (token->type) { 1611 case isc_tokentype_eol: 1612 (*callback)(callbacks, "%s: %s:%lu: near eol: %s", 1613 "dns_rdata_fromtext", name, line, 1614 dns_result_totext(result)); 1615 break; 1616 case isc_tokentype_eof: 1617 (*callback)(callbacks, "%s: %s:%lu: near eof: %s", 1618 "dns_rdata_fromtext", name, line, 1619 dns_result_totext(result)); 1620 break; 1621 case isc_tokentype_number: 1622 (*callback)(callbacks, "%s: %s:%lu: near %lu: %s", 1623 "dns_rdata_fromtext", name, line, 1624 token->value.as_ulong, 1625 dns_result_totext(result)); 1626 break; 1627 case isc_tokentype_string: 1628 case isc_tokentype_qstring: 1629 (*callback)(callbacks, "%s: %s:%lu: near '%s': %s", 1630 "dns_rdata_fromtext", name, line, 1631 DNS_AS_STR(*token), 1632 dns_result_totext(result)); 1633 break; 1634 default: 1635 (*callback)(callbacks, "%s: %s:%lu: %s", 1636 "dns_rdata_fromtext", name, line, 1637 dns_result_totext(result)); 1638 break; 1639 } 1640 } else { 1641 (*callback)(callbacks, "dns_rdata_fromtext: %s:%lu: %s", 1642 name, line, dns_result_totext(result)); 1643 } 1644} 1645 1646dns_rdatatype_t 1647dns_rdata_covers(dns_rdata_t *rdata) { 1648 if (rdata->type == 46) 1649 return (covers_rrsig(rdata)); 1650 return (covers_sig(rdata)); 1651} 1652 1653isc_boolean_t 1654dns_rdatatype_ismeta(dns_rdatatype_t type) { 1655 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_META) != 0) 1656 return (ISC_TRUE); 1657 return (ISC_FALSE); 1658} 1659 1660isc_boolean_t 1661dns_rdatatype_issingleton(dns_rdatatype_t type) { 1662 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_SINGLETON) 1663 != 0) 1664 return (ISC_TRUE); 1665 return (ISC_FALSE); 1666} 1667 1668isc_boolean_t 1669dns_rdatatype_notquestion(dns_rdatatype_t type) { 1670 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_NOTQUESTION) 1671 != 0) 1672 return (ISC_TRUE); 1673 return (ISC_FALSE); 1674} 1675 1676isc_boolean_t 1677dns_rdatatype_questiononly(dns_rdatatype_t type) { 1678 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_QUESTIONONLY) 1679 != 0) 1680 return (ISC_TRUE); 1681 return (ISC_FALSE); 1682} 1683 1684isc_boolean_t 1685dns_rdatatype_atparent(dns_rdatatype_t type) { 1686 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_ATPARENT) != 0) 1687 return (ISC_TRUE); 1688 return (ISC_FALSE); 1689} 1690 1691isc_boolean_t 1692dns_rdataclass_ismeta(dns_rdataclass_t rdclass) { 1693 1694 if (rdclass == dns_rdataclass_reserved0 1695 || rdclass == dns_rdataclass_none 1696 || rdclass == dns_rdataclass_any) 1697 return (ISC_TRUE); 1698 1699 return (ISC_FALSE); /* Assume it is not a meta class. */ 1700} 1701 1702isc_boolean_t 1703dns_rdatatype_isdnssec(dns_rdatatype_t type) { 1704 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_DNSSEC) != 0) 1705 return (ISC_TRUE); 1706 return (ISC_FALSE); 1707} 1708 1709isc_boolean_t 1710dns_rdatatype_iszonecutauth(dns_rdatatype_t type) { 1711 if ((dns_rdatatype_attributes(type) 1712 & (DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH)) 1713 != 0) 1714 return (ISC_TRUE); 1715 return (ISC_FALSE); 1716} 1717 1718isc_boolean_t 1719dns_rdatatype_isknown(dns_rdatatype_t type) { 1720 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_UNKNOWN) 1721 == 0) 1722 return (ISC_TRUE); 1723 return (ISC_FALSE); 1724} 1725