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.32 2020/09/14 08:40:43 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 }; 838 const dns_rdata_type_lookup_t *p; 839 unsigned int n; 840 char lookup[sizeof("nsec3param")]; 841 842 n = source->length; 843 844 if (n == 0) 845 return (DNS_R_UNKNOWN); 846 847 /* source->base is not required to be NUL terminated. */ 848 if ((size_t)snprintf(lookup, sizeof(lookup), "%.*s", n, source->base) 849 >= sizeof(lookup)) 850 return (DNS_R_UNKNOWN); 851 852 p = bsearch(lookup, type_lookup, 853 sizeof(type_lookup)/sizeof(type_lookup[0]), sizeof(type_lookup[0]), 854 type_cmp); 855 856 if (p) { 857 if ((dns_rdatatype_attributes(p->val) & 858 DNS_RDATATYPEATTR_RESERVED) != 0) 859 return (ISC_R_NOTIMPLEMENTED); 860 *typep = p->val; 861 return (ISC_R_SUCCESS); 862 } 863 864 if (n > 4 && strncasecmp("type", lookup, 4) == 0) { 865 int val; 866 const char *errstr; 867 val = strtonum(lookup + 4, 0, UINT16_MAX, &errstr); 868 if (errstr == NULL) { 869 *typep = val; 870 return (ISC_R_SUCCESS); 871 } 872 } 873 874 return (DNS_R_UNKNOWN); 875 } 876 877 isc_result_t 878 dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) { 879 char buf[sizeof("TYPE65535")]; 880 881 switch (type) { 882 case 0: 883 return (isc_str_tobuffer("RESERVED0", target)); 884 case 1: 885 return (isc_str_tobuffer("A", target)); 886 case 2: 887 return (isc_str_tobuffer("NS", target)); 888 case 3: 889 return (isc_str_tobuffer("MD", target)); 890 case 4: 891 return (isc_str_tobuffer("MF", target)); 892 case 5: 893 return (isc_str_tobuffer("CNAME", target)); 894 case 6: 895 return (isc_str_tobuffer("SOA", target)); 896 case 7: 897 return (isc_str_tobuffer("MB", target)); 898 case 8: 899 return (isc_str_tobuffer("MG", target)); 900 case 9: 901 return (isc_str_tobuffer("MR", target)); 902 case 10: 903 return (isc_str_tobuffer("NULL", target)); 904 case 11: 905 return (isc_str_tobuffer("WKS", target)); 906 case 12: 907 return (isc_str_tobuffer("PTR", target)); 908 case 13: 909 return (isc_str_tobuffer("HINFO", target)); 910 case 14: 911 return (isc_str_tobuffer("MINFO", target)); 912 case 15: 913 return (isc_str_tobuffer("MX", target)); 914 case 16: 915 return (isc_str_tobuffer("TXT", target)); 916 case 17: 917 return (isc_str_tobuffer("RP", target)); 918 case 18: 919 return (isc_str_tobuffer("AFSDB", target)); 920 case 19: 921 return (isc_str_tobuffer("X25", target)); 922 case 20: 923 return (isc_str_tobuffer("ISDN", target)); 924 case 21: 925 return (isc_str_tobuffer("RT", target)); 926 case 22: 927 return (isc_str_tobuffer("NSAP", target)); 928 case 23: 929 return (isc_str_tobuffer("NSAP-PTR", target)); 930 case 24: 931 return (isc_str_tobuffer("SIG", target)); 932 case 25: 933 return (isc_str_tobuffer("KEY", target)); 934 case 26: 935 return (isc_str_tobuffer("PX", target)); 936 case 27: 937 return (isc_str_tobuffer("GPOS", target)); 938 case 28: 939 return (isc_str_tobuffer("AAAA", target)); 940 case 29: 941 return (isc_str_tobuffer("LOC", target)); 942 case 30: 943 return (isc_str_tobuffer("NXT", target)); 944 case 31: 945 return (isc_str_tobuffer("EID", target)); 946 case 32: 947 return (isc_str_tobuffer("NIMLOC", target)); 948 case 33: 949 return (isc_str_tobuffer("SRV", target)); 950 case 34: 951 return (isc_str_tobuffer("ATMA", target)); 952 case 35: 953 return (isc_str_tobuffer("NAPTR", target)); 954 case 36: 955 return (isc_str_tobuffer("KX", target)); 956 case 37: 957 return (isc_str_tobuffer("CERT", target)); 958 case 38: 959 return (isc_str_tobuffer("A6", target)); 960 case 39: 961 return (isc_str_tobuffer("DNAME", target)); 962 case 40: 963 return (isc_str_tobuffer("SINK", target)); 964 case 41: 965 return (isc_str_tobuffer("OPT", target)); 966 case 42: 967 return (isc_str_tobuffer("APL", target)); 968 case 43: 969 return (isc_str_tobuffer("DS", target)); 970 case 44: 971 return (isc_str_tobuffer("SSHFP", target)); 972 case 45: 973 return (isc_str_tobuffer("IPSECKEY", target)); 974 case 46: 975 return (isc_str_tobuffer("RRSIG", target)); 976 case 47: 977 return (isc_str_tobuffer("NSEC", target)); 978 case 48: 979 return (isc_str_tobuffer("DNSKEY", target)); 980 case 49: 981 return (isc_str_tobuffer("DHCID", target)); 982 case 50: 983 return (isc_str_tobuffer("NSEC3", target)); 984 case 51: 985 return (isc_str_tobuffer("NSEC3PARAM", target)); 986 case 52: 987 return (isc_str_tobuffer("TLSA", target)); 988 case 53: 989 return (isc_str_tobuffer("SMIMEA", target)); 990 case 55: 991 return (isc_str_tobuffer("HIP", target)); 992 case 56: 993 return (isc_str_tobuffer("NINFO", target)); 994 case 57: 995 return (isc_str_tobuffer("RKEY", target)); 996 case 58: 997 return (isc_str_tobuffer("TALINK", target)); 998 case 59: 999 return (isc_str_tobuffer("CDS", target)); 1000 case 60: 1001 return (isc_str_tobuffer("CDNSKEY", target)); 1002 case 61: 1003 return (isc_str_tobuffer("OPENPGPKEY", target)); 1004 case 62: 1005 return (isc_str_tobuffer("CSYNC", target)); 1006 case 99: 1007 return (isc_str_tobuffer("SPF", target)); 1008 case 100: 1009 return (isc_str_tobuffer("UINFO", target)); 1010 case 101: 1011 return (isc_str_tobuffer("UID", target)); 1012 case 102: 1013 return (isc_str_tobuffer("GID", target)); 1014 case 103: 1015 return (isc_str_tobuffer("UNSPEC", target)); 1016 case 104: 1017 return (isc_str_tobuffer("NID", target)); 1018 case 105: 1019 return (isc_str_tobuffer("L32", target)); 1020 case 106: 1021 return (isc_str_tobuffer("L64", target)); 1022 case 107: 1023 return (isc_str_tobuffer("LP", target)); 1024 case 108: 1025 return (isc_str_tobuffer("EUI48", target)); 1026 case 109: 1027 return (isc_str_tobuffer("EUI64", target)); 1028 case 249: 1029 return (isc_str_tobuffer("TKEY", target)); 1030 case 250: 1031 return (isc_str_tobuffer("TSIG", target)); 1032 case 251: 1033 return (isc_str_tobuffer("IXFR", target)); 1034 case 252: 1035 return (isc_str_tobuffer("AXFR", target)); 1036 case 253: 1037 return (isc_str_tobuffer("MAILB", target)); 1038 case 254: 1039 return (isc_str_tobuffer("MAILA", target)); 1040 case 255: 1041 return (isc_str_tobuffer("ANY", target)); 1042 case 256: 1043 return (isc_str_tobuffer("URI", target)); 1044 case 257: 1045 return (isc_str_tobuffer("CAA", target)); 1046 case 258: 1047 return (isc_str_tobuffer("AVC", target)); 1048 case 259: 1049 return (isc_str_tobuffer("DOA", target)); 1050 case 32768: 1051 return (isc_str_tobuffer("TA", target)); 1052 case 32769: 1053 return (isc_str_tobuffer("DLV", target)); 1054 default: 1055 snprintf(buf, sizeof(buf), "TYPE%u", type); 1056 return (isc_str_tobuffer(buf, target)); 1057 } 1058 } 1059 1060 void 1061 dns_rdatatype_format(dns_rdatatype_t rdtype, 1062 char *array, unsigned int size) 1063 { 1064 isc_result_t result; 1065 isc_buffer_t buf; 1066 1067 if (size == 0U) 1068 return; 1069 1070 isc_buffer_init(&buf, array, size); 1071 result = dns_rdatatype_totext(rdtype, &buf); 1072 /* 1073 * Null terminate. 1074 */ 1075 if (result == ISC_R_SUCCESS) { 1076 if (isc_buffer_availablelength(&buf) >= 1) 1077 isc_buffer_putuint8(&buf, 0); 1078 else 1079 result = ISC_R_NOSPACE; 1080 } 1081 if (result != ISC_R_SUCCESS) 1082 strlcpy(array, "<unknown>", size); 1083 } 1084 1085 /* 1086 * Private function. 1087 */ 1088 1089 static unsigned int 1090 name_length(dns_name_t *name) { 1091 return (name->length); 1092 } 1093 1094 static isc_result_t 1095 txt_totext(isc_region_t *source, int quote, isc_buffer_t *target) { 1096 unsigned int tl; 1097 unsigned int n; 1098 unsigned char *sp; 1099 char *tp; 1100 isc_region_t region; 1101 1102 isc_buffer_availableregion(target, ®ion); 1103 sp = source->base; 1104 tp = (char *)region.base; 1105 tl = region.length; 1106 1107 n = *sp++; 1108 1109 REQUIRE(n + 1 <= source->length); 1110 if (n == 0U) 1111 REQUIRE(quote); 1112 1113 if (quote) { 1114 if (tl < 1) 1115 return (ISC_R_NOSPACE); 1116 *tp++ = '"'; 1117 tl--; 1118 } 1119 while (n--) { 1120 /* 1121 * \DDD space (0x20) if not quoting. 1122 */ 1123 if (*sp < (quote ? 0x20 : 0x21) || *sp >= 0x7f) { 1124 if (tl < 4) 1125 return (ISC_R_NOSPACE); 1126 *tp++ = 0x5c; 1127 *tp++ = 0x30 + ((*sp / 100) % 10); 1128 *tp++ = 0x30 + ((*sp / 10) % 10); 1129 *tp++ = 0x30 + (*sp % 10); 1130 sp++; 1131 tl -= 4; 1132 continue; 1133 } 1134 /* 1135 * Escape double quote and backslash. If we are not 1136 * enclosing the string in double quotes also escape 1137 * at sign and semicolon. 1138 */ 1139 if (*sp == 0x22 || *sp == 0x5c || 1140 (!quote && (*sp == 0x40 || *sp == 0x3b))) { 1141 if (tl < 2) 1142 return (ISC_R_NOSPACE); 1143 *tp++ = '\\'; 1144 tl--; 1145 } 1146 if (tl < 1) 1147 return (ISC_R_NOSPACE); 1148 *tp++ = *sp++; 1149 tl--; 1150 } 1151 if (quote) { 1152 if (tl < 1) 1153 return (ISC_R_NOSPACE); 1154 *tp++ = '"'; 1155 tl--; 1156 POST(tl); 1157 } 1158 isc_buffer_add(target, (unsigned int)(tp - (char *)region.base)); 1159 isc_region_consume(source, *source->base + 1); 1160 return (ISC_R_SUCCESS); 1161 } 1162 1163 static isc_result_t 1164 txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) { 1165 unsigned int n; 1166 isc_region_t sregion; 1167 isc_region_t tregion; 1168 1169 isc_buffer_activeregion(source, &sregion); 1170 if (sregion.length == 0) 1171 return (ISC_R_UNEXPECTEDEND); 1172 n = *sregion.base + 1; 1173 if (n > sregion.length) 1174 return (ISC_R_UNEXPECTEDEND); 1175 1176 isc_buffer_availableregion(target, &tregion); 1177 if (n > tregion.length) 1178 return (ISC_R_NOSPACE); 1179 1180 if (tregion.base != sregion.base) 1181 memmove(tregion.base, sregion.base, n); 1182 isc_buffer_forward(source, n); 1183 isc_buffer_add(target, n); 1184 return (ISC_R_SUCCESS); 1185 } 1186 1187 /* 1188 * Conversion of TXT-like rdata fields without length limits. 1189 */ 1190 static isc_result_t 1191 multitxt_totext(isc_region_t *source, isc_buffer_t *target) { 1192 unsigned int tl; 1193 unsigned int n0, n; 1194 unsigned char *sp; 1195 char *tp; 1196 isc_region_t region; 1197 1198 isc_buffer_availableregion(target, ®ion); 1199 sp = source->base; 1200 tp = (char *)region.base; 1201 tl = region.length; 1202 1203 if (tl < 1) 1204 return (ISC_R_NOSPACE); 1205 *tp++ = '"'; 1206 tl--; 1207 do { 1208 n = source->length; 1209 n0 = source->length - 1; 1210 1211 while (n--) { 1212 if (*sp < 0x20 || *sp >= 0x7f) { 1213 if (tl < 4) 1214 return (ISC_R_NOSPACE); 1215 *tp++ = 0x5c; 1216 *tp++ = 0x30 + ((*sp / 100) % 10); 1217 *tp++ = 0x30 + ((*sp / 10) % 10); 1218 *tp++ = 0x30 + (*sp % 10); 1219 sp++; 1220 tl -= 4; 1221 continue; 1222 } 1223 /* double quote, backslash */ 1224 if (*sp == 0x22 || *sp == 0x5c) { 1225 if (tl < 2) 1226 return (ISC_R_NOSPACE); 1227 *tp++ = '\\'; 1228 tl--; 1229 } 1230 if (tl < 1) 1231 return (ISC_R_NOSPACE); 1232 *tp++ = *sp++; 1233 tl--; 1234 } 1235 isc_region_consume(source, n0 + 1); 1236 } while (source->length != 0); 1237 if (tl < 1) 1238 return (ISC_R_NOSPACE); 1239 *tp++ = '"'; 1240 tl--; 1241 POST(tl); 1242 isc_buffer_add(target, (unsigned int)(tp - (char *)region.base)); 1243 return (ISC_R_SUCCESS); 1244 } 1245 1246 static int 1247 name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) { 1248 int l1, l2; 1249 1250 if (origin == NULL) 1251 goto return_false; 1252 1253 if (dns_name_compare(origin, dns_rootname) == 0) 1254 goto return_false; 1255 1256 if (!dns_name_issubdomain(name, origin)) 1257 goto return_false; 1258 1259 l1 = dns_name_countlabels(name); 1260 l2 = dns_name_countlabels(origin); 1261 1262 if (l1 == l2) 1263 goto return_false; 1264 1265 /* Master files should be case preserving. */ 1266 dns_name_getlabelsequence(name, l1 - l2, l2, target); 1267 if (!dns_name_caseequal(origin, target)) 1268 goto return_false; 1269 1270 dns_name_getlabelsequence(name, 0, l1 - l2, target); 1271 return (1); 1272 1273 return_false: 1274 *target = *name; 1275 return (0); 1276 } 1277 1278 static isc_result_t 1279 inet_totext(int af, isc_region_t *src, isc_buffer_t *target) { 1280 char tmpbuf[64]; 1281 1282 /* Note - inet_ntop doesn't do size checking on its input. */ 1283 if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL) 1284 return (ISC_R_NOSPACE); 1285 if (strlen(tmpbuf) > isc_buffer_availablelength(target)) 1286 return (ISC_R_NOSPACE); 1287 isc_buffer_putstr(target, tmpbuf); 1288 return (ISC_R_SUCCESS); 1289 } 1290 1291 static int 1292 buffer_empty(isc_buffer_t *source) { 1293 return((source->current == source->active) ? 1 : 0); 1294 } 1295 1296 static isc_result_t 1297 uint32_tobuffer(uint32_t value, isc_buffer_t *target) { 1298 isc_region_t region; 1299 1300 isc_buffer_availableregion(target, ®ion); 1301 if (region.length < 4) 1302 return (ISC_R_NOSPACE); 1303 isc_buffer_putuint32(target, value); 1304 return (ISC_R_SUCCESS); 1305 } 1306 1307 static isc_result_t 1308 uint16_tobuffer(uint32_t value, isc_buffer_t *target) { 1309 isc_region_t region; 1310 1311 if (value > 0xffff) 1312 return (ISC_R_RANGE); 1313 isc_buffer_availableregion(target, ®ion); 1314 if (region.length < 2) 1315 return (ISC_R_NOSPACE); 1316 isc_buffer_putuint16(target, (uint16_t)value); 1317 return (ISC_R_SUCCESS); 1318 } 1319 1320 static isc_result_t 1321 name_tobuffer(dns_name_t *name, isc_buffer_t *target) { 1322 isc_region_t r; 1323 dns_name_toregion(name, &r); 1324 return (isc_buffer_copyregion(target, &r)); 1325 } 1326 1327 static uint32_t 1328 uint32_fromregion(isc_region_t *region) { 1329 uint32_t value; 1330 1331 REQUIRE(region->length >= 4); 1332 value = region->base[0] << 24; 1333 value |= region->base[1] << 16; 1334 value |= region->base[2] << 8; 1335 value |= region->base[3]; 1336 return(value); 1337 } 1338 1339 static uint16_t 1340 uint16_fromregion(isc_region_t *region) { 1341 1342 REQUIRE(region->length >= 2); 1343 1344 return ((region->base[0] << 8) | region->base[1]); 1345 } 1346 1347 static uint8_t 1348 uint8_fromregion(isc_region_t *region) { 1349 1350 REQUIRE(region->length >= 1); 1351 1352 return (region->base[0]); 1353 } 1354 1355 static uint8_t 1356 uint8_consume_fromregion(isc_region_t *region) { 1357 uint8_t r = uint8_fromregion(region); 1358 1359 isc_region_consume(region, 1); 1360 return r; 1361 } 1362 1363 static const char atob_digits[86] = 1364 "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \ 1365 "abcdefghijklmnopqrstu"; 1366 /* 1367 * Subroutines to convert between 8 bit binary bytes and printable ASCII. 1368 * Computes the number of bytes, and three kinds of simple checksums. 1369 * Incoming bytes are collected into 32-bit words, then printed in base 85: 1370 * exp(85,5) > exp(2,32) 1371 * The ASCII characters used are between '!' and 'u'; 1372 * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data. 1373 * 1374 * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for 1375 * the atob/btoa programs, released with the compress program, in mod.sources. 1376 * Modified by Mike Schwartz 8/19/86 for use in BIND. 1377 * Modified to be re-entrant 3/2/99. 1378 */ 1379 1380 struct state { 1381 int32_t Ceor; 1382 int32_t Csum; 1383 int32_t Crot; 1384 int32_t word; 1385 int32_t bcount; 1386 }; 1387 1388 #define Ceor state->Ceor 1389 #define Csum state->Csum 1390 #define Crot state->Crot 1391 #define word state->word 1392 #define bcount state->bcount 1393 1394 static isc_result_t byte_btoa(int c, isc_buffer_t *, struct state *state); 1395 1396 /* 1397 * Encode binary byte c into ASCII representation and place into *bufp, 1398 * advancing bufp. 1399 */ 1400 static isc_result_t 1401 byte_btoa(int c, isc_buffer_t *target, struct state *state) { 1402 isc_region_t tr; 1403 1404 isc_buffer_availableregion(target, &tr); 1405 Ceor ^= c; 1406 Csum += c; 1407 Csum += 1; 1408 if ((Crot & 0x80000000)) { 1409 Crot <<= 1; 1410 Crot += 1; 1411 } else { 1412 Crot <<= 1; 1413 } 1414 Crot += c; 1415 1416 word <<= 8; 1417 word |= c; 1418 if (bcount == 3) { 1419 if (word == 0) { 1420 if (tr.length < 1) 1421 return (ISC_R_NOSPACE); 1422 tr.base[0] = 'z'; 1423 isc_buffer_add(target, 1); 1424 } else { 1425 register int tmp = 0; 1426 register int32_t tmpword = word; 1427 1428 if (tmpword < 0) { 1429 /* 1430 * Because some don't support u_long. 1431 */ 1432 tmp = 32; 1433 tmpword -= (int32_t)(85 * 85 * 85 * 85 * 32); 1434 } 1435 if (tmpword < 0) { 1436 tmp = 64; 1437 tmpword -= (int32_t)(85 * 85 * 85 * 85 * 32); 1438 } 1439 if (tr.length < 5) 1440 return (ISC_R_NOSPACE); 1441 tr.base[0] = atob_digits[(tmpword / 1442 (int32_t)(85 * 85 * 85 * 85)) 1443 + tmp]; 1444 tmpword %= (int32_t)(85 * 85 * 85 * 85); 1445 tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)]; 1446 tmpword %= (85 * 85 * 85); 1447 tr.base[2] = atob_digits[tmpword / (85 * 85)]; 1448 tmpword %= (85 * 85); 1449 tr.base[3] = atob_digits[tmpword / 85]; 1450 tmpword %= 85; 1451 tr.base[4] = atob_digits[tmpword]; 1452 isc_buffer_add(target, 5); 1453 } 1454 bcount = 0; 1455 } else { 1456 bcount += 1; 1457 } 1458 return (ISC_R_SUCCESS); 1459 } 1460 1461 /* 1462 * Encode the binary data from inbuf, of length inbuflen, into a 1463 * target. Return success/failure status 1464 */ 1465 static isc_result_t 1466 btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) { 1467 int inc; 1468 struct state statebuf, *state = &statebuf; 1469 char buf[sizeof("x 2000000000 ffffffff ffffffff ffffffff")]; 1470 1471 Ceor = Csum = Crot = word = bcount = 0; 1472 for (inc = 0; inc < inbuflen; inbuf++, inc++) 1473 RETERR(byte_btoa(*inbuf, target, state)); 1474 1475 while (bcount != 0) 1476 RETERR(byte_btoa(0, target, state)); 1477 1478 /* 1479 * Put byte count and checksum information at end of buffer, 1480 * delimited by 'x' 1481 */ 1482 snprintf(buf, sizeof(buf), "x %d %x %x %x", inbuflen, Ceor, Csum, Crot); 1483 return (isc_str_tobuffer(buf, target)); 1484 } 1485 1486 dns_rdatatype_t 1487 dns_rdata_covers(dns_rdata_t *rdata) { 1488 if (rdata->type == dns_rdatatype_rrsig) 1489 return (covers_rrsig(rdata)); 1490 return (covers_sig(rdata)); 1491 } 1492