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