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