1 /* $NetBSD: rdata.c,v 1.12 2015/09/03 07:33:34 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1998-2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* Id */ 21 22 /*! \file */ 23 24 #include <config.h> 25 #include <ctype.h> 26 27 #include <isc/base64.h> 28 #include <isc/hex.h> 29 #include <isc/lex.h> 30 #include <isc/mem.h> 31 #include <isc/parseint.h> 32 #include <isc/print.h> 33 #include <isc/string.h> 34 #include <isc/stdlib.h> 35 #include <isc/util.h> 36 37 #include <dns/callbacks.h> 38 #include <dns/cert.h> 39 #include <dns/compress.h> 40 #include <dns/dsdigest.h> 41 #include <dns/enumtype.h> 42 #include <dns/keyflags.h> 43 #include <dns/keyvalues.h> 44 #include <dns/message.h> 45 #include <dns/rcode.h> 46 #include <dns/rdata.h> 47 #include <dns/rdataclass.h> 48 #include <dns/rdatastruct.h> 49 #include <dns/rdatatype.h> 50 #include <dns/result.h> 51 #include <dns/secalg.h> 52 #include <dns/secproto.h> 53 #include <dns/time.h> 54 #include <dns/ttl.h> 55 56 #define RETERR(x) \ 57 do { \ 58 isc_result_t _r = (x); \ 59 if (_r != ISC_R_SUCCESS) \ 60 return (_r); \ 61 } while (/*CONSTCOND*/0) 62 63 #define RETTOK(x) \ 64 do { \ 65 isc_result_t _r = (x); \ 66 if (_r != ISC_R_SUCCESS) { \ 67 isc_lex_ungettoken(lexer, &token); \ 68 return (_r); \ 69 } \ 70 } while (/*CONSTCOND*/0) 71 72 #define DNS_AS_STR(t) ((t).value.as_textregion.base) 73 74 #define ARGS_FROMTEXT int rdclass, dns_rdatatype_t type, \ 75 isc_lex_t *lexer, dns_name_t *origin, \ 76 unsigned int options, isc_buffer_t *target, \ 77 dns_rdatacallbacks_t *callbacks 78 79 #define ARGS_TOTEXT dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, \ 80 isc_buffer_t *target 81 82 #define ARGS_FROMWIRE int rdclass, dns_rdatatype_t type, \ 83 isc_buffer_t *source, dns_decompress_t *dctx, \ 84 unsigned int options, isc_buffer_t *target 85 86 #define ARGS_TOWIRE dns_rdata_t *rdata, dns_compress_t *cctx, \ 87 isc_buffer_t *target 88 89 #define ARGS_COMPARE const dns_rdata_t *rdata1, const dns_rdata_t *rdata2 90 91 #define ARGS_FROMSTRUCT int rdclass, dns_rdatatype_t type, \ 92 void *source, isc_buffer_t *target 93 94 #define ARGS_TOSTRUCT dns_rdata_t *rdata, void *target, isc_mem_t *mctx 95 96 #define ARGS_FREESTRUCT void *source 97 98 #define ARGS_ADDLDATA dns_rdata_t *rdata, dns_additionaldatafunc_t add, \ 99 void *arg 100 101 #define ARGS_DIGEST dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg 102 103 #define ARGS_CHECKOWNER dns_name_t *name, dns_rdataclass_t rdclass, \ 104 dns_rdatatype_t type, isc_boolean_t wildcard 105 106 #define ARGS_CHECKNAMES dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad 107 108 109 /*% 110 * Context structure for the totext_ functions. 111 * Contains formatting options for rdata-to-text 112 * conversion. 113 */ 114 typedef struct dns_rdata_textctx { 115 dns_name_t *origin; /*%< Current origin, or NULL. */ 116 unsigned int flags; /*%< DNS_STYLEFLAG_* */ 117 unsigned int width; /*%< Width of rdata column. */ 118 const char *linebreak; /*%< Line break string. */ 119 } dns_rdata_textctx_t; 120 121 static isc_result_t 122 txt_totext(isc_region_t *source, isc_boolean_t quote, isc_buffer_t *target); 123 124 static isc_result_t 125 txt_fromtext(isc_textregion_t *source, isc_buffer_t *target); 126 127 static isc_result_t 128 txt_fromwire(isc_buffer_t *source, isc_buffer_t *target); 129 130 static isc_result_t 131 multitxt_totext(isc_region_t *source, isc_buffer_t *target); 132 133 static isc_result_t 134 multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target); 135 136 static isc_boolean_t 137 name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target); 138 139 static unsigned int 140 name_length(dns_name_t *name); 141 142 static isc_result_t 143 str_totext(const char *source, isc_buffer_t *target); 144 145 static isc_result_t 146 inet_totext(int af, isc_region_t *src, isc_buffer_t *target); 147 148 static isc_boolean_t 149 buffer_empty(isc_buffer_t *source); 150 151 static void 152 buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region); 153 154 static isc_result_t 155 uint32_tobuffer(isc_uint32_t, isc_buffer_t *target); 156 157 static isc_result_t 158 uint16_tobuffer(isc_uint32_t, isc_buffer_t *target); 159 160 static isc_result_t 161 uint8_tobuffer(isc_uint32_t, isc_buffer_t *target); 162 163 static isc_result_t 164 name_tobuffer(dns_name_t *name, isc_buffer_t *target); 165 166 static isc_uint32_t 167 uint32_fromregion(isc_region_t *region); 168 169 static isc_uint16_t 170 uint16_fromregion(isc_region_t *region); 171 172 static isc_uint8_t 173 uint8_fromregion(isc_region_t *region); 174 175 static isc_uint8_t 176 uint8_consume_fromregion(isc_region_t *region); 177 178 static isc_result_t 179 mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length); 180 181 static int 182 hexvalue(char value); 183 184 static int 185 decvalue(char value); 186 187 static isc_result_t 188 btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target); 189 190 static isc_result_t 191 atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target); 192 193 static void 194 default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *, ...) 195 ISC_FORMAT_PRINTF(2, 3); 196 197 static void 198 fromtext_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 202 static void 203 fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks); 204 205 static isc_result_t 206 rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, 207 isc_buffer_t *target); 208 209 static void 210 warn_badname(dns_name_t *name, isc_lex_t *lexer, 211 dns_rdatacallbacks_t *callbacks); 212 213 static void 214 warn_badmx(isc_token_t *token, isc_lex_t *lexer, 215 dns_rdatacallbacks_t *callbacks); 216 217 static isc_uint16_t 218 uint16_consume_fromregion(isc_region_t *region); 219 220 static isc_result_t 221 unknown_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 */ 236 static inline int 237 locator_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 288 static inline int 289 getquad(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 308 static inline isc_result_t 309 name_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 317 static inline void * 318 mem_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 330 static const char hexdigits[] = "0123456789abcdef"; 331 static const char decdigits[] = "0123456789"; 332 333 #include "code.h" 334 335 #define META 0x0001 336 #define RESERVED 0x0002 337 338 /*** 339 *** Initialization 340 ***/ 341 342 void 343 dns_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 356 void 357 dns_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 375 void 376 dns_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 398 int 399 dns_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 429 int 430 dns_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 464 void 465 dns_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 482 void 483 dns_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 493 isc_result_t 494 dns_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 564 isc_result_t 565 dns_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 */ 609 static isc_result_t 610 rdata_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 624 static isc_result_t 625 unknown_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 670 isc_result_t 671 dns_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 794 static isc_result_t 795 unknown_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 836 static isc_result_t 837 rdata_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 863 isc_result_t 864 dns_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 880 isc_result_t 881 dns_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 910 isc_result_t 911 dns_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 948 isc_result_t 949 dns_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 964 void 965 dns_rdata_freestruct(void *source) { 966 dns_rdatacommon_t *common = source; 967 REQUIRE(source != NULL); 968 969 FREESTRUCTSWITCH 970 } 971 972 isc_result_t 973 dns_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 997 isc_result_t 998 dns_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 1021 isc_boolean_t 1022 dns_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 1031 isc_boolean_t 1032 dns_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 1040 unsigned int 1041 dns_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 1049 isc_result_t 1050 dns_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 1090 isc_result_t 1091 dns_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 1099 void 1100 dns_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 1128 static unsigned int 1129 name_length(dns_name_t *name) { 1130 return (name->length); 1131 } 1132 1133 static isc_result_t 1134 txt_totext(isc_region_t *source, isc_boolean_t quote, 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 if (n == 0U) 1150 REQUIRE(quote == ISC_TRUE); 1151 1152 if (quote) { 1153 if (tl < 1) 1154 return (ISC_R_NOSPACE); 1155 *tp++ = '"'; 1156 tl--; 1157 } 1158 while (n--) { 1159 /* 1160 * \DDD space (0x20) if not quoting. 1161 */ 1162 if (*sp < (quote ? 0x20 : 0x21) || *sp >= 0x7f) { 1163 if (tl < 4) 1164 return (ISC_R_NOSPACE); 1165 *tp++ = 0x5c; 1166 *tp++ = 0x30 + ((*sp / 100) % 10); 1167 *tp++ = 0x30 + ((*sp / 10) % 10); 1168 *tp++ = 0x30 + (*sp % 10); 1169 sp++; 1170 tl -= 4; 1171 continue; 1172 } 1173 /* 1174 * Escape double quote and backslash. If we are not 1175 * enclosing the string in double quotes also escape 1176 * at sign and semicolon. 1177 */ 1178 if (*sp == 0x22 || *sp == 0x5c || 1179 (!quote && (*sp == 0x40 || *sp == 0x3b))) { 1180 if (tl < 2) 1181 return (ISC_R_NOSPACE); 1182 *tp++ = '\\'; 1183 tl--; 1184 } 1185 if (tl < 1) 1186 return (ISC_R_NOSPACE); 1187 *tp++ = *sp++; 1188 tl--; 1189 } 1190 if (quote) { 1191 if (tl < 1) 1192 return (ISC_R_NOSPACE); 1193 *tp++ = '"'; 1194 tl--; 1195 } 1196 isc_buffer_add(target, (unsigned int)(tp - (char *)region.base)); 1197 isc_region_consume(source, *source->base + 1); 1198 return (ISC_R_SUCCESS); 1199 } 1200 1201 static isc_result_t 1202 txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) { 1203 isc_region_t tregion; 1204 isc_boolean_t escape; 1205 unsigned int n, nrem; 1206 char *s; 1207 unsigned char *t; 1208 int d; 1209 int c; 1210 1211 isc_buffer_availableregion(target, &tregion); 1212 s = source->base; 1213 n = source->length; 1214 t = tregion.base; 1215 nrem = tregion.length; 1216 escape = ISC_FALSE; 1217 if (nrem < 1) 1218 return (ISC_R_NOSPACE); 1219 /* 1220 * Length byte. 1221 */ 1222 nrem--; 1223 t++; 1224 /* 1225 * Maximum text string length. 1226 */ 1227 if (nrem > 255) 1228 nrem = 255; 1229 while (n-- != 0) { 1230 c = (*s++) & 0xff; 1231 if (escape && (d = decvalue((char)c)) != -1) { 1232 c = d; 1233 if (n == 0) 1234 return (DNS_R_SYNTAX); 1235 n--; 1236 if ((d = decvalue(*s++)) != -1) 1237 c = c * 10 + d; 1238 else 1239 return (DNS_R_SYNTAX); 1240 if (n == 0) 1241 return (DNS_R_SYNTAX); 1242 n--; 1243 if ((d = decvalue(*s++)) != -1) 1244 c = c * 10 + d; 1245 else 1246 return (DNS_R_SYNTAX); 1247 if (c > 255) 1248 return (DNS_R_SYNTAX); 1249 } else if (!escape && c == '\\') { 1250 escape = ISC_TRUE; 1251 continue; 1252 } 1253 escape = ISC_FALSE; 1254 if (nrem == 0) 1255 return ((tregion.length <= 256U) ? 1256 ISC_R_NOSPACE : DNS_R_SYNTAX); 1257 *t++ = c; 1258 nrem--; 1259 } 1260 if (escape) 1261 return (DNS_R_SYNTAX); 1262 *tregion.base = (unsigned char)(t - tregion.base - 1); 1263 isc_buffer_add(target, *tregion.base + 1); 1264 return (ISC_R_SUCCESS); 1265 } 1266 1267 static isc_result_t 1268 txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { 1269 unsigned int n; 1270 isc_region_t sregion; 1271 isc_region_t tregion; 1272 1273 isc_buffer_activeregion(source, &sregion); 1274 if (sregion.length == 0) 1275 return (ISC_R_UNEXPECTEDEND); 1276 n = *sregion.base + 1; 1277 if (n > sregion.length) 1278 return (ISC_R_UNEXPECTEDEND); 1279 1280 isc_buffer_availableregion(target, &tregion); 1281 if (n > tregion.length) 1282 return (ISC_R_NOSPACE); 1283 1284 if (tregion.base != sregion.base) 1285 memmove(tregion.base, sregion.base, n); 1286 isc_buffer_forward(source, n); 1287 isc_buffer_add(target, n); 1288 return (ISC_R_SUCCESS); 1289 } 1290 1291 /* 1292 * Conversion of TXT-like rdata fields without length limits. 1293 */ 1294 static isc_result_t 1295 multitxt_totext(isc_region_t *source, isc_buffer_t *target) { 1296 unsigned int tl; 1297 unsigned int n0, n; 1298 unsigned char *sp; 1299 char *tp; 1300 isc_region_t region; 1301 1302 isc_buffer_availableregion(target, ®ion); 1303 sp = source->base; 1304 tp = (char *)region.base; 1305 tl = region.length; 1306 1307 if (tl < 1) 1308 return (ISC_R_NOSPACE); 1309 *tp++ = '"'; 1310 tl--; 1311 do { 1312 n = source->length; 1313 n0 = source->length - 1; 1314 1315 while (n--) { 1316 if (*sp < 0x20 || *sp >= 0x7f) { 1317 if (tl < 4) 1318 return (ISC_R_NOSPACE); 1319 *tp++ = 0x5c; 1320 *tp++ = 0x30 + ((*sp / 100) % 10); 1321 *tp++ = 0x30 + ((*sp / 10) % 10); 1322 *tp++ = 0x30 + (*sp % 10); 1323 sp++; 1324 tl -= 4; 1325 continue; 1326 } 1327 /* double quote, semi-colon, backslash */ 1328 if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) { 1329 if (tl < 2) 1330 return (ISC_R_NOSPACE); 1331 *tp++ = '\\'; 1332 tl--; 1333 } 1334 if (tl < 1) 1335 return (ISC_R_NOSPACE); 1336 *tp++ = *sp++; 1337 tl--; 1338 } 1339 isc_region_consume(source, n0 + 1); 1340 } while (source->length != 0); 1341 if (tl < 1) 1342 return (ISC_R_NOSPACE); 1343 *tp++ = '"'; 1344 tl--; 1345 isc_buffer_add(target, (unsigned int)(tp - (char *)region.base)); 1346 return (ISC_R_SUCCESS); 1347 } 1348 1349 static isc_result_t 1350 multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target) { 1351 isc_region_t tregion; 1352 isc_boolean_t escape; 1353 unsigned int n, nrem; 1354 char *s; 1355 unsigned char *t0, *t; 1356 int d; 1357 int c; 1358 1359 s = source->base; 1360 n = source->length; 1361 escape = ISC_FALSE; 1362 1363 do { 1364 isc_buffer_availableregion(target, &tregion); 1365 t0 = t = tregion.base; 1366 nrem = tregion.length; 1367 if (nrem < 1) 1368 return (ISC_R_NOSPACE); 1369 1370 while (n != 0) { 1371 --n; 1372 c = (*s++) & 0xff; 1373 if (escape && (d = decvalue((char)c)) != -1) { 1374 c = d; 1375 if (n == 0) 1376 return (DNS_R_SYNTAX); 1377 n--; 1378 if ((d = decvalue(*s++)) != -1) 1379 c = c * 10 + d; 1380 else 1381 return (DNS_R_SYNTAX); 1382 if (n == 0) 1383 return (DNS_R_SYNTAX); 1384 n--; 1385 if ((d = decvalue(*s++)) != -1) 1386 c = c * 10 + d; 1387 else 1388 return (DNS_R_SYNTAX); 1389 if (c > 255) 1390 return (DNS_R_SYNTAX); 1391 } else if (!escape && c == '\\') { 1392 escape = ISC_TRUE; 1393 continue; 1394 } 1395 escape = ISC_FALSE; 1396 *t++ = c; 1397 nrem--; 1398 if (nrem == 0) 1399 break; 1400 } 1401 if (escape) 1402 return (DNS_R_SYNTAX); 1403 1404 isc_buffer_add(target, t - t0); 1405 } while (n != 0); 1406 return (ISC_R_SUCCESS); 1407 } 1408 1409 static isc_boolean_t 1410 name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) { 1411 int l1, l2; 1412 1413 if (origin == NULL) 1414 goto return_false; 1415 1416 if (dns_name_compare(origin, dns_rootname) == 0) 1417 goto return_false; 1418 1419 if (!dns_name_issubdomain(name, origin)) 1420 goto return_false; 1421 1422 l1 = dns_name_countlabels(name); 1423 l2 = dns_name_countlabels(origin); 1424 1425 if (l1 == l2) 1426 goto return_false; 1427 1428 /* Master files should be case preserving. */ 1429 dns_name_getlabelsequence(name, l1 - l2, l2, target); 1430 if (!dns_name_caseequal(origin, target)) 1431 goto return_false; 1432 1433 dns_name_getlabelsequence(name, 0, l1 - l2, target); 1434 return (ISC_TRUE); 1435 1436 return_false: 1437 *target = *name; 1438 return (ISC_FALSE); 1439 } 1440 1441 static isc_result_t 1442 str_totext(const char *source, isc_buffer_t *target) { 1443 unsigned int l; 1444 isc_region_t region; 1445 1446 isc_buffer_availableregion(target, ®ion); 1447 l = strlen(source); 1448 1449 if (l > region.length) 1450 return (ISC_R_NOSPACE); 1451 1452 memmove(region.base, source, l); 1453 isc_buffer_add(target, l); 1454 return (ISC_R_SUCCESS); 1455 } 1456 1457 static isc_result_t 1458 inet_totext(int af, isc_region_t *src, isc_buffer_t *target) { 1459 char tmpbuf[64]; 1460 1461 /* Note - inet_ntop doesn't do size checking on its input. */ 1462 if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL) 1463 return (ISC_R_NOSPACE); 1464 if (strlen(tmpbuf) > isc_buffer_availablelength(target)) 1465 return (ISC_R_NOSPACE); 1466 isc_buffer_putstr(target, tmpbuf); 1467 return (ISC_R_SUCCESS); 1468 } 1469 1470 static isc_boolean_t 1471 buffer_empty(isc_buffer_t *source) { 1472 return((source->current == source->active) ? ISC_TRUE : ISC_FALSE); 1473 } 1474 1475 static void 1476 buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region) { 1477 isc_buffer_init(buffer, region->base, region->length); 1478 isc_buffer_add(buffer, region->length); 1479 isc_buffer_setactive(buffer, region->length); 1480 } 1481 1482 static isc_result_t 1483 uint32_tobuffer(isc_uint32_t value, isc_buffer_t *target) { 1484 isc_region_t region; 1485 1486 isc_buffer_availableregion(target, ®ion); 1487 if (region.length < 4) 1488 return (ISC_R_NOSPACE); 1489 isc_buffer_putuint32(target, value); 1490 return (ISC_R_SUCCESS); 1491 } 1492 1493 static isc_result_t 1494 uint16_tobuffer(isc_uint32_t value, isc_buffer_t *target) { 1495 isc_region_t region; 1496 1497 if (value > 0xffff) 1498 return (ISC_R_RANGE); 1499 isc_buffer_availableregion(target, ®ion); 1500 if (region.length < 2) 1501 return (ISC_R_NOSPACE); 1502 isc_buffer_putuint16(target, (isc_uint16_t)value); 1503 return (ISC_R_SUCCESS); 1504 } 1505 1506 static isc_result_t 1507 uint8_tobuffer(isc_uint32_t value, isc_buffer_t *target) { 1508 isc_region_t region; 1509 1510 if (value > 0xff) 1511 return (ISC_R_RANGE); 1512 isc_buffer_availableregion(target, ®ion); 1513 if (region.length < 1) 1514 return (ISC_R_NOSPACE); 1515 isc_buffer_putuint8(target, (isc_uint8_t)value); 1516 return (ISC_R_SUCCESS); 1517 } 1518 1519 static isc_result_t 1520 name_tobuffer(dns_name_t *name, isc_buffer_t *target) { 1521 isc_region_t r; 1522 dns_name_toregion(name, &r); 1523 return (isc_buffer_copyregion(target, &r)); 1524 } 1525 1526 static isc_uint32_t 1527 uint32_fromregion(isc_region_t *region) { 1528 isc_uint32_t value; 1529 1530 REQUIRE(region->length >= 4); 1531 value = region->base[0] << 24; 1532 value |= region->base[1] << 16; 1533 value |= region->base[2] << 8; 1534 value |= region->base[3]; 1535 return(value); 1536 } 1537 1538 static isc_uint16_t 1539 uint16_consume_fromregion(isc_region_t *region) { 1540 isc_uint16_t r = uint16_fromregion(region); 1541 1542 isc_region_consume(region, 2); 1543 return r; 1544 } 1545 1546 static isc_uint16_t 1547 uint16_fromregion(isc_region_t *region) { 1548 1549 REQUIRE(region->length >= 2); 1550 1551 return ((region->base[0] << 8) | region->base[1]); 1552 } 1553 1554 static isc_uint8_t 1555 uint8_fromregion(isc_region_t *region) { 1556 1557 REQUIRE(region->length >= 1); 1558 1559 return (region->base[0]); 1560 } 1561 1562 static isc_uint8_t 1563 uint8_consume_fromregion(isc_region_t *region) { 1564 isc_uint8_t r = uint8_fromregion(region); 1565 1566 isc_region_consume(region, 1); 1567 return r; 1568 } 1569 1570 static isc_result_t 1571 mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) { 1572 isc_region_t tr; 1573 1574 isc_buffer_availableregion(target, &tr); 1575 if (length > tr.length) 1576 return (ISC_R_NOSPACE); 1577 if (tr.base != base) 1578 memmove(tr.base, base, length); 1579 isc_buffer_add(target, length); 1580 return (ISC_R_SUCCESS); 1581 } 1582 1583 static int 1584 hexvalue(char value) { 1585 char *s; 1586 unsigned char c; 1587 1588 c = (unsigned char)value; 1589 1590 if (!isascii(c)) 1591 return (-1); 1592 if (isupper(c)) 1593 c = tolower(c); 1594 if ((s = strchr(hexdigits, c)) == NULL) 1595 return (-1); 1596 return (int)(s - hexdigits); 1597 } 1598 1599 static int 1600 decvalue(char value) { 1601 char *s; 1602 1603 /* 1604 * isascii() is valid for full range of int values, no need to 1605 * mask or cast. 1606 */ 1607 if (!isascii(value)) 1608 return (-1); 1609 if ((s = strchr(decdigits, value)) == NULL) 1610 return (-1); 1611 return (int)(s - decdigits); 1612 } 1613 1614 static const char atob_digits[86] = 1615 "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \ 1616 "abcdefghijklmnopqrstu"; 1617 /* 1618 * Subroutines to convert between 8 bit binary bytes and printable ASCII. 1619 * Computes the number of bytes, and three kinds of simple checksums. 1620 * Incoming bytes are collected into 32-bit words, then printed in base 85: 1621 * exp(85,5) > exp(2,32) 1622 * The ASCII characters used are between '!' and 'u'; 1623 * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data. 1624 * 1625 * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for 1626 * the atob/btoa programs, released with the compress program, in mod.sources. 1627 * Modified by Mike Schwartz 8/19/86 for use in BIND. 1628 * Modified to be re-entrant 3/2/99. 1629 */ 1630 1631 1632 struct state { 1633 isc_int32_t Ceor; 1634 isc_int32_t Csum; 1635 isc_int32_t Crot; 1636 isc_int32_t word; 1637 isc_int32_t bcount; 1638 }; 1639 1640 #define Ceor state->Ceor 1641 #define Csum state->Csum 1642 #define Crot state->Crot 1643 #define word state->word 1644 #define bcount state->bcount 1645 1646 #define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x) 1647 1648 static isc_result_t byte_atob(int c, isc_buffer_t *target, 1649 struct state *state); 1650 static isc_result_t putbyte(int c, isc_buffer_t *, struct state *state); 1651 static isc_result_t byte_btoa(int c, isc_buffer_t *, struct state *state); 1652 1653 /* 1654 * Decode ASCII-encoded byte c into binary representation and 1655 * place into *bufp, advancing bufp. 1656 */ 1657 static isc_result_t 1658 byte_atob(int c, isc_buffer_t *target, struct state *state) { 1659 char *s; 1660 if (c == 'z') { 1661 if (bcount != 0) 1662 return(DNS_R_SYNTAX); 1663 else { 1664 RETERR(putbyte(0, target, state)); 1665 RETERR(putbyte(0, target, state)); 1666 RETERR(putbyte(0, target, state)); 1667 RETERR(putbyte(0, target, state)); 1668 } 1669 } else if ((s = strchr(atob_digits, c)) != NULL) { 1670 if (bcount == 0) { 1671 word = (isc_int32_t)(s - atob_digits); 1672 ++bcount; 1673 } else if (bcount < 4) { 1674 word = times85(word); 1675 word += (isc_int32_t)(s - atob_digits); 1676 ++bcount; 1677 } else { 1678 word = times85(word); 1679 word += (isc_int32_t)(s - atob_digits); 1680 RETERR(putbyte((word >> 24) & 0xff, target, state)); 1681 RETERR(putbyte((word >> 16) & 0xff, target, state)); 1682 RETERR(putbyte((word >> 8) & 0xff, target, state)); 1683 RETERR(putbyte(word & 0xff, target, state)); 1684 word = 0; 1685 bcount = 0; 1686 } 1687 } else 1688 return(DNS_R_SYNTAX); 1689 return(ISC_R_SUCCESS); 1690 } 1691 1692 /* 1693 * Compute checksum info and place c into target. 1694 */ 1695 static isc_result_t 1696 putbyte(int c, isc_buffer_t *target, struct state *state) { 1697 isc_region_t tr; 1698 1699 Ceor ^= c; 1700 Csum += c; 1701 Csum += 1; 1702 if ((Crot & 0x80000000)) { 1703 Crot <<= 1; 1704 Crot += 1; 1705 } else { 1706 Crot <<= 1; 1707 } 1708 Crot += c; 1709 isc_buffer_availableregion(target, &tr); 1710 if (tr.length < 1) 1711 return (ISC_R_NOSPACE); 1712 tr.base[0] = c; 1713 isc_buffer_add(target, 1); 1714 return (ISC_R_SUCCESS); 1715 } 1716 1717 /* 1718 * Read the ASCII-encoded data from inbuf, of length inbuflen, and convert 1719 * it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes; 1720 * outbuflen must be divisible by 4. (Note: this is because outbuf is filled 1721 * in 4 bytes at a time. If the actual data doesn't end on an even 4-byte 1722 * boundary, there will be no problem...it will be padded with 0 bytes, and 1723 * numbytes will indicate the correct number of bytes. The main point is 1724 * that since the buffer is filled in 4 bytes at a time, even if there is 1725 * not a full 4 bytes of data at the end, there has to be room to 0-pad the 1726 * data, so the buffer must be of size divisible by 4). Place the number of 1727 * output bytes in numbytes, and return a failure/success status. 1728 */ 1729 1730 static isc_result_t 1731 atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target) { 1732 long oeor, osum, orot; 1733 struct state statebuf, *state= &statebuf; 1734 isc_token_t token; 1735 char c; 1736 char *e; 1737 1738 Ceor = Csum = Crot = word = bcount = 0; 1739 1740 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 1741 ISC_FALSE)); 1742 while (token.value.as_textregion.length != 0) { 1743 if ((c = token.value.as_textregion.base[0]) == 'x') { 1744 break; 1745 } else 1746 RETERR(byte_atob(c, target, state)); 1747 isc_textregion_consume(&token.value.as_textregion, 1); 1748 } 1749 1750 /* 1751 * Number of bytes. 1752 */ 1753 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 1754 ISC_FALSE)); 1755 if ((token.value.as_ulong % 4) != 0U) 1756 isc_buffer_subtract(target, 4 - (token.value.as_ulong % 4)); 1757 1758 /* 1759 * Checksum. 1760 */ 1761 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 1762 ISC_FALSE)); 1763 oeor = strtol(DNS_AS_STR(token), &e, 16); 1764 if (*e != 0) 1765 return (DNS_R_SYNTAX); 1766 1767 /* 1768 * Checksum. 1769 */ 1770 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 1771 ISC_FALSE)); 1772 osum = strtol(DNS_AS_STR(token), &e, 16); 1773 if (*e != 0) 1774 return (DNS_R_SYNTAX); 1775 1776 /* 1777 * Checksum. 1778 */ 1779 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 1780 ISC_FALSE)); 1781 orot = strtol(DNS_AS_STR(token), &e, 16); 1782 if (*e != 0) 1783 return (DNS_R_SYNTAX); 1784 1785 if ((oeor != Ceor) || (osum != Csum) || (orot != Crot)) 1786 return(DNS_R_BADCKSUM); 1787 return (ISC_R_SUCCESS); 1788 } 1789 1790 /* 1791 * Encode binary byte c into ASCII representation and place into *bufp, 1792 * advancing bufp. 1793 */ 1794 static isc_result_t 1795 byte_btoa(int c, isc_buffer_t *target, struct state *state) { 1796 isc_region_t tr; 1797 1798 isc_buffer_availableregion(target, &tr); 1799 Ceor ^= c; 1800 Csum += c; 1801 Csum += 1; 1802 if ((Crot & 0x80000000)) { 1803 Crot <<= 1; 1804 Crot += 1; 1805 } else { 1806 Crot <<= 1; 1807 } 1808 Crot += c; 1809 1810 word <<= 8; 1811 word |= c; 1812 if (bcount == 3) { 1813 if (word == 0) { 1814 if (tr.length < 1) 1815 return (ISC_R_NOSPACE); 1816 tr.base[0] = 'z'; 1817 isc_buffer_add(target, 1); 1818 } else { 1819 register int tmp = 0; 1820 register isc_int32_t tmpword = word; 1821 1822 if (tmpword < 0) { 1823 /* 1824 * Because some don't support u_long. 1825 */ 1826 tmp = 32; 1827 tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32); 1828 } 1829 if (tmpword < 0) { 1830 tmp = 64; 1831 tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32); 1832 } 1833 if (tr.length < 5) 1834 return (ISC_R_NOSPACE); 1835 tr.base[0] = atob_digits[(tmpword / 1836 (isc_int32_t)(85 * 85 * 85 * 85)) 1837 + tmp]; 1838 tmpword %= (isc_int32_t)(85 * 85 * 85 * 85); 1839 tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)]; 1840 tmpword %= (85 * 85 * 85); 1841 tr.base[2] = atob_digits[tmpword / (85 * 85)]; 1842 tmpword %= (85 * 85); 1843 tr.base[3] = atob_digits[tmpword / 85]; 1844 tmpword %= 85; 1845 tr.base[4] = atob_digits[tmpword]; 1846 isc_buffer_add(target, 5); 1847 } 1848 bcount = 0; 1849 } else { 1850 bcount += 1; 1851 } 1852 return (ISC_R_SUCCESS); 1853 } 1854 1855 1856 /* 1857 * Encode the binary data from inbuf, of length inbuflen, into a 1858 * target. Return success/failure status 1859 */ 1860 static isc_result_t 1861 btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) { 1862 int inc; 1863 struct state statebuf, *state = &statebuf; 1864 char buf[sizeof("x 2000000000 ffffffff ffffffff ffffffff")]; 1865 1866 Ceor = Csum = Crot = word = bcount = 0; 1867 for (inc = 0; inc < inbuflen; inbuf++, inc++) 1868 RETERR(byte_btoa(*inbuf, target, state)); 1869 1870 while (bcount != 0) 1871 RETERR(byte_btoa(0, target, state)); 1872 1873 /* 1874 * Put byte count and checksum information at end of buffer, 1875 * delimited by 'x' 1876 */ 1877 snprintf(buf, sizeof(buf), "x %d %x %x %x", inbuflen, Ceor, Csum, Crot); 1878 return (str_totext(buf, target)); 1879 } 1880 1881 1882 static void 1883 default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *fmt, 1884 ...) 1885 { 1886 va_list ap; 1887 1888 UNUSED(callbacks); 1889 1890 va_start(ap, fmt); 1891 vfprintf(stderr, fmt, ap); 1892 va_end(ap); 1893 fprintf(stderr, "\n"); 1894 } 1895 1896 static void 1897 fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) { 1898 if (isc_lex_isfile(lexer) && callbacks != NULL) { 1899 const char *name = isc_lex_getsourcename(lexer); 1900 if (name == NULL) 1901 name = "UNKNOWN"; 1902 (*callbacks->warn)(callbacks, 1903 "%s:%lu: file does not end with newline", 1904 name, isc_lex_getsourceline(lexer)); 1905 } 1906 } 1907 1908 static void 1909 warn_badmx(isc_token_t *token, isc_lex_t *lexer, 1910 dns_rdatacallbacks_t *callbacks) 1911 { 1912 const char *file; 1913 unsigned long line; 1914 1915 if (lexer != NULL) { 1916 file = isc_lex_getsourcename(lexer); 1917 line = isc_lex_getsourceline(lexer); 1918 (*callbacks->warn)(callbacks, "%s:%u: warning: '%s': %s", 1919 file, line, DNS_AS_STR(*token), 1920 dns_result_totext(DNS_R_MXISADDRESS)); 1921 } 1922 } 1923 1924 static void 1925 warn_badname(dns_name_t *name, isc_lex_t *lexer, 1926 dns_rdatacallbacks_t *callbacks) 1927 { 1928 const char *file; 1929 unsigned long line; 1930 char namebuf[DNS_NAME_FORMATSIZE]; 1931 1932 if (lexer != NULL) { 1933 file = isc_lex_getsourcename(lexer); 1934 line = isc_lex_getsourceline(lexer); 1935 dns_name_format(name, namebuf, sizeof(namebuf)); 1936 (*callbacks->warn)(callbacks, "%s:%u: warning: %s: %s", 1937 file, line, namebuf, 1938 dns_result_totext(DNS_R_BADNAME)); 1939 } 1940 } 1941 1942 static void 1943 fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...), 1944 dns_rdatacallbacks_t *callbacks, const char *name, 1945 unsigned long line, isc_token_t *token, isc_result_t result) 1946 { 1947 if (name == NULL) 1948 name = "UNKNOWN"; 1949 1950 if (token != NULL) { 1951 switch (token->type) { 1952 case isc_tokentype_eol: 1953 (*callback)(callbacks, "%s: %s:%lu: near eol: %s", 1954 "dns_rdata_fromtext", name, line, 1955 dns_result_totext(result)); 1956 break; 1957 case isc_tokentype_eof: 1958 (*callback)(callbacks, "%s: %s:%lu: near eof: %s", 1959 "dns_rdata_fromtext", name, line, 1960 dns_result_totext(result)); 1961 break; 1962 case isc_tokentype_number: 1963 (*callback)(callbacks, "%s: %s:%lu: near %lu: %s", 1964 "dns_rdata_fromtext", name, line, 1965 token->value.as_ulong, 1966 dns_result_totext(result)); 1967 break; 1968 case isc_tokentype_string: 1969 case isc_tokentype_qstring: 1970 (*callback)(callbacks, "%s: %s:%lu: near '%s': %s", 1971 "dns_rdata_fromtext", name, line, 1972 DNS_AS_STR(*token), 1973 dns_result_totext(result)); 1974 break; 1975 default: 1976 (*callback)(callbacks, "%s: %s:%lu: %s", 1977 "dns_rdata_fromtext", name, line, 1978 dns_result_totext(result)); 1979 break; 1980 } 1981 } else { 1982 (*callback)(callbacks, "dns_rdata_fromtext: %s:%lu: %s", 1983 name, line, dns_result_totext(result)); 1984 } 1985 } 1986 1987 dns_rdatatype_t 1988 dns_rdata_covers(dns_rdata_t *rdata) { 1989 if (rdata->type == 46) 1990 return (covers_rrsig(rdata)); 1991 return (covers_sig(rdata)); 1992 } 1993 1994 isc_boolean_t 1995 dns_rdatatype_ismeta(dns_rdatatype_t type) { 1996 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_META) != 0) 1997 return (ISC_TRUE); 1998 return (ISC_FALSE); 1999 } 2000 2001 isc_boolean_t 2002 dns_rdatatype_issingleton(dns_rdatatype_t type) { 2003 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_SINGLETON) 2004 != 0) 2005 return (ISC_TRUE); 2006 return (ISC_FALSE); 2007 } 2008 2009 isc_boolean_t 2010 dns_rdatatype_notquestion(dns_rdatatype_t type) { 2011 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_NOTQUESTION) 2012 != 0) 2013 return (ISC_TRUE); 2014 return (ISC_FALSE); 2015 } 2016 2017 isc_boolean_t 2018 dns_rdatatype_questiononly(dns_rdatatype_t type) { 2019 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_QUESTIONONLY) 2020 != 0) 2021 return (ISC_TRUE); 2022 return (ISC_FALSE); 2023 } 2024 2025 isc_boolean_t 2026 dns_rdatatype_atparent(dns_rdatatype_t type) { 2027 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_ATPARENT) != 0) 2028 return (ISC_TRUE); 2029 return (ISC_FALSE); 2030 } 2031 2032 isc_boolean_t 2033 dns_rdataclass_ismeta(dns_rdataclass_t rdclass) { 2034 2035 if (rdclass == dns_rdataclass_reserved0 2036 || rdclass == dns_rdataclass_none 2037 || rdclass == dns_rdataclass_any) 2038 return (ISC_TRUE); 2039 2040 return (ISC_FALSE); /* Assume it is not a meta class. */ 2041 } 2042 2043 isc_boolean_t 2044 dns_rdatatype_isdnssec(dns_rdatatype_t type) { 2045 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_DNSSEC) != 0) 2046 return (ISC_TRUE); 2047 return (ISC_FALSE); 2048 } 2049 2050 isc_boolean_t 2051 dns_rdatatype_iszonecutauth(dns_rdatatype_t type) { 2052 if ((dns_rdatatype_attributes(type) 2053 & (DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH)) 2054 != 0) 2055 return (ISC_TRUE); 2056 return (ISC_FALSE); 2057 } 2058 2059 isc_boolean_t 2060 dns_rdatatype_isknown(dns_rdatatype_t type) { 2061 if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_UNKNOWN) 2062 == 0) 2063 return (ISC_TRUE); 2064 return (ISC_FALSE); 2065 } 2066 2067 void 2068 dns_rdata_exists(dns_rdata_t *rdata, dns_rdatatype_t type) { 2069 2070 REQUIRE(rdata != NULL); 2071 REQUIRE(DNS_RDATA_INITIALIZED(rdata)); 2072 2073 rdata->data = NULL; 2074 rdata->length = 0; 2075 rdata->flags = DNS_RDATA_UPDATE; 2076 rdata->type = type; 2077 rdata->rdclass = dns_rdataclass_any; 2078 } 2079 2080 void 2081 dns_rdata_notexist(dns_rdata_t *rdata, dns_rdatatype_t type) { 2082 2083 REQUIRE(rdata != NULL); 2084 REQUIRE(DNS_RDATA_INITIALIZED(rdata)); 2085 2086 rdata->data = NULL; 2087 rdata->length = 0; 2088 rdata->flags = DNS_RDATA_UPDATE; 2089 rdata->type = type; 2090 rdata->rdclass = dns_rdataclass_none; 2091 } 2092 2093 void 2094 dns_rdata_deleterrset(dns_rdata_t *rdata, dns_rdatatype_t type) { 2095 2096 REQUIRE(rdata != NULL); 2097 REQUIRE(DNS_RDATA_INITIALIZED(rdata)); 2098 2099 rdata->data = NULL; 2100 rdata->length = 0; 2101 rdata->flags = DNS_RDATA_UPDATE; 2102 rdata->type = type; 2103 rdata->rdclass = dns_rdataclass_any; 2104 } 2105 2106 void 2107 dns_rdata_makedelete(dns_rdata_t *rdata) { 2108 REQUIRE(rdata != NULL); 2109 2110 rdata->rdclass = dns_rdataclass_none; 2111 } 2112 2113 const char * 2114 dns_rdata_updateop(dns_rdata_t *rdata, dns_section_t section) { 2115 2116 REQUIRE(rdata != NULL); 2117 REQUIRE(DNS_RDATA_INITIALIZED(rdata)); 2118 2119 switch (section) { 2120 case DNS_SECTION_PREREQUISITE: 2121 switch (rdata->rdclass) { 2122 case dns_rdataclass_none: 2123 switch (rdata->type) { 2124 case dns_rdatatype_any: 2125 return ("domain doesn't exist"); 2126 default: 2127 return ("rrset doesn't exist"); 2128 } 2129 case dns_rdataclass_any: 2130 switch (rdata->type) { 2131 case dns_rdatatype_any: 2132 return ("domain exists"); 2133 default: 2134 return ("rrset exists (value independent)"); 2135 } 2136 default: 2137 return ("rrset exists (value dependent)"); 2138 } 2139 case DNS_SECTION_UPDATE: 2140 switch (rdata->rdclass) { 2141 case dns_rdataclass_none: 2142 return ("delete"); 2143 case dns_rdataclass_any: 2144 switch (rdata->type) { 2145 case dns_rdatatype_any: 2146 return ("delete all rrsets"); 2147 default: 2148 return ("delete rrset"); 2149 } 2150 default: 2151 return ("add"); 2152 } 2153 } 2154 return ("invalid"); 2155 } 2156