1 /* 2 * rdata.c -- RDATA conversion functions. 3 * 4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 10 #include "config.h" 11 12 #include <sys/types.h> 13 #include <sys/socket.h> 14 #include <netinet/in.h> 15 #include <arpa/inet.h> 16 #include <ctype.h> 17 #include <netdb.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #ifdef HAVE_STRINGS_H 21 #include <strings.h> 22 #endif 23 24 #include "rdata.h" 25 #include "zonec.h" 26 27 /* Taken from RFC 4398, section 2.1. */ 28 lookup_table_type dns_certificate_types[] = { 29 /* 0 Reserved */ 30 { 1, "PKIX" }, /* X.509 as per PKIX */ 31 { 2, "SPKI" }, /* SPKI cert */ 32 { 3, "PGP" }, /* OpenPGP packet */ 33 { 4, "IPKIX" }, /* The URL of an X.509 data object */ 34 { 5, "ISPKI" }, /* The URL of an SPKI certificate */ 35 { 6, "IPGP" }, /* The fingerprint and URL of an OpenPGP packet */ 36 { 7, "ACPKIX" }, /* Attribute Certificate */ 37 { 8, "IACPKIX" }, /* The URL of an Attribute Certificate */ 38 { 253, "URI" }, /* URI private */ 39 { 254, "OID" }, /* OID private */ 40 /* 255 Reserved */ 41 /* 256-65279 Available for IANA assignment */ 42 /* 65280-65534 Experimental */ 43 /* 65535 Reserved */ 44 { 0, NULL } 45 }; 46 47 /* Taken from RFC 2535, section 7. */ 48 lookup_table_type dns_algorithms[] = { 49 { 1, "RSAMD5" }, /* RFC 2537 */ 50 { 2, "DH" }, /* RFC 2539 */ 51 { 3, "DSA" }, /* RFC 2536 */ 52 { 4, "ECC" }, 53 { 5, "RSASHA1" }, /* RFC 3110 */ 54 { 6, "DSA-NSEC3-SHA1" }, /* RFC 5155 */ 55 { 7, "RSASHA1-NSEC3-SHA1" }, /* RFC 5155 */ 56 { 8, "RSASHA256" }, /* RFC 5702 */ 57 { 10, "RSASHA512" }, /* RFC 5702 */ 58 { 12, "ECC-GOST" }, /* RFC 5933 */ 59 { 13, "ECDSAP256SHA256" }, /* RFC 6605 */ 60 { 14, "ECDSAP384SHA384" }, /* RFC 6605 */ 61 { 252, "INDIRECT" }, 62 { 253, "PRIVATEDNS" }, 63 { 254, "PRIVATEOID" }, 64 { 0, NULL } 65 }; 66 67 typedef int (*rdata_to_string_type)(buffer_type *output, 68 rdata_atom_type rdata, 69 rr_type *rr); 70 71 static int 72 rdata_dname_to_string(buffer_type *output, rdata_atom_type rdata, 73 rr_type* ATTR_UNUSED(rr)) 74 { 75 buffer_printf(output, 76 "%s", 77 dname_to_string(domain_dname(rdata_atom_domain(rdata)), 78 NULL)); 79 return 1; 80 } 81 82 static int 83 rdata_dns_name_to_string(buffer_type *output, rdata_atom_type rdata, 84 rr_type* ATTR_UNUSED(rr)) 85 { 86 const uint8_t *data = rdata_atom_data(rdata); 87 size_t offset = 0; 88 uint8_t length = data[offset]; 89 size_t i; 90 91 while (length > 0) 92 { 93 if (offset) /* concat label */ 94 buffer_printf(output, "."); 95 96 for (i = 1; i <= length; ++i) { 97 uint8_t ch = data[i+offset]; 98 99 if (ch=='.' || ch==';' || ch=='(' || ch==')' || ch=='\\') { 100 buffer_printf(output, "\\%c", (char) ch); 101 } else if (!isgraph((int)(unsigned char) ch)) { 102 buffer_printf(output, "\\%03u", (unsigned int) ch); 103 } else if (isprint((int)(unsigned char) ch)) { 104 buffer_printf(output, "%c", (char) ch); 105 } else { 106 buffer_printf(output, "\\%03u", (unsigned int) ch); 107 } 108 } 109 /* next label */ 110 offset = offset+length+1; 111 length = data[offset]; 112 } 113 114 /* root label */ 115 buffer_printf(output, "."); 116 return 1; 117 } 118 119 static int 120 rdata_text_to_string(buffer_type *output, rdata_atom_type rdata, 121 rr_type* ATTR_UNUSED(rr)) 122 { 123 const uint8_t *data = rdata_atom_data(rdata); 124 uint8_t length = data[0]; 125 size_t i; 126 127 buffer_printf(output, "\""); 128 for (i = 1; i <= length; ++i) { 129 char ch = (char) data[i]; 130 if (isprint((int)(unsigned char)ch)) { 131 if (ch == '"' || ch == '\\') { 132 buffer_printf(output, "\\"); 133 } 134 buffer_printf(output, "%c", ch); 135 } else { 136 buffer_printf(output, "\\%03u", (unsigned) data[i]); 137 } 138 } 139 buffer_printf(output, "\""); 140 return 1; 141 } 142 143 static int 144 rdata_texts_to_string(buffer_type *output, rdata_atom_type rdata, 145 rr_type* ATTR_UNUSED(rr)) 146 { 147 uint16_t pos = 0; 148 const uint8_t *data = rdata_atom_data(rdata); 149 uint16_t length = rdata_atom_size(rdata); 150 size_t i; 151 152 while (pos < length && pos + data[pos] < length) { 153 buffer_printf(output, "\""); 154 for (i = 1; i <= data[pos]; ++i) { 155 char ch = (char) data[pos + i]; 156 if (isprint((int)(unsigned char)ch)) { 157 if (ch == '"' || ch == '\\') { 158 buffer_printf(output, "\\"); 159 } 160 buffer_printf(output, "%c", ch); 161 } else { 162 buffer_printf(output, "\\%03u", (unsigned) data[pos+i]); 163 } 164 } 165 pos += data[pos]+1; 166 buffer_printf(output, pos < length?"\" ":"\""); 167 } 168 return 1; 169 } 170 171 static int 172 rdata_long_text_to_string(buffer_type *output, rdata_atom_type rdata, 173 rr_type* ATTR_UNUSED(rr)) 174 { 175 const uint8_t *data = rdata_atom_data(rdata); 176 uint16_t length = rdata_atom_size(rdata); 177 size_t i; 178 179 buffer_printf(output, "\""); 180 for (i = 0; i < length; ++i) { 181 char ch = (char) data[i]; 182 if (isprint((int)(unsigned char)ch)) { 183 if (ch == '"' || ch == '\\') { 184 buffer_printf(output, "\\"); 185 } 186 buffer_printf(output, "%c", ch); 187 } else { 188 buffer_printf(output, "\\%03u", (unsigned) data[i]); 189 } 190 } 191 buffer_printf(output, "\""); 192 return 1; 193 } 194 195 static int 196 rdata_tag_to_string(buffer_type *output, rdata_atom_type rdata, 197 rr_type* ATTR_UNUSED(rr)) 198 { 199 const uint8_t *data = rdata_atom_data(rdata); 200 uint8_t length = data[0]; 201 size_t i; 202 for (i = 1; i <= length; ++i) { 203 char ch = (char) data[i]; 204 if (isdigit((int)ch) || islower((int)ch)) 205 buffer_printf(output, "%c", ch); 206 else return 0; 207 } 208 return 1; 209 } 210 211 static int 212 rdata_byte_to_string(buffer_type *output, rdata_atom_type rdata, 213 rr_type* ATTR_UNUSED(rr)) 214 { 215 uint8_t data = *rdata_atom_data(rdata); 216 buffer_printf(output, "%lu", (unsigned long) data); 217 return 1; 218 } 219 220 static int 221 rdata_short_to_string(buffer_type *output, rdata_atom_type rdata, 222 rr_type* ATTR_UNUSED(rr)) 223 { 224 uint16_t data = read_uint16(rdata_atom_data(rdata)); 225 buffer_printf(output, "%lu", (unsigned long) data); 226 return 1; 227 } 228 229 static int 230 rdata_long_to_string(buffer_type *output, rdata_atom_type rdata, 231 rr_type* ATTR_UNUSED(rr)) 232 { 233 uint32_t data = read_uint32(rdata_atom_data(rdata)); 234 buffer_printf(output, "%lu", (unsigned long) data); 235 return 1; 236 } 237 238 static int 239 rdata_a_to_string(buffer_type *output, rdata_atom_type rdata, 240 rr_type* ATTR_UNUSED(rr)) 241 { 242 int result = 0; 243 char str[200]; 244 if (inet_ntop(AF_INET, rdata_atom_data(rdata), str, sizeof(str))) { 245 buffer_printf(output, "%s", str); 246 result = 1; 247 } 248 return result; 249 } 250 251 static int 252 rdata_aaaa_to_string(buffer_type *output, rdata_atom_type rdata, 253 rr_type* ATTR_UNUSED(rr)) 254 { 255 int result = 0; 256 char str[200]; 257 if (inet_ntop(AF_INET6, rdata_atom_data(rdata), str, sizeof(str))) { 258 buffer_printf(output, "%s", str); 259 result = 1; 260 } 261 return result; 262 } 263 264 static int 265 rdata_ilnp64_to_string(buffer_type *output, rdata_atom_type rdata, 266 rr_type* ATTR_UNUSED(rr)) 267 { 268 uint8_t* data = rdata_atom_data(rdata); 269 uint16_t a1 = read_uint16(data); 270 uint16_t a2 = read_uint16(data+2); 271 uint16_t a3 = read_uint16(data+4); 272 uint16_t a4 = read_uint16(data+6); 273 274 buffer_printf(output, "%.4x:%.4x:%.4x:%.4x", a1, a2, a3, a4); 275 return 1; 276 } 277 278 static int 279 rdata_eui48_to_string(buffer_type *output, rdata_atom_type rdata, 280 rr_type* ATTR_UNUSED(rr)) 281 { 282 uint8_t* data = rdata_atom_data(rdata); 283 uint8_t a1 = data[0]; 284 uint8_t a2 = data[1]; 285 uint8_t a3 = data[2]; 286 uint8_t a4 = data[3]; 287 uint8_t a5 = data[4]; 288 uint8_t a6 = data[5]; 289 290 buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", 291 a1, a2, a3, a4, a5, a6); 292 return 1; 293 } 294 295 static int 296 rdata_eui64_to_string(buffer_type *output, rdata_atom_type rdata, 297 rr_type* ATTR_UNUSED(rr)) 298 { 299 uint8_t* data = rdata_atom_data(rdata); 300 uint8_t a1 = data[0]; 301 uint8_t a2 = data[1]; 302 uint8_t a3 = data[2]; 303 uint8_t a4 = data[3]; 304 uint8_t a5 = data[4]; 305 uint8_t a6 = data[5]; 306 uint8_t a7 = data[6]; 307 uint8_t a8 = data[7]; 308 309 buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", 310 a1, a2, a3, a4, a5, a6, a7, a8); 311 return 1; 312 } 313 314 static int 315 rdata_rrtype_to_string(buffer_type *output, rdata_atom_type rdata, 316 rr_type* ATTR_UNUSED(rr)) 317 { 318 uint16_t type = read_uint16(rdata_atom_data(rdata)); 319 buffer_printf(output, "%s", rrtype_to_string(type)); 320 return 1; 321 } 322 323 static int 324 rdata_algorithm_to_string(buffer_type *output, rdata_atom_type rdata, 325 rr_type* ATTR_UNUSED(rr)) 326 { 327 uint8_t id = *rdata_atom_data(rdata); 328 buffer_printf(output, "%u", (unsigned) id); 329 return 1; 330 } 331 332 static int 333 rdata_certificate_type_to_string(buffer_type *output, rdata_atom_type rdata, 334 rr_type* ATTR_UNUSED(rr)) 335 { 336 uint16_t id = read_uint16(rdata_atom_data(rdata)); 337 lookup_table_type *type 338 = lookup_by_id(dns_certificate_types, id); 339 if (type) { 340 buffer_printf(output, "%s", type->name); 341 } else { 342 buffer_printf(output, "%u", (unsigned) id); 343 } 344 return 1; 345 } 346 347 static int 348 rdata_period_to_string(buffer_type *output, rdata_atom_type rdata, 349 rr_type* ATTR_UNUSED(rr)) 350 { 351 uint32_t period = read_uint32(rdata_atom_data(rdata)); 352 buffer_printf(output, "%lu", (unsigned long) period); 353 return 1; 354 } 355 356 static int 357 rdata_time_to_string(buffer_type *output, rdata_atom_type rdata, 358 rr_type* ATTR_UNUSED(rr)) 359 { 360 int result = 0; 361 time_t time = (time_t) read_uint32(rdata_atom_data(rdata)); 362 struct tm *tm = gmtime(&time); 363 char buf[15]; 364 if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", tm)) { 365 buffer_printf(output, "%s", buf); 366 result = 1; 367 } 368 return result; 369 } 370 371 static int 372 rdata_base32_to_string(buffer_type *output, rdata_atom_type rdata, 373 rr_type* ATTR_UNUSED(rr)) 374 { 375 int length; 376 size_t size = rdata_atom_size(rdata); 377 if(size == 0) { 378 buffer_write(output, "-", 1); 379 return 1; 380 } 381 size -= 1; /* remove length byte from count */ 382 buffer_reserve(output, size * 2 + 1); 383 length = b32_ntop(rdata_atom_data(rdata)+1, size, 384 (char *) buffer_current(output), size * 2); 385 if (length > 0) { 386 buffer_skip(output, length); 387 } 388 return length != -1; 389 } 390 391 static int 392 rdata_base64_to_string(buffer_type *output, rdata_atom_type rdata, 393 rr_type* ATTR_UNUSED(rr)) 394 { 395 int length; 396 size_t size = rdata_atom_size(rdata); 397 if(size == 0) 398 return 1; 399 buffer_reserve(output, size * 2 + 1); 400 length = b64_ntop(rdata_atom_data(rdata), size, 401 (char *) buffer_current(output), size * 2); 402 if (length > 0) { 403 buffer_skip(output, length); 404 } 405 return length != -1; 406 } 407 408 static void 409 hex_to_string(buffer_type *output, const uint8_t *data, size_t size) 410 { 411 static const char hexdigits[] = { 412 '0', '1', '2', '3', '4', '5', '6', '7', 413 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 414 }; 415 size_t i; 416 417 buffer_reserve(output, size * 2); 418 for (i = 0; i < size; ++i) { 419 uint8_t octet = *data++; 420 buffer_write_u8(output, hexdigits[octet >> 4]); 421 buffer_write_u8(output, hexdigits[octet & 0x0f]); 422 } 423 } 424 425 static int 426 rdata_hex_to_string(buffer_type *output, rdata_atom_type rdata, 427 rr_type* ATTR_UNUSED(rr)) 428 { 429 hex_to_string(output, rdata_atom_data(rdata), rdata_atom_size(rdata)); 430 return 1; 431 } 432 433 static int 434 rdata_hexlen_to_string(buffer_type *output, rdata_atom_type rdata, 435 rr_type* ATTR_UNUSED(rr)) 436 { 437 if(rdata_atom_size(rdata) <= 1) { 438 /* NSEC3 salt hex can be empty */ 439 buffer_printf(output, "-"); 440 return 1; 441 } 442 hex_to_string(output, rdata_atom_data(rdata)+1, rdata_atom_size(rdata)-1); 443 return 1; 444 } 445 446 static int 447 rdata_nsap_to_string(buffer_type *output, rdata_atom_type rdata, 448 rr_type* ATTR_UNUSED(rr)) 449 { 450 buffer_printf(output, "0x"); 451 hex_to_string(output, rdata_atom_data(rdata), rdata_atom_size(rdata)); 452 return 1; 453 } 454 455 static int 456 rdata_apl_to_string(buffer_type *output, rdata_atom_type rdata, 457 rr_type* ATTR_UNUSED(rr)) 458 { 459 int result = 0; 460 buffer_type packet; 461 462 buffer_create_from( 463 &packet, rdata_atom_data(rdata), rdata_atom_size(rdata)); 464 465 if (buffer_available(&packet, 4)) { 466 uint16_t address_family = buffer_read_u16(&packet); 467 uint8_t prefix = buffer_read_u8(&packet); 468 uint8_t length = buffer_read_u8(&packet); 469 int negated = length & APL_NEGATION_MASK; 470 int af = -1; 471 472 length &= APL_LENGTH_MASK; 473 switch (address_family) { 474 case 1: af = AF_INET; break; 475 case 2: af = AF_INET6; break; 476 } 477 if (af != -1 && buffer_available(&packet, length)) { 478 char text_address[1000]; 479 uint8_t address[128]; 480 memset(address, 0, sizeof(address)); 481 buffer_read(&packet, address, length); 482 if (inet_ntop(af, address, text_address, sizeof(text_address))) { 483 buffer_printf(output, "%s%d:%s/%d", 484 negated ? "!" : "", 485 (int) address_family, 486 text_address, 487 (int) prefix); 488 result = 1; 489 } 490 } 491 } 492 return result; 493 } 494 495 static int 496 rdata_services_to_string(buffer_type *output, rdata_atom_type rdata, 497 rr_type* ATTR_UNUSED(rr)) 498 { 499 int result = 0; 500 buffer_type packet; 501 502 buffer_create_from( 503 &packet, rdata_atom_data(rdata), rdata_atom_size(rdata)); 504 505 if (buffer_available(&packet, 1)) { 506 uint8_t protocol_number = buffer_read_u8(&packet); 507 ssize_t bitmap_size = buffer_remaining(&packet); 508 uint8_t *bitmap = buffer_current(&packet); 509 struct protoent *proto = getprotobynumber(protocol_number); 510 511 if (proto) { 512 int i; 513 514 buffer_printf(output, "%s", proto->p_name); 515 516 for (i = 0; i < bitmap_size * 8; ++i) { 517 if (get_bit(bitmap, i)) { 518 struct servent *service = getservbyport((int)htons(i), proto->p_name); 519 if (service) { 520 buffer_printf(output, " %s", service->s_name); 521 } else { 522 buffer_printf(output, " %d", i); 523 } 524 } 525 } 526 buffer_skip(&packet, bitmap_size); 527 result = 1; 528 } 529 } 530 return result; 531 } 532 533 static int 534 rdata_ipsecgateway_to_string(buffer_type *output, rdata_atom_type rdata, rr_type* rr) 535 { 536 int gateway_type = rdata_atom_data(rr->rdatas[1])[0]; 537 switch(gateway_type) { 538 case IPSECKEY_NOGATEWAY: 539 buffer_printf(output, "."); 540 break; 541 case IPSECKEY_IP4: 542 rdata_a_to_string(output, rdata, rr); 543 break; 544 case IPSECKEY_IP6: 545 rdata_aaaa_to_string(output, rdata, rr); 546 break; 547 case IPSECKEY_DNAME: 548 { 549 region_type* temp = region_create(xalloc, free); 550 const dname_type* d = dname_make(temp, 551 rdata_atom_data(rdata), 0); 552 if(!d) { 553 region_destroy(temp); 554 return 0; 555 } 556 buffer_printf(output, "%s", dname_to_string(d, NULL)); 557 region_destroy(temp); 558 } 559 break; 560 default: 561 return 0; 562 } 563 return 1; 564 } 565 566 static int 567 rdata_nxt_to_string(buffer_type *output, rdata_atom_type rdata, 568 rr_type* ATTR_UNUSED(rr)) 569 { 570 size_t i; 571 uint8_t *bitmap = rdata_atom_data(rdata); 572 size_t bitmap_size = rdata_atom_size(rdata); 573 574 for (i = 0; i < bitmap_size * 8; ++i) { 575 if (get_bit(bitmap, i)) { 576 buffer_printf(output, "%s ", rrtype_to_string(i)); 577 } 578 } 579 580 buffer_skip(output, -1); 581 582 return 1; 583 } 584 585 static int 586 rdata_nsec_to_string(buffer_type *output, rdata_atom_type rdata, 587 rr_type* ATTR_UNUSED(rr)) 588 { 589 size_t saved_position = buffer_position(output); 590 buffer_type packet; 591 int insert_space = 0; 592 593 buffer_create_from( 594 &packet, rdata_atom_data(rdata), rdata_atom_size(rdata)); 595 596 while (buffer_available(&packet, 2)) { 597 uint8_t window = buffer_read_u8(&packet); 598 uint8_t bitmap_size = buffer_read_u8(&packet); 599 uint8_t *bitmap = buffer_current(&packet); 600 int i; 601 602 if (!buffer_available(&packet, bitmap_size)) { 603 buffer_set_position(output, saved_position); 604 return 0; 605 } 606 607 for (i = 0; i < bitmap_size * 8; ++i) { 608 if (get_bit(bitmap, i)) { 609 buffer_printf(output, 610 "%s%s", 611 insert_space ? " " : "", 612 rrtype_to_string( 613 window * 256 + i)); 614 insert_space = 1; 615 } 616 } 617 buffer_skip(&packet, bitmap_size); 618 } 619 620 return 1; 621 } 622 623 static int 624 rdata_loc_to_string(buffer_type *ATTR_UNUSED(output), 625 rdata_atom_type ATTR_UNUSED(rdata), 626 rr_type* ATTR_UNUSED(rr)) 627 { 628 /* 629 * Returning 0 forces the record to be printed in unknown 630 * format. 631 */ 632 return 0; 633 } 634 635 static int 636 rdata_unknown_to_string(buffer_type *output, rdata_atom_type rdata, 637 rr_type* ATTR_UNUSED(rr)) 638 { 639 uint16_t size = rdata_atom_size(rdata); 640 buffer_printf(output, "\\# %lu ", (unsigned long) size); 641 hex_to_string(output, rdata_atom_data(rdata), size); 642 return 1; 643 } 644 645 static rdata_to_string_type rdata_to_string_table[RDATA_ZF_UNKNOWN + 1] = { 646 rdata_dname_to_string, 647 rdata_dns_name_to_string, 648 rdata_text_to_string, 649 rdata_texts_to_string, 650 rdata_byte_to_string, 651 rdata_short_to_string, 652 rdata_long_to_string, 653 rdata_a_to_string, 654 rdata_aaaa_to_string, 655 rdata_rrtype_to_string, 656 rdata_algorithm_to_string, 657 rdata_certificate_type_to_string, 658 rdata_period_to_string, 659 rdata_time_to_string, 660 rdata_base64_to_string, 661 rdata_base32_to_string, 662 rdata_hex_to_string, 663 rdata_hexlen_to_string, 664 rdata_nsap_to_string, 665 rdata_apl_to_string, 666 rdata_ipsecgateway_to_string, 667 rdata_services_to_string, 668 rdata_nxt_to_string, 669 rdata_nsec_to_string, 670 rdata_loc_to_string, 671 rdata_ilnp64_to_string, 672 rdata_eui48_to_string, 673 rdata_eui64_to_string, 674 rdata_long_text_to_string, 675 rdata_tag_to_string, 676 rdata_unknown_to_string 677 }; 678 679 int 680 rdata_atom_to_string(buffer_type *output, rdata_zoneformat_type type, 681 rdata_atom_type rdata, rr_type* record) 682 { 683 return rdata_to_string_table[type](output, rdata, record); 684 } 685 686 ssize_t 687 rdata_wireformat_to_rdata_atoms(region_type *region, 688 domain_table_type *owners, 689 uint16_t rrtype, 690 uint16_t data_size, 691 buffer_type *packet, 692 rdata_atom_type **rdatas) 693 { 694 size_t end = buffer_position(packet) + data_size; 695 size_t i; 696 rdata_atom_type temp_rdatas[MAXRDATALEN]; 697 rrtype_descriptor_type *descriptor = rrtype_descriptor_by_type(rrtype); 698 region_type *temp_region; 699 700 assert(descriptor->maximum <= MAXRDATALEN); 701 702 if (!buffer_available(packet, data_size)) { 703 return -1; 704 } 705 706 temp_region = region_create(xalloc, free); 707 708 for (i = 0; i < descriptor->maximum; ++i) { 709 int is_domain = 0; 710 int is_normalized = 0; 711 int is_wirestore = 0; 712 size_t length = 0; 713 int required = i < descriptor->minimum; 714 715 switch (rdata_atom_wireformat_type(rrtype, i)) { 716 case RDATA_WF_COMPRESSED_DNAME: 717 case RDATA_WF_UNCOMPRESSED_DNAME: 718 is_domain = 1; 719 is_normalized = 1; 720 break; 721 case RDATA_WF_LITERAL_DNAME: 722 is_domain = 1; 723 is_wirestore = 1; 724 break; 725 case RDATA_WF_BYTE: 726 length = sizeof(uint8_t); 727 break; 728 case RDATA_WF_SHORT: 729 length = sizeof(uint16_t); 730 break; 731 case RDATA_WF_LONG: 732 length = sizeof(uint32_t); 733 break; 734 case RDATA_WF_TEXTS: 735 case RDATA_WF_LONG_TEXT: 736 length = end - buffer_position(packet); 737 break; 738 case RDATA_WF_TEXT: 739 case RDATA_WF_BINARYWITHLENGTH: 740 /* Length is stored in the first byte. */ 741 length = 1; 742 if (buffer_position(packet) + length <= end) { 743 length += buffer_current(packet)[length - 1]; 744 } 745 break; 746 case RDATA_WF_A: 747 length = sizeof(in_addr_t); 748 break; 749 case RDATA_WF_AAAA: 750 length = IP6ADDRLEN; 751 break; 752 case RDATA_WF_ILNP64: 753 length = IP6ADDRLEN/2; 754 break; 755 case RDATA_WF_EUI48: 756 length = EUI48ADDRLEN; 757 break; 758 case RDATA_WF_EUI64: 759 length = EUI64ADDRLEN; 760 break; 761 case RDATA_WF_BINARY: 762 /* Remaining RDATA is binary. */ 763 length = end - buffer_position(packet); 764 break; 765 case RDATA_WF_APL: 766 length = (sizeof(uint16_t) /* address family */ 767 + sizeof(uint8_t) /* prefix */ 768 + sizeof(uint8_t)); /* length */ 769 if (buffer_position(packet) + length <= end) { 770 /* Mask out negation bit. */ 771 length += (buffer_current(packet)[length - 1] 772 & APL_LENGTH_MASK); 773 } 774 break; 775 case RDATA_WF_IPSECGATEWAY: 776 switch(rdata_atom_data(temp_rdatas[1])[0]) /* gateway type */ { 777 default: 778 case IPSECKEY_NOGATEWAY: 779 length = 0; 780 break; 781 case IPSECKEY_IP4: 782 length = IP4ADDRLEN; 783 break; 784 case IPSECKEY_IP6: 785 length = IP6ADDRLEN; 786 break; 787 case IPSECKEY_DNAME: 788 is_domain = 1; 789 is_normalized = 1; 790 is_wirestore = 1; 791 break; 792 } 793 break; 794 } 795 796 if (is_domain) { 797 const dname_type *dname; 798 799 if (!required && buffer_position(packet) == end) { 800 break; 801 } 802 803 dname = dname_make_from_packet( 804 temp_region, packet, 1, is_normalized); 805 if (!dname || buffer_position(packet) > end) { 806 /* Error in domain name. */ 807 region_destroy(temp_region); 808 return -1; 809 } 810 if(is_wirestore) { 811 temp_rdatas[i].data = (uint16_t *) region_alloc( 812 region, sizeof(uint16_t) + dname->name_size); 813 temp_rdatas[i].data[0] = dname->name_size; 814 memcpy(temp_rdatas[i].data+1, dname_name(dname), 815 dname->name_size); 816 } else { 817 temp_rdatas[i].domain 818 = domain_table_insert(owners, dname); 819 temp_rdatas[i].domain->usage ++; 820 } 821 } else { 822 if (buffer_position(packet) + length > end) { 823 if (required) { 824 /* Truncated RDATA. */ 825 region_destroy(temp_region); 826 return -1; 827 } else { 828 break; 829 } 830 } 831 if (!required && buffer_position(packet) == end) { 832 break; 833 } 834 835 temp_rdatas[i].data = (uint16_t *) region_alloc( 836 region, sizeof(uint16_t) + length); 837 temp_rdatas[i].data[0] = length; 838 buffer_read(packet, temp_rdatas[i].data + 1, length); 839 } 840 } 841 842 if (buffer_position(packet) < end) { 843 /* Trailing garbage. */ 844 region_destroy(temp_region); 845 return -1; 846 } 847 848 *rdatas = (rdata_atom_type *) region_alloc_init( 849 region, temp_rdatas, i * sizeof(rdata_atom_type)); 850 region_destroy(temp_region); 851 return (ssize_t)i; 852 } 853 854 size_t 855 rdata_maximum_wireformat_size(rrtype_descriptor_type *descriptor, 856 size_t rdata_count, 857 rdata_atom_type *rdatas) 858 { 859 size_t result = 0; 860 size_t i; 861 for (i = 0; i < rdata_count; ++i) { 862 if (rdata_atom_is_domain(descriptor->type, i)) { 863 result += domain_dname(rdata_atom_domain(rdatas[i]))->name_size; 864 } else { 865 result += rdata_atom_size(rdatas[i]); 866 } 867 } 868 return result; 869 } 870 871 int 872 rdata_atoms_to_unknown_string(buffer_type *output, 873 rrtype_descriptor_type *descriptor, 874 size_t rdata_count, 875 rdata_atom_type *rdatas) 876 { 877 size_t i; 878 size_t size = 879 rdata_maximum_wireformat_size(descriptor, rdata_count, rdatas); 880 buffer_printf(output, " \\# %lu ", (unsigned long) size); 881 for (i = 0; i < rdata_count; ++i) { 882 if (rdata_atom_is_domain(descriptor->type, i)) { 883 const dname_type *dname = 884 domain_dname(rdata_atom_domain(rdatas[i])); 885 hex_to_string( 886 output, dname_name(dname), dname->name_size); 887 } else { 888 hex_to_string(output, rdata_atom_data(rdatas[i]), 889 rdata_atom_size(rdatas[i])); 890 } 891 } 892 return 1; 893 } 894 895 int 896 print_rdata(buffer_type *output, rrtype_descriptor_type *descriptor, 897 rr_type *record) 898 { 899 size_t i; 900 size_t saved_position = buffer_position(output); 901 902 for (i = 0; i < record->rdata_count; ++i) { 903 if (i == 0) { 904 buffer_printf(output, "\t"); 905 } else if (descriptor->type == TYPE_SOA && i == 2) { 906 buffer_printf(output, " (\n\t\t"); 907 } else { 908 buffer_printf(output, " "); 909 } 910 if (!rdata_atom_to_string( 911 output, 912 (rdata_zoneformat_type) descriptor->zoneformat[i], 913 record->rdatas[i], record)) 914 { 915 buffer_set_position(output, saved_position); 916 return 0; 917 } 918 } 919 if (descriptor->type == TYPE_SOA) { 920 buffer_printf(output, " )"); 921 } 922 923 return 1; 924 } 925 926 927