rdata.c revision 224092
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 2011-01-13 04:59:25 tbox Exp $ */ 19 20/*! \file */ 21 22#include <config.h> 23#include <ctype.h> 24 25#include <isc/base64.h> 26#include <isc/hex.h> 27#include <isc/lex.h> 28#include <isc/mem.h> 29#include <isc/parseint.h> 30#include <isc/print.h> 31#include <isc/string.h> 32#include <isc/stdlib.h> 33#include <isc/util.h> 34 35#include <dns/callbacks.h> 36#include <dns/cert.h> 37#include <dns/compress.h> 38#include <dns/enumtype.h> 39#include <dns/keyflags.h> 40#include <dns/keyvalues.h> 41#include <dns/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 dns_rdata_toregion(rdata, &sr); 712 INSIST(sr.length < 65536); 713 snprintf(buf, sizeof(buf), "%u", sr.length); 714 result = str_totext(buf, target); 715 if (sr.length != 0 && result == ISC_R_SUCCESS) { 716 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 717 result = str_totext(" ( ", target); 718 else 719 result = str_totext(" ", target); 720 if (result == ISC_R_SUCCESS) 721 result = isc_hex_totext(&sr, tctx->width - 2, 722 tctx->linebreak, 723 target); 724 if (result == ISC_R_SUCCESS && 725 (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 726 result = str_totext(" )", target); 727 } 728 } 729 730 return (result); 731} 732 733isc_result_t 734dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) 735{ 736 dns_rdata_textctx_t tctx; 737 738 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 739 740 /* 741 * Set up formatting options for single-line output. 742 */ 743 tctx.origin = origin; 744 tctx.flags = 0; 745 tctx.width = 60; 746 tctx.linebreak = " "; 747 return (rdata_totext(rdata, &tctx, target)); 748} 749 750isc_result_t 751dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, 752 unsigned int flags, unsigned int width, 753 const char *linebreak, isc_buffer_t *target) 754{ 755 dns_rdata_textctx_t tctx; 756 757 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 758 759 /* 760 * Set up formatting options for formatted output. 761 */ 762 tctx.origin = origin; 763 tctx.flags = flags; 764 if ((flags & DNS_STYLEFLAG_MULTILINE) != 0) { 765 tctx.width = width; 766 tctx.linebreak = linebreak; 767 } else { 768 tctx.width = 60; /* Used for hex word length only. */ 769 tctx.linebreak = " "; 770 } 771 return (rdata_totext(rdata, &tctx, target)); 772} 773 774isc_result_t 775dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 776 dns_rdatatype_t type, void *source, 777 isc_buffer_t *target) 778{ 779 isc_result_t result = ISC_R_NOTIMPLEMENTED; 780 isc_buffer_t st; 781 isc_region_t region; 782 isc_boolean_t use_default = ISC_FALSE; 783 784 REQUIRE(source != NULL); 785 if (rdata != NULL) { 786 REQUIRE(DNS_RDATA_INITIALIZED(rdata)); 787 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 788 } 789 790 st = *target; 791 792 FROMSTRUCTSWITCH 793 794 if (use_default) 795 (void)NULL; 796 797 if (rdata != NULL && result == ISC_R_SUCCESS) { 798 region.base = isc_buffer_used(&st); 799 region.length = isc_buffer_usedlength(target) - 800 isc_buffer_usedlength(&st); 801 dns_rdata_fromregion(rdata, rdclass, type, ®ion); 802 } 803 if (result != ISC_R_SUCCESS) 804 *target = st; 805 return (result); 806} 807 808isc_result_t 809dns_rdata_tostruct(dns_rdata_t *rdata, void *target, isc_mem_t *mctx) { 810 isc_result_t result = ISC_R_NOTIMPLEMENTED; 811 isc_boolean_t use_default = ISC_FALSE; 812 813 REQUIRE(rdata != NULL); 814 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 815 816 TOSTRUCTSWITCH 817 818 if (use_default) 819 (void)NULL; 820 821 return (result); 822} 823 824void 825dns_rdata_freestruct(void *source) { 826 dns_rdatacommon_t *common = source; 827 REQUIRE(source != NULL); 828 829 FREESTRUCTSWITCH 830} 831 832isc_result_t 833dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add, 834 void *arg) 835{ 836 isc_result_t result = ISC_R_NOTIMPLEMENTED; 837 isc_boolean_t use_default = ISC_FALSE; 838 839 /* 840 * Call 'add' for each name and type from 'rdata' which is subject to 841 * additional section processing. 842 */ 843 844 REQUIRE(rdata != NULL); 845 REQUIRE(add != NULL); 846 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 847 848 ADDITIONALDATASWITCH 849 850 /* No additional processing for unknown types */ 851 if (use_default) 852 result = ISC_R_SUCCESS; 853 854 return (result); 855} 856 857isc_result_t 858dns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg) { 859 isc_result_t result = ISC_R_NOTIMPLEMENTED; 860 isc_boolean_t use_default = ISC_FALSE; 861 isc_region_t r; 862 863 /* 864 * Send 'rdata' in DNSSEC canonical form to 'digest'. 865 */ 866 867 REQUIRE(rdata != NULL); 868 REQUIRE(digest != NULL); 869 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 870 871 DIGESTSWITCH 872 873 if (use_default) { 874 dns_rdata_toregion(rdata, &r); 875 result = (digest)(arg, &r); 876 } 877 878 return (result); 879} 880 881isc_boolean_t 882dns_rdata_checkowner(dns_name_t *name, dns_rdataclass_t rdclass, 883 dns_rdatatype_t type, isc_boolean_t wildcard) 884{ 885 isc_boolean_t result; 886 887 CHECKOWNERSWITCH 888 return (result); 889} 890 891isc_boolean_t 892dns_rdata_checknames(dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad) 893{ 894 isc_boolean_t result; 895 896 CHECKNAMESSWITCH 897 return (result); 898} 899 900unsigned int 901dns_rdatatype_attributes(dns_rdatatype_t type) 902{ 903 RDATATYPE_ATTRIBUTE_SW 904 if (type >= (dns_rdatatype_t)128 && type < (dns_rdatatype_t)255) 905 return (DNS_RDATATYPEATTR_UNKNOWN | DNS_RDATATYPEATTR_META); 906 return (DNS_RDATATYPEATTR_UNKNOWN); 907} 908 909isc_result_t 910dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) { 911 unsigned int hash; 912 unsigned int n; 913 unsigned char a, b; 914 915 n = source->length; 916 917 if (n == 0) 918 return (DNS_R_UNKNOWN); 919 920 a = tolower((unsigned char)source->base[0]); 921 b = tolower((unsigned char)source->base[n - 1]); 922 923 hash = ((a + n) * b) % 256; 924 925 /* 926 * This switch block is inlined via \#define, and will use "return" 927 * to return a result to the caller if it is a valid (known) 928 * rdatatype name. 929 */ 930 RDATATYPE_FROMTEXT_SW(hash, source->base, n, typep); 931 932 if (source->length > 4 && source->length < (4 + sizeof("65000")) && 933 strncasecmp("type", source->base, 4) == 0) { 934 char buf[sizeof("65000")]; 935 char *endp; 936 unsigned int val; 937 938 strncpy(buf, source->base + 4, source->length - 4); 939 buf[source->length - 4] = '\0'; 940 val = strtoul(buf, &endp, 10); 941 if (*endp == '\0' && val <= 0xffff) { 942 *typep = (dns_rdatatype_t)val; 943 return (ISC_R_SUCCESS); 944 } 945 } 946 947 return (DNS_R_UNKNOWN); 948} 949 950isc_result_t 951dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) { 952 char buf[sizeof("TYPE65535")]; 953 954 RDATATYPE_TOTEXT_SW 955 snprintf(buf, sizeof(buf), "TYPE%u", type); 956 return (str_totext(buf, target)); 957} 958 959void 960dns_rdatatype_format(dns_rdatatype_t rdtype, 961 char *array, unsigned int size) 962{ 963 isc_result_t result; 964 isc_buffer_t buf; 965 966 isc_buffer_init(&buf, array, size); 967 result = dns_rdatatype_totext(rdtype, &buf); 968 /* 969 * Null terminate. 970 */ 971 if (result == ISC_R_SUCCESS) { 972 if (isc_buffer_availablelength(&buf) >= 1) 973 isc_buffer_putuint8(&buf, 0); 974 else 975 result = ISC_R_NOSPACE; 976 } 977 if (result != ISC_R_SUCCESS) { 978 snprintf(array, size, "<unknown>"); 979 array[size - 1] = '\0'; 980 } 981} 982 983/* 984 * Private function. 985 */ 986 987static unsigned int 988name_length(dns_name_t *name) { 989 return (name->length); 990} 991 992static isc_result_t 993txt_totext(isc_region_t *source, isc_buffer_t *target) { 994 unsigned int tl; 995 unsigned int n; 996 unsigned char *sp; 997 char *tp; 998 isc_region_t region; 999 1000 isc_buffer_availableregion(target, ®ion); 1001 sp = source->base; 1002 tp = (char *)region.base; 1003 tl = region.length; 1004 1005 n = *sp++; 1006 1007 REQUIRE(n + 1 <= source->length); 1008 1009 if (tl < 1) 1010 return (ISC_R_NOSPACE); 1011 *tp++ = '"'; 1012 tl--; 1013 while (n--) { 1014 if (*sp < 0x20 || *sp >= 0x7f) { 1015 if (tl < 4) 1016 return (ISC_R_NOSPACE); 1017 *tp++ = 0x5c; 1018 *tp++ = 0x30 + ((*sp / 100) % 10); 1019 *tp++ = 0x30 + ((*sp / 10) % 10); 1020 *tp++ = 0x30 + (*sp % 10); 1021 sp++; 1022 tl -= 4; 1023 continue; 1024 } 1025 /* double quote, semi-colon, backslash */ 1026 if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) { 1027 if (tl < 2) 1028 return (ISC_R_NOSPACE); 1029 *tp++ = '\\'; 1030 tl--; 1031 } 1032 if (tl < 1) 1033 return (ISC_R_NOSPACE); 1034 *tp++ = *sp++; 1035 tl--; 1036 } 1037 if (tl < 1) 1038 return (ISC_R_NOSPACE); 1039 *tp++ = '"'; 1040 tl--; 1041 isc_buffer_add(target, tp - (char *)region.base); 1042 isc_region_consume(source, *source->base + 1); 1043 return (ISC_R_SUCCESS); 1044} 1045 1046static isc_result_t 1047txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) { 1048 isc_region_t tregion; 1049 isc_boolean_t escape; 1050 unsigned int n, nrem; 1051 char *s; 1052 unsigned char *t; 1053 int d; 1054 int c; 1055 1056 isc_buffer_availableregion(target, &tregion); 1057 s = source->base; 1058 n = source->length; 1059 t = tregion.base; 1060 nrem = tregion.length; 1061 escape = ISC_FALSE; 1062 if (nrem < 1) 1063 return (ISC_R_NOSPACE); 1064 /* 1065 * Length byte. 1066 */ 1067 nrem--; 1068 t++; 1069 /* 1070 * Maximum text string length. 1071 */ 1072 if (nrem > 255) 1073 nrem = 255; 1074 while (n-- != 0) { 1075 c = (*s++) & 0xff; 1076 if (escape && (d = decvalue((char)c)) != -1) { 1077 c = d; 1078 if (n == 0) 1079 return (DNS_R_SYNTAX); 1080 n--; 1081 if ((d = decvalue(*s++)) != -1) 1082 c = c * 10 + d; 1083 else 1084 return (DNS_R_SYNTAX); 1085 if (n == 0) 1086 return (DNS_R_SYNTAX); 1087 n--; 1088 if ((d = decvalue(*s++)) != -1) 1089 c = c * 10 + d; 1090 else 1091 return (DNS_R_SYNTAX); 1092 if (c > 255) 1093 return (DNS_R_SYNTAX); 1094 } else if (!escape && c == '\\') { 1095 escape = ISC_TRUE; 1096 continue; 1097 } 1098 escape = ISC_FALSE; 1099 if (nrem == 0) 1100 return (ISC_R_NOSPACE); 1101 *t++ = c; 1102 nrem--; 1103 } 1104 if (escape) 1105 return (DNS_R_SYNTAX); 1106 *tregion.base = t - tregion.base - 1; 1107 isc_buffer_add(target, *tregion.base + 1); 1108 return (ISC_R_SUCCESS); 1109} 1110 1111static isc_result_t 1112txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { 1113 unsigned int n; 1114 isc_region_t sregion; 1115 isc_region_t tregion; 1116 1117 isc_buffer_activeregion(source, &sregion); 1118 if (sregion.length == 0) 1119 return(ISC_R_UNEXPECTEDEND); 1120 n = *sregion.base + 1; 1121 if (n > sregion.length) 1122 return (ISC_R_UNEXPECTEDEND); 1123 1124 isc_buffer_availableregion(target, &tregion); 1125 if (n > tregion.length) 1126 return (ISC_R_NOSPACE); 1127 1128 memcpy(tregion.base, sregion.base, n); 1129 isc_buffer_forward(source, n); 1130 isc_buffer_add(target, n); 1131 return (ISC_R_SUCCESS); 1132} 1133 1134static isc_boolean_t 1135name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) { 1136 int l1, l2; 1137 1138 if (origin == NULL) 1139 goto return_false; 1140 1141 if (dns_name_compare(origin, dns_rootname) == 0) 1142 goto return_false; 1143 1144 if (!dns_name_issubdomain(name, origin)) 1145 goto return_false; 1146 1147 l1 = dns_name_countlabels(name); 1148 l2 = dns_name_countlabels(origin); 1149 1150 if (l1 == l2) 1151 goto return_false; 1152 1153 /* Master files should be case preserving. */ 1154 dns_name_getlabelsequence(name, l1 - l2, l2, target); 1155 if (!dns_name_caseequal(origin, target)) 1156 goto return_false; 1157 1158 dns_name_getlabelsequence(name, 0, l1 - l2, target); 1159 return (ISC_TRUE); 1160 1161return_false: 1162 *target = *name; 1163 return (ISC_FALSE); 1164} 1165 1166static isc_result_t 1167str_totext(const char *source, isc_buffer_t *target) { 1168 unsigned int l; 1169 isc_region_t region; 1170 1171 isc_buffer_availableregion(target, ®ion); 1172 l = strlen(source); 1173 1174 if (l > region.length) 1175 return (ISC_R_NOSPACE); 1176 1177 memcpy(region.base, source, l); 1178 isc_buffer_add(target, l); 1179 return (ISC_R_SUCCESS); 1180} 1181 1182static isc_result_t 1183inet_totext(int af, isc_region_t *src, isc_buffer_t *target) { 1184 char tmpbuf[64]; 1185 1186 /* Note - inet_ntop doesn't do size checking on its input. */ 1187 if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL) 1188 return (ISC_R_NOSPACE); 1189 if (strlen(tmpbuf) > isc_buffer_availablelength(target)) 1190 return (ISC_R_NOSPACE); 1191 isc_buffer_putstr(target, tmpbuf); 1192 return (ISC_R_SUCCESS); 1193} 1194 1195static isc_boolean_t 1196buffer_empty(isc_buffer_t *source) { 1197 return((source->current == source->active) ? ISC_TRUE : ISC_FALSE); 1198} 1199 1200static void 1201buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region) { 1202 isc_buffer_init(buffer, region->base, region->length); 1203 isc_buffer_add(buffer, region->length); 1204 isc_buffer_setactive(buffer, region->length); 1205} 1206 1207static isc_result_t 1208uint32_tobuffer(isc_uint32_t value, isc_buffer_t *target) { 1209 isc_region_t region; 1210 1211 isc_buffer_availableregion(target, ®ion); 1212 if (region.length < 4) 1213 return (ISC_R_NOSPACE); 1214 isc_buffer_putuint32(target, value); 1215 return (ISC_R_SUCCESS); 1216} 1217 1218static isc_result_t 1219uint16_tobuffer(isc_uint32_t value, isc_buffer_t *target) { 1220 isc_region_t region; 1221 1222 if (value > 0xffff) 1223 return (ISC_R_RANGE); 1224 isc_buffer_availableregion(target, ®ion); 1225 if (region.length < 2) 1226 return (ISC_R_NOSPACE); 1227 isc_buffer_putuint16(target, (isc_uint16_t)value); 1228 return (ISC_R_SUCCESS); 1229} 1230 1231static isc_result_t 1232uint8_tobuffer(isc_uint32_t value, isc_buffer_t *target) { 1233 isc_region_t region; 1234 1235 if (value > 0xff) 1236 return (ISC_R_RANGE); 1237 isc_buffer_availableregion(target, ®ion); 1238 if (region.length < 1) 1239 return (ISC_R_NOSPACE); 1240 isc_buffer_putuint8(target, (isc_uint8_t)value); 1241 return (ISC_R_SUCCESS); 1242} 1243 1244static isc_result_t 1245name_tobuffer(dns_name_t *name, isc_buffer_t *target) { 1246 isc_region_t r; 1247 dns_name_toregion(name, &r); 1248 return (isc_buffer_copyregion(target, &r)); 1249} 1250 1251static isc_uint32_t 1252uint32_fromregion(isc_region_t *region) { 1253 isc_uint32_t value; 1254 1255 REQUIRE(region->length >= 4); 1256 value = region->base[0] << 24; 1257 value |= region->base[1] << 16; 1258 value |= region->base[2] << 8; 1259 value |= region->base[3]; 1260 return(value); 1261} 1262 1263static isc_uint16_t 1264uint16_consume_fromregion(isc_region_t *region) { 1265 isc_uint16_t r = uint16_fromregion(region); 1266 1267 isc_region_consume(region, 2); 1268 return r; 1269} 1270 1271static isc_uint16_t 1272uint16_fromregion(isc_region_t *region) { 1273 1274 REQUIRE(region->length >= 2); 1275 1276 return ((region->base[0] << 8) | region->base[1]); 1277} 1278 1279static isc_uint8_t 1280uint8_fromregion(isc_region_t *region) { 1281 1282 REQUIRE(region->length >= 1); 1283 1284 return (region->base[0]); 1285} 1286 1287static isc_uint8_t 1288uint8_consume_fromregion(isc_region_t *region) { 1289 isc_uint8_t r = uint8_fromregion(region); 1290 1291 isc_region_consume(region, 1); 1292 return r; 1293} 1294 1295static isc_result_t 1296mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { 1297 isc_region_t tr; 1298 1299 isc_buffer_availableregion(target, &tr); 1300 if (length > tr.length) 1301 return (ISC_R_NOSPACE); 1302 memcpy(tr.base, base, length); 1303 isc_buffer_add(target, length); 1304 return (ISC_R_SUCCESS); 1305} 1306 1307static int 1308hexvalue(char value) { 1309 char *s; 1310 unsigned char c; 1311 1312 c = (unsigned char)value; 1313 1314 if (!isascii(c)) 1315 return (-1); 1316 if (isupper(c)) 1317 c = tolower(c); 1318 if ((s = strchr(hexdigits, c)) == NULL) 1319 return (-1); 1320 return (s - hexdigits); 1321} 1322 1323static int 1324decvalue(char value) { 1325 char *s; 1326 1327 /* 1328 * isascii() is valid for full range of int values, no need to 1329 * mask or cast. 1330 */ 1331 if (!isascii(value)) 1332 return (-1); 1333 if ((s = strchr(decdigits, value)) == NULL) 1334 return (-1); 1335 return (s - decdigits); 1336} 1337 1338static const char atob_digits[86] = 1339 "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \ 1340 "abcdefghijklmnopqrstu"; 1341/* 1342 * Subroutines to convert between 8 bit binary bytes and printable ASCII. 1343 * Computes the number of bytes, and three kinds of simple checksums. 1344 * Incoming bytes are collected into 32-bit words, then printed in base 85: 1345 * exp(85,5) > exp(2,32) 1346 * The ASCII characters used are between '!' and 'u'; 1347 * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data. 1348 * 1349 * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for 1350 * the atob/btoa programs, released with the compress program, in mod.sources. 1351 * Modified by Mike Schwartz 8/19/86 for use in BIND. 1352 * Modified to be re-entrant 3/2/99. 1353 */ 1354 1355 1356struct state { 1357 isc_int32_t Ceor; 1358 isc_int32_t Csum; 1359 isc_int32_t Crot; 1360 isc_int32_t word; 1361 isc_int32_t bcount; 1362}; 1363 1364#define Ceor state->Ceor 1365#define Csum state->Csum 1366#define Crot state->Crot 1367#define word state->word 1368#define bcount state->bcount 1369 1370#define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x) 1371 1372static isc_result_t byte_atob(int c, isc_buffer_t *target, 1373 struct state *state); 1374static isc_result_t putbyte(int c, isc_buffer_t *, struct state *state); 1375static isc_result_t byte_btoa(int c, isc_buffer_t *, struct state *state); 1376 1377/* 1378 * Decode ASCII-encoded byte c into binary representation and 1379 * place into *bufp, advancing bufp. 1380 */ 1381static isc_result_t 1382byte_atob(int c, isc_buffer_t *target, struct state *state) { 1383 char *s; 1384 if (c == 'z') { 1385 if (bcount != 0) 1386 return(DNS_R_SYNTAX); 1387 else { 1388 RETERR(putbyte(0, target, state)); 1389 RETERR(putbyte(0, target, state)); 1390 RETERR(putbyte(0, target, state)); 1391 RETERR(putbyte(0, target, state)); 1392 } 1393 } else if ((s = strchr(atob_digits, c)) != NULL) { 1394 if (bcount == 0) { 1395 word = s - atob_digits; 1396 ++bcount; 1397 } else if (bcount < 4) { 1398 word = times85(word); 1399 word += s - atob_digits; 1400 ++bcount; 1401 } else { 1402 word = times85(word); 1403 word += s - atob_digits; 1404 RETERR(putbyte((word >> 24) & 0xff, target, state)); 1405 RETERR(putbyte((word >> 16) & 0xff, target, state)); 1406 RETERR(putbyte((word >> 8) & 0xff, target, state)); 1407 RETERR(putbyte(word & 0xff, target, state)); 1408 word = 0; 1409 bcount = 0; 1410 } 1411 } else 1412 return(DNS_R_SYNTAX); 1413 return(ISC_R_SUCCESS); 1414} 1415 1416/* 1417 * Compute checksum info and place c into target. 1418 */ 1419static isc_result_t 1420putbyte(int c, isc_buffer_t *target, struct state *state) { 1421 isc_region_t tr; 1422 1423 Ceor ^= c; 1424 Csum += c; 1425 Csum += 1; 1426 if ((Crot & 0x80000000)) { 1427 Crot <<= 1; 1428 Crot += 1; 1429 } else { 1430 Crot <<= 1; 1431 } 1432 Crot += c; 1433 isc_buffer_availableregion(target, &tr); 1434 if (tr.length < 1) 1435 return (ISC_R_NOSPACE); 1436 tr.base[0] = c; 1437 isc_buffer_add(target, 1); 1438 return (ISC_R_SUCCESS); 1439} 1440 1441/* 1442 * Read the ASCII-encoded data from inbuf, of length inbuflen, and convert 1443 * it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes; 1444 * outbuflen must be divisible by 4. (Note: this is because outbuf is filled 1445 * in 4 bytes at a time. If the actual data doesn't end on an even 4-byte 1446 * boundary, there will be no problem...it will be padded with 0 bytes, and 1447 * numbytes will indicate the correct number of bytes. The main point is 1448 * that since the buffer is filled in 4 bytes at a time, even if there is 1449 * not a full 4 bytes of data at the end, there has to be room to 0-pad the 1450 * data, so the buffer must be of size divisible by 4). Place the number of 1451 * output bytes in numbytes, and return a failure/success status. 1452 */ 1453 1454static isc_result_t 1455atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target) { 1456 long oeor, osum, orot; 1457 struct state statebuf, *state= &statebuf; 1458 isc_token_t token; 1459 char c; 1460 char *e; 1461 1462 Ceor = Csum = Crot = word = bcount = 0; 1463 1464 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 1465 ISC_FALSE)); 1466 while (token.value.as_textregion.length != 0) { 1467 if ((c = token.value.as_textregion.base[0]) == 'x') { 1468 break; 1469 } else 1470 RETERR(byte_atob(c, target, state)); 1471 isc_textregion_consume(&token.value.as_textregion, 1); 1472 } 1473 1474 /* 1475 * Number of bytes. 1476 */ 1477 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 1478 ISC_FALSE)); 1479 if ((token.value.as_ulong % 4) != 0U) 1480 isc_buffer_subtract(target, 4 - (token.value.as_ulong % 4)); 1481 1482 /* 1483 * Checksum. 1484 */ 1485 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 1486 ISC_FALSE)); 1487 oeor = strtol(DNS_AS_STR(token), &e, 16); 1488 if (*e != 0) 1489 return (DNS_R_SYNTAX); 1490 1491 /* 1492 * Checksum. 1493 */ 1494 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 1495 ISC_FALSE)); 1496 osum = strtol(DNS_AS_STR(token), &e, 16); 1497 if (*e != 0) 1498 return (DNS_R_SYNTAX); 1499 1500 /* 1501 * Checksum. 1502 */ 1503 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 1504 ISC_FALSE)); 1505 orot = strtol(DNS_AS_STR(token), &e, 16); 1506 if (*e != 0) 1507 return (DNS_R_SYNTAX); 1508 1509 if ((oeor != Ceor) || (osum != Csum) || (orot != Crot)) 1510 return(DNS_R_BADCKSUM); 1511 return (ISC_R_SUCCESS); 1512} 1513 1514/* 1515 * Encode binary byte c into ASCII representation and place into *bufp, 1516 * advancing bufp. 1517 */ 1518static isc_result_t 1519byte_btoa(int c, isc_buffer_t *target, struct state *state) { 1520 isc_region_t tr; 1521 1522 isc_buffer_availableregion(target, &tr); 1523 Ceor ^= c; 1524 Csum += c; 1525 Csum += 1; 1526 if ((Crot & 0x80000000)) { 1527 Crot <<= 1; 1528 Crot += 1; 1529 } else { 1530 Crot <<= 1; 1531 } 1532 Crot += c; 1533 1534 word <<= 8; 1535 word |= c; 1536 if (bcount == 3) { 1537 if (word == 0) { 1538 if (tr.length < 1) 1539 return (ISC_R_NOSPACE); 1540 tr.base[0] = 'z'; 1541 isc_buffer_add(target, 1); 1542 } else { 1543 register int tmp = 0; 1544 register isc_int32_t tmpword = word; 1545 1546 if (tmpword < 0) { 1547 /* 1548 * Because some don't support u_long. 1549 */ 1550 tmp = 32; 1551 tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32); 1552 } 1553 if (tmpword < 0) { 1554 tmp = 64; 1555 tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32); 1556 } 1557 if (tr.length < 5) 1558 return (ISC_R_NOSPACE); 1559 tr.base[0] = atob_digits[(tmpword / 1560 (isc_int32_t)(85 * 85 * 85 * 85)) 1561 + tmp]; 1562 tmpword %= (isc_int32_t)(85 * 85 * 85 * 85); 1563 tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)]; 1564 tmpword %= (85 * 85 * 85); 1565 tr.base[2] = atob_digits[tmpword / (85 * 85)]; 1566 tmpword %= (85 * 85); 1567 tr.base[3] = atob_digits[tmpword / 85]; 1568 tmpword %= 85; 1569 tr.base[4] = atob_digits[tmpword]; 1570 isc_buffer_add(target, 5); 1571 } 1572 bcount = 0; 1573 } else { 1574 bcount += 1; 1575 } 1576 return (ISC_R_SUCCESS); 1577} 1578 1579 1580/* 1581 * Encode the binary data from inbuf, of length inbuflen, into a 1582 * target. Return success/failure status 1583 */ 1584static isc_result_t 1585btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) { 1586 int inc; 1587 struct state statebuf, *state = &statebuf; 1588 char buf[sizeof("x 2000000000 ffffffff ffffffff ffffffff")]; 1589 1590 Ceor = Csum = Crot = word = bcount = 0; 1591 for (inc = 0; inc < inbuflen; inbuf++, inc++) 1592 RETERR(byte_btoa(*inbuf, target, state)); 1593 1594 while (bcount != 0) 1595 RETERR(byte_btoa(0, target, state)); 1596 1597 /* 1598 * Put byte count and checksum information at end of buffer, 1599 * delimited by 'x' 1600 */ 1601 snprintf(buf, sizeof(buf), "x %d %x %x %x", inbuflen, Ceor, Csum, Crot); 1602 return (str_totext(buf, target)); 1603} 1604 1605 1606static void 1607default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, 1608 ...) 1609{ 1610 va_list ap; 1611 1612 UNUSED(callbacks); 1613 1614 va_start(ap, fmt); 1615 vfprintf(stderr, fmt, ap); 1616 va_end(ap); 1617 fprintf(stderr, "\n"); 1618} 1619 1620static void 1621fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) { 1622 if (isc_lex_isfile(lexer) && callbacks != NULL) { 1623 const char *name = isc_lex_getsourcename(lexer); 1624 if (name == NULL) 1625 name = "UNKNOWN"; 1626 (*callbacks->warn)(callbacks, 1627 "%s:%lu: file does not end with newline", 1628 name, isc_lex_getsourceline(lexer)); 1629 } 1630} 1631 1632static void 1633warn_badmx(isc_token_t *token, isc_lex_t *lexer, 1634 dns_rdatacallbacks_t *callbacks) 1635{ 1636 const char *file; 1637 unsigned long line; 1638 1639 if (lexer != NULL) { 1640 file = isc_lex_getsourcename(lexer); 1641 line = isc_lex_getsourceline(lexer); 1642 (*callbacks->warn)(callbacks, "%s:%u: warning: '%s': %s", 1643 file, line, DNS_AS_STR(*token), 1644 dns_result_totext(DNS_R_MXISADDRESS)); 1645 } 1646} 1647 1648static void 1649warn_badname(dns_name_t *name, isc_lex_t *lexer, 1650 dns_rdatacallbacks_t *callbacks) 1651{ 1652 const char *file; 1653 unsigned long line; 1654 char namebuf[DNS_NAME_FORMATSIZE]; 1655 1656 if (lexer != NULL) { 1657 file = isc_lex_getsourcename(lexer); 1658 line = isc_lex_getsourceline(lexer); 1659 dns_name_format(name, namebuf, sizeof(namebuf)); 1660 (*callbacks->warn)(callbacks, "%s:%u: warning: %s: %s", 1661 file, line, namebuf, 1662 dns_result_totext(DNS_R_BADNAME)); 1663 } 1664} 1665 1666static void 1667fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...), 1668 dns_rdatacallbacks_t *callbacks, const char *name, 1669 unsigned long line, isc_token_t *token, isc_result_t result) 1670{ 1671 if (name == NULL) 1672 name = "UNKNOWN"; 1673 1674 if (token != NULL) { 1675 switch (token->type) { 1676 case isc_tokentype_eol: 1677 (*callback)(callbacks, "%s: %s:%lu: near eol: %s", 1678 "dns_rdata_fromtext", name, line, 1679 dns_result_totext(result)); 1680 break; 1681 case isc_tokentype_eof: 1682 (*callback)(callbacks, "%s: %s:%lu: near eof: %s", 1683 "dns_rdata_fromtext", name, line, 1684 dns_result_totext(result)); 1685 break; 1686 case isc_tokentype_number: 1687 (*callback)(callbacks, "%s: %s:%lu: near %lu: %s", 1688 "dns_rdata_fromtext", name, line, 1689 token->value.as_ulong, 1690 dns_result_totext(result)); 1691 break; 1692 case isc_tokentype_string: 1693 case isc_tokentype_qstring: 1694 (*callback)(callbacks, "%s: %s:%lu: near '%s': %s", 1695 "dns_rdata_fromtext", name, line, 1696 DNS_AS_STR(*token), 1697 dns_result_totext(result)); 1698 break; 1699 default: 1700 (*callback)(callbacks, "%s: %s:%lu: %s", 1701 "dns_rdata_fromtext", name, line, 1702 dns_result_totext(result)); 1703 break; 1704 } 1705 } else { 1706 (*callback)(callbacks, "dns_rdata_fromtext: %s:%lu: %s", 1707 name, line, dns_result_totext(result)); 1708 } 1709} 1710 1711dns_rdatatype_t 1712dns_rdata_covers(dns_rdata_t *rdata) { 1713 if (rdata->type == 46) 1714 return (covers_rrsig(rdata)); 1715 return (covers_sig(rdata)); 1716} 1717 1718isc_boolean_t 1719dns_rdatatype_ismeta(dns_rdatatype_t type) { 1720 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_META) != 0) 1721 return (ISC_TRUE); 1722 return (ISC_FALSE); 1723} 1724 1725isc_boolean_t 1726dns_rdatatype_issingleton(dns_rdatatype_t type) { 1727 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_SINGLETON) 1728 != 0) 1729 return (ISC_TRUE); 1730 return (ISC_FALSE); 1731} 1732 1733isc_boolean_t 1734dns_rdatatype_notquestion(dns_rdatatype_t type) { 1735 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_NOTQUESTION) 1736 != 0) 1737 return (ISC_TRUE); 1738 return (ISC_FALSE); 1739} 1740 1741isc_boolean_t 1742dns_rdatatype_questiononly(dns_rdatatype_t type) { 1743 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_QUESTIONONLY) 1744 != 0) 1745 return (ISC_TRUE); 1746 return (ISC_FALSE); 1747} 1748 1749isc_boolean_t 1750dns_rdatatype_atparent(dns_rdatatype_t type) { 1751 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_ATPARENT) != 0) 1752 return (ISC_TRUE); 1753 return (ISC_FALSE); 1754} 1755 1756isc_boolean_t 1757dns_rdataclass_ismeta(dns_rdataclass_t rdclass) { 1758 1759 if (rdclass == dns_rdataclass_reserved0 1760 || rdclass == dns_rdataclass_none 1761 || rdclass == dns_rdataclass_any) 1762 return (ISC_TRUE); 1763 1764 return (ISC_FALSE); /* Assume it is not a meta class. */ 1765} 1766 1767isc_boolean_t 1768dns_rdatatype_isdnssec(dns_rdatatype_t type) { 1769 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_DNSSEC) != 0) 1770 return (ISC_TRUE); 1771 return (ISC_FALSE); 1772} 1773 1774isc_boolean_t 1775dns_rdatatype_iszonecutauth(dns_rdatatype_t type) { 1776 if ((dns_rdatatype_attributes(type) 1777 & (DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH)) 1778 != 0) 1779 return (ISC_TRUE); 1780 return (ISC_FALSE); 1781} 1782 1783isc_boolean_t 1784dns_rdatatype_isknown(dns_rdatatype_t type) { 1785 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_UNKNOWN) 1786 == 0) 1787 return (ISC_TRUE); 1788 return (ISC_FALSE); 1789} 1790 1791void 1792dns_rdata_exists(dns_rdata_t *rdata, dns_rdatatype_t type) { 1793 1794 REQUIRE(rdata != NULL); 1795 REQUIRE(DNS_RDATA_INITIALIZED(rdata)); 1796 1797 rdata->data = NULL; 1798 rdata->length = 0; 1799 rdata->flags = DNS_RDATA_UPDATE; 1800 rdata->type = type; 1801 rdata->rdclass = dns_rdataclass_any; 1802} 1803 1804void 1805dns_rdata_notexist(dns_rdata_t *rdata, dns_rdatatype_t type) { 1806 1807 REQUIRE(rdata != NULL); 1808 REQUIRE(DNS_RDATA_INITIALIZED(rdata)); 1809 1810 rdata->data = NULL; 1811 rdata->length = 0; 1812 rdata->flags = DNS_RDATA_UPDATE; 1813 rdata->type = type; 1814 rdata->rdclass = dns_rdataclass_none; 1815} 1816 1817void 1818dns_rdata_deleterrset(dns_rdata_t *rdata, dns_rdatatype_t type) { 1819 1820 REQUIRE(rdata != NULL); 1821 REQUIRE(DNS_RDATA_INITIALIZED(rdata)); 1822 1823 rdata->data = NULL; 1824 rdata->length = 0; 1825 rdata->flags = DNS_RDATA_UPDATE; 1826 rdata->type = type; 1827 rdata->rdclass = dns_rdataclass_any; 1828} 1829 1830void 1831dns_rdata_makedelete(dns_rdata_t *rdata) { 1832 REQUIRE(rdata != NULL); 1833 1834 rdata->rdclass = dns_rdataclass_none; 1835} 1836 1837const char * 1838dns_rdata_updateop(dns_rdata_t *rdata, dns_section_t section) { 1839 1840 REQUIRE(rdata != NULL); 1841 REQUIRE(DNS_RDATA_INITIALIZED(rdata)); 1842 1843 switch (section) { 1844 case DNS_SECTION_PREREQUISITE: 1845 switch (rdata->rdclass) { 1846 case dns_rdataclass_none: 1847 switch (rdata->type) { 1848 case dns_rdatatype_any: 1849 return ("domain doesn't exist"); 1850 default: 1851 return ("rrset doesn't exist"); 1852 } 1853 case dns_rdataclass_any: 1854 switch (rdata->type) { 1855 case dns_rdatatype_any: 1856 return ("domain exists"); 1857 default: 1858 return ("rrset exists (value independent)"); 1859 } 1860 default: 1861 return ("rrset exists (value dependent)"); 1862 } 1863 case DNS_SECTION_UPDATE: 1864 switch (rdata->rdclass) { 1865 case dns_rdataclass_none: 1866 return ("delete"); 1867 case dns_rdataclass_any: 1868 switch (rdata->type) { 1869 case dns_rdatatype_any: 1870 return ("delete all rrsets"); 1871 default: 1872 return ("delete rrset"); 1873 } 1874 default: 1875 return ("add"); 1876 } 1877 } 1878 return ("invalid"); 1879} 1880