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