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