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