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