1 /* 2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 /* $Id: rdata.c,v 1.30 2020/02/26 18:49:02 florian Exp $ */ 18 19 /*! \file */ 20 21 #include <ctype.h> 22 #include <stdlib.h> 23 #include <string.h> 24 25 #include <isc/base64.h> 26 #include <isc/hex.h> 27 #include <isc/util.h> 28 #include <isc/buffer.h> 29 30 #include <dns/cert.h> 31 #include <dns/compress.h> 32 #include <dns/keyvalues.h> 33 #include <dns/rcode.h> 34 #include <dns/rdata.h> 35 #include <dns/rdatatype.h> 36 #include <dns/result.h> 37 #include <dns/time.h> 38 #include <dns/ttl.h> 39 40 #define RETERR(x) \ 41 do { \ 42 isc_result_t _r = (x); \ 43 if (_r != ISC_R_SUCCESS) \ 44 return (_r); \ 45 } while (0) 46 47 #define ARGS_TOTEXT dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, \ 48 isc_buffer_t *target 49 50 #define ARGS_FROMWIRE int rdclass, dns_rdatatype_t type, \ 51 isc_buffer_t *source, dns_decompress_t *dctx, \ 52 unsigned int options, isc_buffer_t *target 53 54 #define ARGS_TOWIRE dns_rdata_t *rdata, dns_compress_t *cctx, \ 55 isc_buffer_t *target 56 57 #define ARGS_FROMSTRUCT int rdclass, dns_rdatatype_t type, \ 58 void *source, isc_buffer_t *target 59 60 #define ARGS_TOSTRUCT const dns_rdata_t *rdata, void *target 61 62 #define ARGS_FREESTRUCT void *source 63 64 #define ARGS_CHECKOWNER dns_name_t *name, dns_rdataclass_t rdclass, \ 65 dns_rdatatype_t type, isc_boolean_t wildcard 66 67 /*% 68 * Context structure for the totext_ functions. 69 * Contains formatting options for rdata-to-text 70 * conversion. 71 */ 72 typedef struct dns_rdata_textctx { 73 dns_name_t *origin; /*%< Current origin, or NULL. */ 74 unsigned int flags; /*%< DNS_STYLEFLAG_* */ 75 unsigned int width; /*%< Width of rdata column. */ 76 const char *linebreak; /*%< Line break string. */ 77 } dns_rdata_textctx_t; 78 79 typedef struct dns_rdata_type_lookup { 80 const char *type; 81 int val; 82 } dns_rdata_type_lookup_t; 83 84 static isc_result_t 85 txt_totext(isc_region_t *source, isc_boolean_t quote, isc_buffer_t *target); 86 87 static isc_result_t 88 txt_fromwire(isc_buffer_t *source, isc_buffer_t *target); 89 90 static isc_result_t 91 multitxt_totext(isc_region_t *source, isc_buffer_t *target); 92 93 static isc_boolean_t 94 name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target); 95 96 static unsigned int 97 name_length(dns_name_t *name); 98 99 static isc_result_t 100 inet_totext(int af, isc_region_t *src, isc_buffer_t *target); 101 102 static isc_boolean_t 103 buffer_empty(isc_buffer_t *source); 104 105 static isc_result_t 106 uint32_tobuffer(uint32_t, isc_buffer_t *target); 107 108 static isc_result_t 109 uint16_tobuffer(uint32_t, isc_buffer_t *target); 110 111 static isc_result_t 112 name_tobuffer(dns_name_t *name, isc_buffer_t *target); 113 114 static uint32_t 115 uint32_fromregion(isc_region_t *region); 116 117 static uint16_t 118 uint16_fromregion(isc_region_t *region); 119 120 static uint8_t 121 uint8_fromregion(isc_region_t *region); 122 123 static uint8_t 124 uint8_consume_fromregion(isc_region_t *region); 125 126 static isc_result_t 127 btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target); 128 129 static isc_result_t 130 rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, 131 isc_buffer_t *target); 132 133 static isc_result_t 134 unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, 135 isc_buffer_t *target); 136 137 static inline isc_result_t 138 generic_totext_key(ARGS_TOTEXT); 139 140 static inline isc_result_t 141 generic_fromwire_key(ARGS_FROMWIRE); 142 143 static isc_result_t 144 generic_totext_txt(ARGS_TOTEXT); 145 146 static isc_result_t 147 generic_fromwire_txt(ARGS_FROMWIRE); 148 149 static isc_result_t 150 generic_totext_ds(ARGS_TOTEXT); 151 152 static isc_result_t 153 generic_fromwire_ds(ARGS_FROMWIRE); 154 155 static isc_result_t 156 generic_totext_tlsa(ARGS_TOTEXT); 157 158 static isc_result_t 159 generic_fromwire_tlsa(ARGS_FROMWIRE); 160 161 static inline isc_result_t 162 name_duporclone(dns_name_t *source, dns_name_t *target) { 163 164 return (dns_name_dup(source, target)); 165 } 166 167 static inline void * 168 mem_maybedup(void *source, size_t length) { 169 void *copy; 170 171 copy = malloc(length); 172 if (copy != NULL) 173 memmove(copy, source, length); 174 175 return (copy); 176 } 177 178 static inline isc_result_t 179 typemap_totext(isc_region_t *sr, dns_rdata_textctx_t *tctx, 180 isc_buffer_t *target) 181 { 182 unsigned int i, j, k; 183 unsigned int window, len; 184 isc_boolean_t first = ISC_TRUE; 185 186 for (i = 0; i < sr->length; i += len) { 187 if (tctx != NULL && 188 (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { 189 RETERR(isc_str_tobuffer(tctx->linebreak, target)); 190 first = ISC_TRUE; 191 } 192 INSIST(i + 2 <= sr->length); 193 window = sr->base[i]; 194 len = sr->base[i + 1]; 195 INSIST(len > 0 && len <= 32); 196 i += 2; 197 INSIST(i + len <= sr->length); 198 for (j = 0; j < len; j++) { 199 dns_rdatatype_t t; 200 if (sr->base[i + j] == 0) 201 continue; 202 for (k = 0; k < 8; k++) { 203 if ((sr->base[i + j] & (0x80 >> k)) == 0) 204 continue; 205 t = window * 256 + j * 8 + k; 206 if (!first) 207 RETERR(isc_str_tobuffer(" ", target)); 208 first = ISC_FALSE; 209 RETERR(dns_rdatatype_totext(t, target)); 210 } 211 } 212 } 213 return (ISC_R_SUCCESS); 214 } 215 216 static isc_result_t 217 typemap_test(isc_region_t *sr, isc_boolean_t allow_empty) { 218 unsigned int window, lastwindow = 0; 219 unsigned int len; 220 isc_boolean_t first = ISC_TRUE; 221 unsigned int i; 222 223 for (i = 0; i < sr->length; i += len) { 224 /* 225 * Check for overflow. 226 */ 227 if (i + 2 > sr->length) 228 return (DNS_R_FORMERR); 229 window = sr->base[i]; 230 len = sr->base[i + 1]; 231 i += 2; 232 /* 233 * Check that bitmap windows are in the correct order. 234 */ 235 if (!first && window <= lastwindow) 236 return (DNS_R_FORMERR); 237 /* 238 * Check for legal lengths. 239 */ 240 if (len < 1 || len > 32) 241 return (DNS_R_FORMERR); 242 /* 243 * Check for overflow. 244 */ 245 if (i + len > sr->length) 246 return (DNS_R_FORMERR); 247 /* 248 * The last octet of the bitmap must be non zero. 249 */ 250 if (sr->base[i + len - 1] == 0) 251 return (DNS_R_FORMERR); 252 lastwindow = window; 253 first = ISC_FALSE; 254 } 255 if (i != sr->length) 256 return (DNS_R_EXTRADATA); 257 if (!allow_empty && first) 258 return (DNS_R_FORMERR); 259 return (ISC_R_SUCCESS); 260 } 261 262 static const char decdigits[] = "0123456789"; 263 264 #include "code.h" 265 266 /*** 267 *** Initialization 268 ***/ 269 270 void 271 dns_rdata_init(dns_rdata_t *rdata) { 272 273 REQUIRE(rdata != NULL); 274 275 rdata->data = NULL; 276 rdata->length = 0; 277 rdata->rdclass = 0; 278 rdata->type = 0; 279 rdata->flags = 0; 280 ISC_LINK_INIT(rdata, link); 281 /* ISC_LIST_INIT(rdata->list); */ 282 } 283 284 void 285 dns_rdata_reset(dns_rdata_t *rdata) { 286 287 REQUIRE(rdata != NULL); 288 289 REQUIRE(!ISC_LINK_LINKED(rdata, link)); 290 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 291 292 rdata->data = NULL; 293 rdata->length = 0; 294 rdata->rdclass = 0; 295 rdata->type = 0; 296 rdata->flags = 0; 297 } 298 299 /*** 300 *** 301 ***/ 302 303 void 304 dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target) { 305 306 REQUIRE(src != NULL); 307 REQUIRE(target != NULL); 308 309 REQUIRE(DNS_RDATA_INITIALIZED(target)); 310 311 REQUIRE(DNS_RDATA_VALIDFLAGS(src)); 312 REQUIRE(DNS_RDATA_VALIDFLAGS(target)); 313 314 target->data = src->data; 315 target->length = src->length; 316 target->rdclass = src->rdclass; 317 target->type = src->type; 318 target->flags = src->flags; 319 } 320 321 /*** 322 *** Conversions 323 ***/ 324 325 void 326 dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 327 dns_rdatatype_t type, isc_region_t *r) 328 { 329 330 REQUIRE(rdata != NULL); 331 REQUIRE(DNS_RDATA_INITIALIZED(rdata)); 332 REQUIRE(r != NULL); 333 334 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 335 336 rdata->data = r->base; 337 rdata->length = r->length; 338 rdata->rdclass = rdclass; 339 rdata->type = type; 340 rdata->flags = 0; 341 } 342 343 void 344 dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r) { 345 346 REQUIRE(rdata != NULL); 347 REQUIRE(r != NULL); 348 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 349 350 r->base = rdata->data; 351 r->length = rdata->length; 352 } 353 354 isc_result_t 355 dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 356 dns_rdatatype_t type, isc_buffer_t *source, 357 dns_decompress_t *dctx, unsigned int options, 358 isc_buffer_t *target) 359 { 360 isc_result_t result = ISC_R_NOTIMPLEMENTED; 361 isc_region_t region; 362 isc_buffer_t ss; 363 isc_buffer_t st; 364 isc_boolean_t use_default = ISC_FALSE; 365 uint32_t activelength; 366 unsigned int length; 367 368 REQUIRE(dctx != NULL); 369 if (rdata != NULL) { 370 REQUIRE(DNS_RDATA_INITIALIZED(rdata)); 371 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 372 } 373 REQUIRE(source != NULL); 374 REQUIRE(target != NULL); 375 376 if (type == 0) 377 return (DNS_R_FORMERR); 378 379 ss = *source; 380 st = *target; 381 382 activelength = isc_buffer_activelength(source); 383 INSIST(activelength < 65536); 384 385 FROMWIRESWITCH 386 387 if (use_default) { 388 if (activelength > isc_buffer_availablelength(target)) 389 result = ISC_R_NOSPACE; 390 else { 391 isc_buffer_putmem(target, isc_buffer_current(source), 392 activelength); 393 isc_buffer_forward(source, activelength); 394 result = ISC_R_SUCCESS; 395 } 396 } 397 398 /* 399 * Reject any rdata that expands out to more than DNS_RDATA_MAXLENGTH 400 * as we cannot transmit it. 401 */ 402 length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); 403 if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH) 404 result = DNS_R_FORMERR; 405 406 /* 407 * We should have consumed all of our buffer. 408 */ 409 if (result == ISC_R_SUCCESS && !buffer_empty(source)) 410 result = DNS_R_EXTRADATA; 411 412 if (rdata != NULL && result == ISC_R_SUCCESS) { 413 region.base = isc_buffer_used(&st); 414 region.length = length; 415 dns_rdata_fromregion(rdata, rdclass, type, ®ion); 416 } 417 418 if (result != ISC_R_SUCCESS) { 419 *source = ss; 420 *target = st; 421 } 422 return (result); 423 } 424 425 isc_result_t 426 dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx, 427 isc_buffer_t *target) 428 { 429 isc_result_t result = ISC_R_NOTIMPLEMENTED; 430 isc_boolean_t use_default = ISC_FALSE; 431 isc_region_t tr; 432 isc_buffer_t st; 433 434 REQUIRE(rdata != NULL); 435 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 436 437 /* 438 * Some DynDNS meta-RRs have empty rdata. 439 */ 440 if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { 441 INSIST(rdata->length == 0); 442 return (ISC_R_SUCCESS); 443 } 444 445 st = *target; 446 447 TOWIRESWITCH 448 449 if (use_default) { 450 isc_buffer_availableregion(target, &tr); 451 if (tr.length < rdata->length) 452 return (ISC_R_NOSPACE); 453 memmove(tr.base, rdata->data, rdata->length); 454 isc_buffer_add(target, rdata->length); 455 return (ISC_R_SUCCESS); 456 } 457 if (result != ISC_R_SUCCESS) { 458 *target = st; 459 INSIST(target->used < 65536); 460 dns_compress_rollback(cctx, (uint16_t)target->used); 461 } 462 return (result); 463 } 464 465 static isc_result_t 466 unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, 467 isc_buffer_t *target) 468 { 469 isc_result_t result; 470 char buf[sizeof("65535")]; 471 isc_region_t sr; 472 473 strlcpy(buf, "\\# ", sizeof(buf)); 474 result = isc_str_tobuffer(buf, target); 475 if (result != ISC_R_SUCCESS) 476 return (result); 477 478 dns_rdata_toregion(rdata, &sr); 479 INSIST(sr.length < 65536); 480 snprintf(buf, sizeof(buf), "%u", sr.length); 481 result = isc_str_tobuffer(buf, target); 482 if (result != ISC_R_SUCCESS) 483 return (result); 484 485 if (sr.length != 0U) { 486 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 487 result = isc_str_tobuffer(" ( ", target); 488 else 489 result = isc_str_tobuffer(" ", target); 490 491 if (result != ISC_R_SUCCESS) 492 return (result); 493 494 if (tctx->width == 0) /* No splitting */ 495 result = isc_hex_totext(&sr, 0, "", target); 496 else 497 result = isc_hex_totext(&sr, tctx->width - 2, 498 tctx->linebreak, 499 target); 500 if (result == ISC_R_SUCCESS && 501 (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) 502 result = isc_str_tobuffer(" )", target); 503 } 504 return (result); 505 } 506 507 static isc_result_t 508 rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, 509 isc_buffer_t *target) 510 { 511 isc_result_t result = ISC_R_NOTIMPLEMENTED; 512 isc_boolean_t use_default = ISC_FALSE; 513 unsigned int cur; 514 515 REQUIRE(rdata != NULL); 516 REQUIRE(tctx->origin == NULL || 517 dns_name_isabsolute(tctx->origin) == ISC_TRUE); 518 519 /* 520 * Some DynDNS meta-RRs have empty rdata. 521 */ 522 if ((rdata->flags & DNS_RDATA_UPDATE) != 0) { 523 INSIST(rdata->length == 0); 524 return (ISC_R_SUCCESS); 525 } 526 527 cur = isc_buffer_usedlength(target); 528 529 TOTEXTSWITCH 530 531 if (use_default || (result == ISC_R_NOTIMPLEMENTED)) { 532 unsigned int u = isc_buffer_usedlength(target); 533 534 INSIST(u >= cur); 535 isc_buffer_subtract(target, u - cur); 536 result = unknown_totext(rdata, tctx, target); 537 } 538 539 return (result); 540 } 541 542 isc_result_t 543 dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target) 544 { 545 dns_rdata_textctx_t tctx; 546 547 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 548 549 /* 550 * Set up formatting options for single-line output. 551 */ 552 tctx.origin = origin; 553 tctx.flags = 0; 554 tctx.width = 60; 555 tctx.linebreak = " "; 556 return (rdata_totext(rdata, &tctx, target)); 557 } 558 559 isc_result_t 560 dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, 561 unsigned int flags, unsigned int width, 562 unsigned int split_width, const char *linebreak, 563 isc_buffer_t *target) 564 { 565 dns_rdata_textctx_t tctx; 566 567 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 568 569 /* 570 * Set up formatting options for formatted output. 571 */ 572 tctx.origin = origin; 573 tctx.flags = flags; 574 if (split_width == 0xffffffff) 575 tctx.width = width; 576 else 577 tctx.width = split_width; 578 579 if ((flags & DNS_STYLEFLAG_MULTILINE) != 0) 580 tctx.linebreak = linebreak; 581 else { 582 if (split_width == 0xffffffff) 583 tctx.width = 60; /* Used for hex word length only. */ 584 tctx.linebreak = " "; 585 } 586 return (rdata_totext(rdata, &tctx, target)); 587 } 588 589 isc_result_t 590 dns_rdata_fromstruct_soa(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 591 dns_rdatatype_t type, dns_rdata_soa_t *soa, 592 isc_buffer_t *target) 593 { 594 isc_result_t result = ISC_R_NOTIMPLEMENTED; 595 isc_buffer_t st; 596 isc_region_t region; 597 unsigned int length; 598 599 REQUIRE(soa != NULL); 600 if (rdata != NULL) { 601 REQUIRE(DNS_RDATA_INITIALIZED(rdata)); 602 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 603 } 604 605 st = *target; 606 result = fromstruct_soa(rdclass, type, soa, target); 607 608 length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); 609 if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH) 610 result = ISC_R_NOSPACE; 611 612 if (rdata != NULL && result == ISC_R_SUCCESS) { 613 region.base = isc_buffer_used(&st); 614 region.length = length; 615 dns_rdata_fromregion(rdata, rdclass, type, ®ion); 616 } 617 if (result != ISC_R_SUCCESS) 618 *target = st; 619 return (result); 620 } 621 622 isc_result_t 623 dns_rdata_fromstruct_tsig(dns_rdata_t *rdata, dns_rdataclass_t rdclass, 624 dns_rdatatype_t type, dns_rdata_any_tsig_t *tsig, 625 isc_buffer_t *target) 626 { 627 isc_result_t result = ISC_R_NOTIMPLEMENTED; 628 isc_buffer_t st; 629 isc_region_t region; 630 unsigned int length; 631 632 REQUIRE(tsig != NULL); 633 if (rdata != NULL) { 634 REQUIRE(DNS_RDATA_INITIALIZED(rdata)); 635 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 636 } 637 638 st = *target; 639 result = fromstruct_any_tsig(rdclass, type, tsig, target); 640 641 length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); 642 if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH) 643 result = ISC_R_NOSPACE; 644 645 if (rdata != NULL && result == ISC_R_SUCCESS) { 646 region.base = isc_buffer_used(&st); 647 region.length = length; 648 dns_rdata_fromregion(rdata, rdclass, type, ®ion); 649 } 650 if (result != ISC_R_SUCCESS) 651 *target = st; 652 return (result); 653 } 654 655 isc_result_t 656 dns_rdata_tostruct_cname(const dns_rdata_t *rdata, dns_rdata_cname_t *cname) { 657 REQUIRE(rdata != NULL); 658 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 659 660 return (tostruct_cname(rdata, cname)); 661 } 662 663 isc_result_t 664 dns_rdata_tostruct_ns(const dns_rdata_t *rdata, dns_rdata_ns_t *ns) { 665 REQUIRE(rdata != NULL); 666 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 667 668 return (tostruct_ns(rdata, ns)); 669 } 670 671 isc_result_t 672 dns_rdata_tostruct_soa(const dns_rdata_t *rdata, dns_rdata_soa_t *soa) { 673 REQUIRE(rdata != NULL); 674 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 675 676 return (tostruct_soa(rdata, soa)); 677 } 678 679 isc_result_t 680 dns_rdata_tostruct_tsig(const dns_rdata_t *rdata, dns_rdata_any_tsig_t *tsig) { 681 REQUIRE(rdata != NULL); 682 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata)); 683 684 return (tostruct_any_tsig(rdata, tsig)); 685 } 686 687 void 688 dns_rdata_freestruct_cname(dns_rdata_cname_t *cname) { 689 REQUIRE(cname != NULL); 690 691 freestruct_cname(cname); 692 } 693 694 void 695 dns_rdata_freestruct_ns(dns_rdata_ns_t *ns) { 696 REQUIRE(ns != NULL); 697 698 freestruct_ns(ns); 699 } 700 701 void 702 dns_rdata_freestruct_soa(dns_rdata_soa_t *soa) { 703 REQUIRE(soa != NULL); 704 705 freestruct_soa(soa); 706 } 707 708 void 709 dns_rdata_freestruct_tsig(dns_rdata_any_tsig_t *tsig) { 710 REQUIRE(tsig != NULL); 711 712 freestruct_any_tsig(tsig); 713 } 714 715 isc_boolean_t 716 dns_rdata_checkowner_nsec3(dns_name_t *name, dns_rdataclass_t rdclass, 717 dns_rdatatype_t type, isc_boolean_t wildcard) 718 { 719 return checkowner_nsec3(name, rdclass, type, wildcard); 720 } 721 722 unsigned int 723 dns_rdatatype_attributes(dns_rdatatype_t type) 724 { 725 switch (type) { 726 case 0: 727 case 31: 728 case 32: 729 case 34: 730 case 100: 731 case 101: 732 case 102: 733 return (DNS_RDATATYPEATTR_RESERVED); 734 default: 735 return (0); 736 } 737 } 738 739 static int 740 type_cmp(const void *k, const void *e) 741 { 742 return (strcasecmp(k, ((const dns_rdata_type_lookup_t *)e)->type)); 743 } 744 745 isc_result_t 746 dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) { 747 /* This has to be sorted always. */ 748 static const dns_rdata_type_lookup_t type_lookup[] = { 749 {"a", 1}, 750 {"a6", 38}, 751 {"aaaa", 28}, 752 {"afsdb", 18}, 753 {"any", 255}, 754 {"apl", 42}, 755 {"atma", 34}, 756 {"avc", 258}, 757 {"axfr", 252}, 758 {"caa", 257}, 759 {"cdnskey", 60}, 760 {"cds", 59}, 761 {"cert", 37}, 762 {"cname", 5}, 763 {"csync", 62}, 764 {"dhcid", 49}, 765 {"dlv", 32769}, 766 {"dname", 39}, 767 {"dnskey", 48}, 768 {"doa", 259}, 769 {"ds", 43}, 770 {"eid", 31}, 771 {"eui48", 108}, 772 {"eui64", 109}, 773 {"gid", 102}, 774 {"gpos", 27}, 775 {"hinfo", 13}, 776 {"hip", 55}, 777 {"ipseckey", 45}, 778 {"isdn", 20}, 779 {"ixfr", 251}, 780 {"key", 25}, 781 {"keydata", 65533}, 782 {"kx", 36}, 783 {"l32", 105}, 784 {"l64", 106}, 785 {"loc", 29}, 786 {"lp", 107}, 787 {"maila", 254}, 788 {"mailb", 253}, 789 {"mb", 7}, 790 {"md", 3}, 791 {"mf", 4}, 792 {"mg", 8}, 793 {"minfo", 14}, 794 {"mr", 9}, 795 {"mx", 15}, 796 {"naptr", 35}, 797 {"nid", 104}, 798 {"nimloc", 32}, 799 {"ninfo", 56}, 800 {"ns", 2}, 801 {"nsap", 22}, 802 {"nsap-ptr", 23}, 803 {"nsec", 47}, 804 {"nsec3", 50}, 805 {"nsec3param", 51}, 806 {"null", 10}, 807 {"nxt", 30}, 808 {"openpgpkey", 61}, 809 {"opt", 41}, 810 {"ptr", 12}, 811 {"px", 26}, 812 {"reserved0", 0}, 813 {"rkey", 57}, 814 {"rp", 17}, 815 {"rrsig", 46}, 816 {"rt", 21}, 817 {"sig", 24}, 818 {"sink", 40}, 819 {"smimea", 53}, 820 {"soa", 6}, 821 {"spf", 99}, 822 {"srv", 33}, 823 {"sshfp", 44}, 824 {"ta", 32768}, 825 {"talink", 58}, 826 {"tkey", 249}, 827 {"tlsa", 52}, 828 {"tsig", 250}, 829 {"txt", 16}, 830 {"uid", 101}, 831 {"uinfo", 100}, 832 {"unspec", 103}, 833 {"uri", 256}, 834 {"wks", 11}, 835 {"x25", 19} 836 }; 837 const dns_rdata_type_lookup_t *p; 838 unsigned int n; 839 char lookup[sizeof("nsec3param")]; 840 841 n = source->length; 842 843 if (n == 0) 844 return (DNS_R_UNKNOWN); 845 846 /* source->base is not required to be NUL terminated. */ 847 if ((size_t)snprintf(lookup, sizeof(lookup), "%.*s", n, source->base) 848 >= sizeof(lookup)) 849 return (DNS_R_UNKNOWN); 850 851 p = bsearch(lookup, type_lookup, 852 sizeof(type_lookup)/sizeof(type_lookup[0]), sizeof(type_lookup[0]), 853 type_cmp); 854 855 if (p) { 856 if ((dns_rdatatype_attributes(p->val) & 857 DNS_RDATATYPEATTR_RESERVED) != 0) 858 return (ISC_R_NOTIMPLEMENTED); 859 *typep = p->val; 860 return (ISC_R_SUCCESS); 861 } 862 863 if (n > 4 && strncasecmp("type", lookup, 4) == 0) { 864 int val; 865 const char *errstr; 866 val = strtonum(lookup + 4, 0, UINT16_MAX, &errstr); 867 if (errstr == NULL) { 868 *typep = val; 869 return (ISC_R_SUCCESS); 870 } 871 } 872 873 return (DNS_R_UNKNOWN); 874 } 875 876 isc_result_t 877 dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) { 878 char buf[sizeof("TYPE65535")]; 879 880 switch (type) { 881 case 0: 882 return (isc_str_tobuffer("RESERVED0", target)); 883 case 1: 884 return (isc_str_tobuffer("A", target)); 885 case 2: 886 return (isc_str_tobuffer("NS", target)); 887 case 3: 888 return (isc_str_tobuffer("MD", target)); 889 case 4: 890 return (isc_str_tobuffer("MF", target)); 891 case 5: 892 return (isc_str_tobuffer("CNAME", target)); 893 case 6: 894 return (isc_str_tobuffer("SOA", target)); 895 case 7: 896 return (isc_str_tobuffer("MB", target)); 897 case 8: 898 return (isc_str_tobuffer("MG", target)); 899 case 9: 900 return (isc_str_tobuffer("MR", target)); 901 case 10: 902 return (isc_str_tobuffer("NULL", target)); 903 case 11: 904 return (isc_str_tobuffer("WKS", target)); 905 case 12: 906 return (isc_str_tobuffer("PTR", target)); 907 case 13: 908 return (isc_str_tobuffer("HINFO", target)); 909 case 14: 910 return (isc_str_tobuffer("MINFO", target)); 911 case 15: 912 return (isc_str_tobuffer("MX", target)); 913 case 16: 914 return (isc_str_tobuffer("TXT", target)); 915 case 17: 916 return (isc_str_tobuffer("RP", target)); 917 case 18: 918 return (isc_str_tobuffer("AFSDB", target)); 919 case 19: 920 return (isc_str_tobuffer("X25", target)); 921 case 20: 922 return (isc_str_tobuffer("ISDN", target)); 923 case 21: 924 return (isc_str_tobuffer("RT", target)); 925 case 22: 926 return (isc_str_tobuffer("NSAP", target)); 927 case 23: 928 return (isc_str_tobuffer("NSAP-PTR", target)); 929 case 24: 930 return (isc_str_tobuffer("SIG", target)); 931 case 25: 932 return (isc_str_tobuffer("KEY", target)); 933 case 26: 934 return (isc_str_tobuffer("PX", target)); 935 case 27: 936 return (isc_str_tobuffer("GPOS", target)); 937 case 28: 938 return (isc_str_tobuffer("AAAA", target)); 939 case 29: 940 return (isc_str_tobuffer("LOC", target)); 941 case 30: 942 return (isc_str_tobuffer("NXT", target)); 943 case 31: 944 return (isc_str_tobuffer("EID", target)); 945 case 32: 946 return (isc_str_tobuffer("NIMLOC", target)); 947 case 33: 948 return (isc_str_tobuffer("SRV", target)); 949 case 34: 950 return (isc_str_tobuffer("ATMA", target)); 951 case 35: 952 return (isc_str_tobuffer("NAPTR", target)); 953 case 36: 954 return (isc_str_tobuffer("KX", target)); 955 case 37: 956 return (isc_str_tobuffer("CERT", target)); 957 case 38: 958 return (isc_str_tobuffer("A6", target)); 959 case 39: 960 return (isc_str_tobuffer("DNAME", target)); 961 case 40: 962 return (isc_str_tobuffer("SINK", target)); 963 case 41: 964 return (isc_str_tobuffer("OPT", target)); 965 case 42: 966 return (isc_str_tobuffer("APL", target)); 967 case 43: 968 return (isc_str_tobuffer("DS", target)); 969 case 44: 970 return (isc_str_tobuffer("SSHFP", target)); 971 case 45: 972 return (isc_str_tobuffer("IPSECKEY", target)); 973 case 46: 974 return (isc_str_tobuffer("RRSIG", target)); 975 case 47: 976 return (isc_str_tobuffer("NSEC", target)); 977 case 48: 978 return (isc_str_tobuffer("DNSKEY", target)); 979 case 49: 980 return (isc_str_tobuffer("DHCID", target)); 981 case 50: 982 return (isc_str_tobuffer("NSEC3", target)); 983 case 51: 984 return (isc_str_tobuffer("NSEC3PARAM", target)); 985 case 52: 986 return (isc_str_tobuffer("TLSA", target)); 987 case 53: 988 return (isc_str_tobuffer("SMIMEA", target)); 989 case 55: 990 return (isc_str_tobuffer("HIP", target)); 991 case 56: 992 return (isc_str_tobuffer("NINFO", target)); 993 case 57: 994 return (isc_str_tobuffer("RKEY", target)); 995 case 58: 996 return (isc_str_tobuffer("TALINK", target)); 997 case 59: 998 return (isc_str_tobuffer("CDS", target)); 999 case 60: 1000 return (isc_str_tobuffer("CDNSKEY", target)); 1001 case 61: 1002 return (isc_str_tobuffer("OPENPGPKEY", target)); 1003 case 62: 1004 return (isc_str_tobuffer("CSYNC", target)); 1005 case 99: 1006 return (isc_str_tobuffer("SPF", target)); 1007 case 100: 1008 return (isc_str_tobuffer("UINFO", target)); 1009 case 101: 1010 return (isc_str_tobuffer("UID", target)); 1011 case 102: 1012 return (isc_str_tobuffer("GID", target)); 1013 case 103: 1014 return (isc_str_tobuffer("UNSPEC", target)); 1015 case 104: 1016 return (isc_str_tobuffer("NID", target)); 1017 case 105: 1018 return (isc_str_tobuffer("L32", target)); 1019 case 106: 1020 return (isc_str_tobuffer("L64", target)); 1021 case 107: 1022 return (isc_str_tobuffer("LP", target)); 1023 case 108: 1024 return (isc_str_tobuffer("EUI48", target)); 1025 case 109: 1026 return (isc_str_tobuffer("EUI64", target)); 1027 case 249: 1028 return (isc_str_tobuffer("TKEY", target)); 1029 case 250: 1030 return (isc_str_tobuffer("TSIG", target)); 1031 case 251: 1032 return (isc_str_tobuffer("IXFR", target)); 1033 case 252: 1034 return (isc_str_tobuffer("AXFR", target)); 1035 case 253: 1036 return (isc_str_tobuffer("MAILB", target)); 1037 case 254: 1038 return (isc_str_tobuffer("MAILA", target)); 1039 case 255: 1040 return (isc_str_tobuffer("ANY", target)); 1041 case 256: 1042 return (isc_str_tobuffer("URI", target)); 1043 case 257: 1044 return (isc_str_tobuffer("CAA", target)); 1045 case 258: 1046 return (isc_str_tobuffer("AVC", target)); 1047 case 259: 1048 return (isc_str_tobuffer("DOA", target)); 1049 case 32768: 1050 return (isc_str_tobuffer("TA", target)); 1051 case 32769: 1052 return (isc_str_tobuffer("DLV", target)); 1053 default: 1054 snprintf(buf, sizeof(buf), "TYPE%u", type); 1055 return (isc_str_tobuffer(buf, target)); 1056 } 1057 } 1058 1059 void 1060 dns_rdatatype_format(dns_rdatatype_t rdtype, 1061 char *array, unsigned int size) 1062 { 1063 isc_result_t result; 1064 isc_buffer_t buf; 1065 1066 if (size == 0U) 1067 return; 1068 1069 isc_buffer_init(&buf, array, size); 1070 result = dns_rdatatype_totext(rdtype, &buf); 1071 /* 1072 * Null terminate. 1073 */ 1074 if (result == ISC_R_SUCCESS) { 1075 if (isc_buffer_availablelength(&buf) >= 1) 1076 isc_buffer_putuint8(&buf, 0); 1077 else 1078 result = ISC_R_NOSPACE; 1079 } 1080 if (result != ISC_R_SUCCESS) 1081 strlcpy(array, "<unknown>", size); 1082 } 1083 1084 /* 1085 * Private function. 1086 */ 1087 1088 static unsigned int 1089 name_length(dns_name_t *name) { 1090 return (name->length); 1091 } 1092 1093 static isc_result_t 1094 txt_totext(isc_region_t *source, isc_boolean_t quote, isc_buffer_t *target) { 1095 unsigned int tl; 1096 unsigned int n; 1097 unsigned char *sp; 1098 char *tp; 1099 isc_region_t region; 1100 1101 isc_buffer_availableregion(target, ®ion); 1102 sp = source->base; 1103 tp = (char *)region.base; 1104 tl = region.length; 1105 1106 n = *sp++; 1107 1108 REQUIRE(n + 1 <= source->length); 1109 if (n == 0U) 1110 REQUIRE(quote == ISC_TRUE); 1111 1112 if (quote) { 1113 if (tl < 1) 1114 return (ISC_R_NOSPACE); 1115 *tp++ = '"'; 1116 tl--; 1117 } 1118 while (n--) { 1119 /* 1120 * \DDD space (0x20) if not quoting. 1121 */ 1122 if (*sp < (quote ? 0x20 : 0x21) || *sp >= 0x7f) { 1123 if (tl < 4) 1124 return (ISC_R_NOSPACE); 1125 *tp++ = 0x5c; 1126 *tp++ = 0x30 + ((*sp / 100) % 10); 1127 *tp++ = 0x30 + ((*sp / 10) % 10); 1128 *tp++ = 0x30 + (*sp % 10); 1129 sp++; 1130 tl -= 4; 1131 continue; 1132 } 1133 /* 1134 * Escape double quote and backslash. If we are not 1135 * enclosing the string in double quotes also escape 1136 * at sign and semicolon. 1137 */ 1138 if (*sp == 0x22 || *sp == 0x5c || 1139 (!quote && (*sp == 0x40 || *sp == 0x3b))) { 1140 if (tl < 2) 1141 return (ISC_R_NOSPACE); 1142 *tp++ = '\\'; 1143 tl--; 1144 } 1145 if (tl < 1) 1146 return (ISC_R_NOSPACE); 1147 *tp++ = *sp++; 1148 tl--; 1149 } 1150 if (quote) { 1151 if (tl < 1) 1152 return (ISC_R_NOSPACE); 1153 *tp++ = '"'; 1154 tl--; 1155 POST(tl); 1156 } 1157 isc_buffer_add(target, (unsigned int)(tp - (char *)region.base)); 1158 isc_region_consume(source, *source->base + 1); 1159 return (ISC_R_SUCCESS); 1160 } 1161 1162 static isc_result_t 1163 txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { 1164 unsigned int n; 1165 isc_region_t sregion; 1166 isc_region_t tregion; 1167 1168 isc_buffer_activeregion(source, &sregion); 1169 if (sregion.length == 0) 1170 return (ISC_R_UNEXPECTEDEND); 1171 n = *sregion.base + 1; 1172 if (n > sregion.length) 1173 return (ISC_R_UNEXPECTEDEND); 1174 1175 isc_buffer_availableregion(target, &tregion); 1176 if (n > tregion.length) 1177 return (ISC_R_NOSPACE); 1178 1179 if (tregion.base != sregion.base) 1180 memmove(tregion.base, sregion.base, n); 1181 isc_buffer_forward(source, n); 1182 isc_buffer_add(target, n); 1183 return (ISC_R_SUCCESS); 1184 } 1185 1186 /* 1187 * Conversion of TXT-like rdata fields without length limits. 1188 */ 1189 static isc_result_t 1190 multitxt_totext(isc_region_t *source, isc_buffer_t *target) { 1191 unsigned int tl; 1192 unsigned int n0, n; 1193 unsigned char *sp; 1194 char *tp; 1195 isc_region_t region; 1196 1197 isc_buffer_availableregion(target, ®ion); 1198 sp = source->base; 1199 tp = (char *)region.base; 1200 tl = region.length; 1201 1202 if (tl < 1) 1203 return (ISC_R_NOSPACE); 1204 *tp++ = '"'; 1205 tl--; 1206 do { 1207 n = source->length; 1208 n0 = source->length - 1; 1209 1210 while (n--) { 1211 if (*sp < 0x20 || *sp >= 0x7f) { 1212 if (tl < 4) 1213 return (ISC_R_NOSPACE); 1214 *tp++ = 0x5c; 1215 *tp++ = 0x30 + ((*sp / 100) % 10); 1216 *tp++ = 0x30 + ((*sp / 10) % 10); 1217 *tp++ = 0x30 + (*sp % 10); 1218 sp++; 1219 tl -= 4; 1220 continue; 1221 } 1222 /* double quote, backslash */ 1223 if (*sp == 0x22 || *sp == 0x5c) { 1224 if (tl < 2) 1225 return (ISC_R_NOSPACE); 1226 *tp++ = '\\'; 1227 tl--; 1228 } 1229 if (tl < 1) 1230 return (ISC_R_NOSPACE); 1231 *tp++ = *sp++; 1232 tl--; 1233 } 1234 isc_region_consume(source, n0 + 1); 1235 } while (source->length != 0); 1236 if (tl < 1) 1237 return (ISC_R_NOSPACE); 1238 *tp++ = '"'; 1239 tl--; 1240 POST(tl); 1241 isc_buffer_add(target, (unsigned int)(tp - (char *)region.base)); 1242 return (ISC_R_SUCCESS); 1243 } 1244 1245 static isc_boolean_t 1246 name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) { 1247 int l1, l2; 1248 1249 if (origin == NULL) 1250 goto return_false; 1251 1252 if (dns_name_compare(origin, dns_rootname) == 0) 1253 goto return_false; 1254 1255 if (!dns_name_issubdomain(name, origin)) 1256 goto return_false; 1257 1258 l1 = dns_name_countlabels(name); 1259 l2 = dns_name_countlabels(origin); 1260 1261 if (l1 == l2) 1262 goto return_false; 1263 1264 /* Master files should be case preserving. */ 1265 dns_name_getlabelsequence(name, l1 - l2, l2, target); 1266 if (!dns_name_caseequal(origin, target)) 1267 goto return_false; 1268 1269 dns_name_getlabelsequence(name, 0, l1 - l2, target); 1270 return (ISC_TRUE); 1271 1272 return_false: 1273 *target = *name; 1274 return (ISC_FALSE); 1275 } 1276 1277 static isc_result_t 1278 inet_totext(int af, isc_region_t *src, isc_buffer_t *target) { 1279 char tmpbuf[64]; 1280 1281 /* Note - inet_ntop doesn't do size checking on its input. */ 1282 if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL) 1283 return (ISC_R_NOSPACE); 1284 if (strlen(tmpbuf) > isc_buffer_availablelength(target)) 1285 return (ISC_R_NOSPACE); 1286 isc_buffer_putstr(target, tmpbuf); 1287 return (ISC_R_SUCCESS); 1288 } 1289 1290 static isc_boolean_t 1291 buffer_empty(isc_buffer_t *source) { 1292 return((source->current == source->active) ? ISC_TRUE : ISC_FALSE); 1293 } 1294 1295 static isc_result_t 1296 uint32_tobuffer(uint32_t value, isc_buffer_t *target) { 1297 isc_region_t region; 1298 1299 isc_buffer_availableregion(target, ®ion); 1300 if (region.length < 4) 1301 return (ISC_R_NOSPACE); 1302 isc_buffer_putuint32(target, value); 1303 return (ISC_R_SUCCESS); 1304 } 1305 1306 static isc_result_t 1307 uint16_tobuffer(uint32_t value, isc_buffer_t *target) { 1308 isc_region_t region; 1309 1310 if (value > 0xffff) 1311 return (ISC_R_RANGE); 1312 isc_buffer_availableregion(target, ®ion); 1313 if (region.length < 2) 1314 return (ISC_R_NOSPACE); 1315 isc_buffer_putuint16(target, (uint16_t)value); 1316 return (ISC_R_SUCCESS); 1317 } 1318 1319 static isc_result_t 1320 name_tobuffer(dns_name_t *name, isc_buffer_t *target) { 1321 isc_region_t r; 1322 dns_name_toregion(name, &r); 1323 return (isc_buffer_copyregion(target, &r)); 1324 } 1325 1326 static uint32_t 1327 uint32_fromregion(isc_region_t *region) { 1328 uint32_t value; 1329 1330 REQUIRE(region->length >= 4); 1331 value = region->base[0] << 24; 1332 value |= region->base[1] << 16; 1333 value |= region->base[2] << 8; 1334 value |= region->base[3]; 1335 return(value); 1336 } 1337 1338 static uint16_t 1339 uint16_fromregion(isc_region_t *region) { 1340 1341 REQUIRE(region->length >= 2); 1342 1343 return ((region->base[0] << 8) | region->base[1]); 1344 } 1345 1346 static uint8_t 1347 uint8_fromregion(isc_region_t *region) { 1348 1349 REQUIRE(region->length >= 1); 1350 1351 return (region->base[0]); 1352 } 1353 1354 static uint8_t 1355 uint8_consume_fromregion(isc_region_t *region) { 1356 uint8_t r = uint8_fromregion(region); 1357 1358 isc_region_consume(region, 1); 1359 return r; 1360 } 1361 1362 static const char atob_digits[86] = 1363 "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \ 1364 "abcdefghijklmnopqrstu"; 1365 /* 1366 * Subroutines to convert between 8 bit binary bytes and printable ASCII. 1367 * Computes the number of bytes, and three kinds of simple checksums. 1368 * Incoming bytes are collected into 32-bit words, then printed in base 85: 1369 * exp(85,5) > exp(2,32) 1370 * The ASCII characters used are between '!' and 'u'; 1371 * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data. 1372 * 1373 * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for 1374 * the atob/btoa programs, released with the compress program, in mod.sources. 1375 * Modified by Mike Schwartz 8/19/86 for use in BIND. 1376 * Modified to be re-entrant 3/2/99. 1377 */ 1378 1379 struct state { 1380 int32_t Ceor; 1381 int32_t Csum; 1382 int32_t Crot; 1383 int32_t word; 1384 int32_t bcount; 1385 }; 1386 1387 #define Ceor state->Ceor 1388 #define Csum state->Csum 1389 #define Crot state->Crot 1390 #define word state->word 1391 #define bcount state->bcount 1392 1393 static isc_result_t byte_btoa(int c, isc_buffer_t *, struct state *state); 1394 1395 /* 1396 * Encode binary byte c into ASCII representation and place into *bufp, 1397 * advancing bufp. 1398 */ 1399 static isc_result_t 1400 byte_btoa(int c, isc_buffer_t *target, struct state *state) { 1401 isc_region_t tr; 1402 1403 isc_buffer_availableregion(target, &tr); 1404 Ceor ^= c; 1405 Csum += c; 1406 Csum += 1; 1407 if ((Crot & 0x80000000)) { 1408 Crot <<= 1; 1409 Crot += 1; 1410 } else { 1411 Crot <<= 1; 1412 } 1413 Crot += c; 1414 1415 word <<= 8; 1416 word |= c; 1417 if (bcount == 3) { 1418 if (word == 0) { 1419 if (tr.length < 1) 1420 return (ISC_R_NOSPACE); 1421 tr.base[0] = 'z'; 1422 isc_buffer_add(target, 1); 1423 } else { 1424 register int tmp = 0; 1425 register int32_t tmpword = word; 1426 1427 if (tmpword < 0) { 1428 /* 1429 * Because some don't support u_long. 1430 */ 1431 tmp = 32; 1432 tmpword -= (int32_t)(85 * 85 * 85 * 85 * 32); 1433 } 1434 if (tmpword < 0) { 1435 tmp = 64; 1436 tmpword -= (int32_t)(85 * 85 * 85 * 85 * 32); 1437 } 1438 if (tr.length < 5) 1439 return (ISC_R_NOSPACE); 1440 tr.base[0] = atob_digits[(tmpword / 1441 (int32_t)(85 * 85 * 85 * 85)) 1442 + tmp]; 1443 tmpword %= (int32_t)(85 * 85 * 85 * 85); 1444 tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)]; 1445 tmpword %= (85 * 85 * 85); 1446 tr.base[2] = atob_digits[tmpword / (85 * 85)]; 1447 tmpword %= (85 * 85); 1448 tr.base[3] = atob_digits[tmpword / 85]; 1449 tmpword %= 85; 1450 tr.base[4] = atob_digits[tmpword]; 1451 isc_buffer_add(target, 5); 1452 } 1453 bcount = 0; 1454 } else { 1455 bcount += 1; 1456 } 1457 return (ISC_R_SUCCESS); 1458 } 1459 1460 /* 1461 * Encode the binary data from inbuf, of length inbuflen, into a 1462 * target. Return success/failure status 1463 */ 1464 static isc_result_t 1465 btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) { 1466 int inc; 1467 struct state statebuf, *state = &statebuf; 1468 char buf[sizeof("x 2000000000 ffffffff ffffffff ffffffff")]; 1469 1470 Ceor = Csum = Crot = word = bcount = 0; 1471 for (inc = 0; inc < inbuflen; inbuf++, inc++) 1472 RETERR(byte_btoa(*inbuf, target, state)); 1473 1474 while (bcount != 0) 1475 RETERR(byte_btoa(0, target, state)); 1476 1477 /* 1478 * Put byte count and checksum information at end of buffer, 1479 * delimited by 'x' 1480 */ 1481 snprintf(buf, sizeof(buf), "x %d %x %x %x", inbuflen, Ceor, Csum, Crot); 1482 return (isc_str_tobuffer(buf, target)); 1483 } 1484 1485 dns_rdatatype_t 1486 dns_rdata_covers(dns_rdata_t *rdata) { 1487 if (rdata->type == dns_rdatatype_rrsig) 1488 return (covers_rrsig(rdata)); 1489 return (covers_sig(rdata)); 1490 } 1491