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