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