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