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 #include <inttypes.h> 21 #ifdef HAVE_STRINGS_H 22 #include <strings.h> 23 #endif 24 25 #include "rdata.h" 26 #include "zonec.h" 27 #include "query.h" 28 #include "dname.h" 29 30 /* Taken from RFC 4398, section 2.1. */ 31 lookup_table_type dns_certificate_types[] = { 32 /* 0 Reserved */ 33 { 1, "PKIX" }, /* X.509 as per PKIX */ 34 { 2, "SPKI" }, /* SPKI cert */ 35 { 3, "PGP" }, /* OpenPGP packet */ 36 { 4, "IPKIX" }, /* The URL of an X.509 data object */ 37 { 5, "ISPKI" }, /* The URL of an SPKI certificate */ 38 { 6, "IPGP" }, /* The fingerprint and URL of an OpenPGP packet */ 39 { 7, "ACPKIX" }, /* Attribute Certificate */ 40 { 8, "IACPKIX" }, /* The URL of an Attribute Certificate */ 41 { 253, "URI" }, /* URI private */ 42 { 254, "OID" }, /* OID private */ 43 /* 255 Reserved */ 44 /* 256-65279 Available for IANA assignment */ 45 /* 65280-65534 Experimental */ 46 /* 65535 Reserved */ 47 { 0, NULL } 48 }; 49 50 /* Taken from RFC 2535, section 7. */ 51 lookup_table_type dns_algorithms[] = { 52 { 1, "RSAMD5" }, /* RFC 2537 */ 53 { 2, "DH" }, /* RFC 2539 */ 54 { 3, "DSA" }, /* RFC 2536 */ 55 { 4, "ECC" }, 56 { 5, "RSASHA1" }, /* RFC 3110 */ 57 { 6, "DSA-NSEC3-SHA1" }, /* RFC 5155 */ 58 { 7, "RSASHA1-NSEC3-SHA1" }, /* RFC 5155 */ 59 { 8, "RSASHA256" }, /* RFC 5702 */ 60 { 10, "RSASHA512" }, /* RFC 5702 */ 61 { 12, "ECC-GOST" }, /* RFC 5933 */ 62 { 13, "ECDSAP256SHA256" }, /* RFC 6605 */ 63 { 14, "ECDSAP384SHA384" }, /* RFC 6605 */ 64 { 15, "ED25519" }, /* RFC 8080 */ 65 { 16, "ED448" }, /* RFC 8080 */ 66 { 252, "INDIRECT" }, 67 { 253, "PRIVATEDNS" }, 68 { 254, "PRIVATEOID" }, 69 { 0, NULL } 70 }; 71 72 /* Print svcparam key without a value */ 73 static int print_svcparam_no_value(struct buffer *output, uint16_t svcparamkey, 74 const uint8_t* data, uint16_t datalen); 75 76 /* Print svcparam mandatory */ 77 static int print_svcparam_mandatory(struct buffer *output, 78 uint16_t svcparamkey, const uint8_t* data, uint16_t datalen); 79 80 /* Print svcparam alpn */ 81 static int print_svcparam_alpn(struct buffer *output, 82 uint16_t svcparamkey, const uint8_t* data, uint16_t datalen); 83 84 /* Print svcparam port */ 85 static int print_svcparam_port(struct buffer *output, 86 uint16_t svcparamkey, const uint8_t* data, uint16_t datalen); 87 88 /* Print svcparam ipv4hint */ 89 static int print_svcparam_ipv4hint(struct buffer *output, 90 uint16_t svcparamkey, const uint8_t* data, uint16_t datalen); 91 92 /* Print svcparam ech */ 93 static int print_svcparam_ech(struct buffer *output, 94 uint16_t svcparamkey, const uint8_t* data, uint16_t datalen); 95 96 /* Print svcparam ipv6hint */ 97 static int print_svcparam_ipv6hint(struct buffer *output, 98 uint16_t svcparamkey, const uint8_t* data, uint16_t datalen); 99 100 /* Print svcparam dohpath */ 101 static int print_svcparam_dohpath(struct buffer *output, 102 uint16_t svcparamkey, const uint8_t* data, uint16_t datalen); 103 104 /* Print svcparam tls-supported-groups */ 105 static int print_svcparam_tls_supported_groups(struct buffer *output, 106 uint16_t svcparamkey, const uint8_t* data, uint16_t datalen); 107 108 static const nsd_svcparam_descriptor_type svcparams[] = { 109 { SVCB_KEY_MANDATORY, "mandatory", print_svcparam_mandatory }, 110 { SVCB_KEY_ALPN, "alpn", print_svcparam_alpn }, 111 { SVCB_KEY_NO_DEFAULT_ALPN, "no-default-alpn", 112 print_svcparam_no_value }, 113 { SVCB_KEY_PORT, "port", print_svcparam_port }, 114 { SVCB_KEY_IPV4HINT, "ipv4hint", print_svcparam_ipv4hint }, 115 { SVCB_KEY_ECH, "ech", print_svcparam_ech }, 116 { SVCB_KEY_IPV6HINT, "ipv6hint", print_svcparam_ipv6hint }, 117 { SVCB_KEY_DOHPATH, "dohpath", print_svcparam_dohpath }, 118 { SVCB_KEY_OHTTP, "ohttp", print_svcparam_no_value }, 119 { SVCB_KEY_TLS_SUPPORTED_GROUPS, "tls-supported-groups", 120 print_svcparam_tls_supported_groups }, 121 }; 122 123 /* 124 * Print domain name, as example.com. with escapes. 125 * The domain name is wireformat in the rdata. That is a literal dname 126 * in the rdata. 127 * @param output: the string is output here. 128 * @param rdlength: length of rdata. 129 * @param rdata: the rdata. The rdata+*offset is where the field is. 130 * @param offset: the current position on input. The position is updated to 131 * be incremented with the length of rdata that was used. 132 * @return false on failure. 133 */ 134 static int 135 print_name_literal(struct buffer *output, uint16_t rdlength, 136 const uint8_t *rdata, uint16_t *offset) 137 { 138 const uint8_t *name, *label, *limit; 139 assert(rdlength >= *offset); 140 if (rdlength - *offset == 0) 141 return 0; 142 143 name = rdata + *offset; 144 label = name; 145 limit = rdata + rdlength; 146 147 if(*label) { 148 do { 149 /* space for labellen, label and a next root label. */ 150 if (label - name > MAXDOMAINLEN-1 151 || *label > MAXLABELLEN 152 || limit - label < 2 + *label) 153 return 0; 154 label += 1 + *label; 155 } while (*label); 156 } else { 157 /* root domain. */ 158 /* The label is within the rdlength by the checks at start of 159 * the function. */ 160 } 161 162 buffer_printf(output, "%s", wiredname2str(name)); 163 *offset += (label - name) + 1 /* root label */; 164 return 1; 165 } 166 167 /* 168 * Print domain name, as example.com. with escapes. 169 * The domain must be a reference in the rdata. That is a stored pointer 170 * to struct domain. 171 * @param output: the string is output here. 172 * @param rdlength: length of rdata. 173 * @param rdata: the rdata. The rdata+*offset is where the field is. 174 * @param offset: the current position on input. The position is updated to 175 * be incremented with the length of rdata that was used. 176 * @return false on failure. 177 */ 178 static int 179 print_domain(struct buffer *output, uint16_t rdlength, const uint8_t *rdata, 180 uint16_t *offset) 181 { 182 const struct dname *dname; 183 struct domain *domain; 184 if(rdlength - *offset < (uint16_t)sizeof(void*)) 185 return 0; 186 memcpy(&domain, rdata+*offset, sizeof(void*)); 187 dname = domain_dname(domain); 188 buffer_printf(output, "%s", dname_to_string(dname, NULL)); 189 *offset += sizeof(void*); 190 return 1; 191 } 192 193 /* Return length of string or -1 on wireformat error. offset is moved +len. */ 194 static inline int32_t 195 skip_string(struct buffer* output, uint16_t rdlength, uint16_t* offset) 196 { 197 int32_t length; 198 if (rdlength - *offset < 1) 199 return -1; 200 length = buffer_read_u8(output); 201 if (length + 1 > rdlength - *offset) 202 return -1; 203 buffer_skip(output, length); 204 *offset += length + 1; 205 return length + 1; 206 } 207 208 /* Return length of strings or -1 on wireformat error. offset is moved +len. */ 209 static inline int32_t 210 skip_strings(struct buffer* output, uint16_t rdlength, uint16_t* offset) 211 { 212 int32_t olen = 0; 213 while(*offset < rdlength) { 214 int32_t slen = skip_string(output, rdlength, offset); 215 if(slen < 0) 216 return slen; 217 olen += slen; 218 } 219 return olen; 220 } 221 222 /* 223 * Print string, as "string" with escapes. 224 * @param output: the string is output here. 225 * @param rdlength: length of rdata. 226 * @param rdata: the rdata. The rdata+*offset is where the field is. 227 * @param offset: the current position on input. The position is updated to 228 * be incremented with the length of rdata that was used. 229 * @return false on failure. 230 */ 231 static int 232 print_string(struct buffer *output, uint16_t rdlength, const uint8_t *rdata, 233 uint16_t *offset) 234 { 235 size_t n; 236 if(rdlength - *offset < 1) 237 return 0; 238 n = rdata[*offset]; 239 if((size_t)rdlength - *offset < 1 + n) 240 return 0; 241 buffer_printf(output, "\""); 242 for (size_t i = 1; i <= n; i++) { 243 char ch = (char) rdata[*offset+i]; 244 if (isprint((unsigned char)ch)) { 245 if (ch == '"' || ch == '\\') { 246 buffer_printf(output, "\\"); 247 } 248 buffer_printf(output, "%c", ch); 249 } else { 250 buffer_printf(output, "\\%03u", 251 (unsigned) rdata[*offset+i]); 252 } 253 } 254 buffer_printf(output, "\""); 255 *offset += 1; 256 *offset += n; 257 return 1; 258 } 259 260 static int32_t 261 print_text(struct buffer *output, uint16_t rdlength, const uint8_t *rdata, 262 uint16_t *offset) 263 { 264 buffer_printf(output, "\""); 265 for (size_t i = *offset; i < rdlength; ++i) { 266 char ch = (char) rdata[i]; 267 if (isprint((unsigned char)ch)) { 268 if (ch == '"' || ch == '\\') { 269 buffer_printf(output, "\\"); 270 } 271 buffer_printf(output, "%c", ch); 272 } else { 273 buffer_printf(output, "\\%03u", (unsigned) rdata[i]); 274 } 275 } 276 buffer_printf(output, "\""); 277 *offset = rdlength; 278 return 1; 279 } 280 281 static int 282 print_unquoted(buffer_type *output, uint16_t rdlength, 283 const uint8_t* rdata, uint16_t* offset) 284 { 285 uint8_t len; 286 size_t i; 287 288 if(rdlength - *offset < 1) 289 return 0; 290 len = rdata[*offset]; 291 if(((size_t)len) + 1 > (size_t)rdlength - *offset) 292 return 0; 293 294 for (i = 1; i <= (size_t)len; ++i) { 295 char ch = (char) rdata[*offset + i]; 296 if (isprint((unsigned char)ch)) { 297 if (ch == '"' || ch == '\\' || ch == '(' || ch == ')' 298 || ch == '\'' || isspace((unsigned char)ch)) { 299 buffer_printf(output, "\\"); 300 } 301 buffer_printf(output, "%c", ch); 302 } else { 303 buffer_printf(output, "\\%03u", 304 (unsigned) rdata[*offset + i]); 305 } 306 } 307 *offset += 1; 308 *offset += len; 309 return 1; 310 } 311 312 static int 313 print_unquoteds(buffer_type *output, uint16_t rdlength, 314 const uint8_t* rdata, uint16_t* offset) 315 { 316 while (*offset < rdlength) { 317 if(!print_unquoted(output, rdlength, rdata, offset)) 318 return 0; 319 if(*offset < rdlength) 320 buffer_printf(output, " "); 321 } 322 return 1; 323 } 324 325 /* 326 * Print IP4 address. 327 * @param output: the string is output here. 328 * @param rdlength: length of rdata. 329 * @param rdata: the rdata. The rdata+*offset is where the field is. 330 * @param offset: the current position on input. The position is updated to 331 * be incremented with the length of rdata that was used. 332 * @return false on failure. 333 */ 334 static int 335 print_ip4(struct buffer *output, size_t rdlength, const uint8_t *rdata, 336 uint16_t *offset) 337 { 338 char str[INET_ADDRSTRLEN + 1]; 339 assert(rdlength >= *offset); 340 if(((size_t)*offset) + 4 > rdlength) 341 return 0; 342 if(!inet_ntop(AF_INET, rdata + *offset, str, sizeof(str))) 343 return 0; 344 buffer_printf(output, "%s", str); 345 *offset += 4; 346 return 1; 347 } 348 349 /* 350 * Print IP6 address. 351 * @param output: the string is output here. 352 * @param rdlength: length of rdata. 353 * @param rdata: the rdata. The rdata+*offset is where the field is. 354 * @param offset: the current position on input. The position is updated to 355 * be incremented with the length of rdata that was used. 356 * @return false on failure. 357 */ 358 static int 359 print_ip6(struct buffer *output, size_t rdlength, const uint8_t *rdata, 360 uint16_t *offset) 361 { 362 char str[INET6_ADDRSTRLEN + 1]; 363 assert(rdlength >= *offset); 364 if (rdlength - *offset < 16) 365 return 0; 366 if (!inet_ntop(AF_INET6, rdata + *offset, str, sizeof(str))) 367 return 0; 368 buffer_printf(output, "%s", str); 369 *offset += 16; 370 return 1; 371 } 372 373 /* 374 * Print ilnp64 field. 375 * @param output: the string is output here. 376 * @param rdlength: length of rdata. 377 * @param rdata: the rdata. The rdata+*offset is where the field is. 378 * @param offset: the current position on input. The position is updated to 379 * be incremented with the length of rdata that was used. 380 * @return false on failure. 381 */ 382 static int 383 print_ilnp64(struct buffer *output, uint16_t rdlength, const uint8_t *rdata, 384 uint16_t *offset) 385 { 386 uint16_t a1, a2, a3, a4; 387 assert(rdlength >= *offset); 388 if (rdlength - *offset < 8) 389 return 0; 390 a1 = read_uint16(rdata + *offset); 391 a2 = read_uint16(rdata + *offset + 2); 392 a3 = read_uint16(rdata + *offset + 4); 393 a4 = read_uint16(rdata + *offset + 6); 394 395 buffer_printf(output, "%.4x:%.4x:%.4x:%.4x", a1, a2, a3, a4); 396 *offset += 8; 397 return 1; 398 } 399 400 /* 401 * Print certificate type. 402 * @param output: the string is output here. 403 * @param rdlength: length of rdata. 404 * @param rdata: the rdata. The rdata+*offset is where the field is. 405 * @param offset: the current position on input. The position is updated to 406 * be incremented with the length of rdata that was used. 407 * @return false on failure. 408 */ 409 static int 410 print_certificate_type(struct buffer *output, size_t rdlength, 411 const uint8_t *rdata, uint16_t *offset) 412 { 413 uint16_t id; 414 lookup_table_type* type; 415 if (rdlength < *offset || rdlength - *offset < 2) 416 return 0; 417 id = read_uint16(rdata + *offset); 418 type = lookup_by_id(dns_certificate_types, id); 419 if (type) 420 buffer_printf(output, "%s", type->name); 421 else 422 buffer_printf(output, "%u", (unsigned) id); 423 *offset += 2; 424 return 1; 425 } 426 427 /* 428 * Print time field. 429 * @param output: the string is output here. 430 * @param rdlength: length of rdata. 431 * @param rdata: the rdata. The rdata+*offset is where the field is. 432 * @param offset: the current position on input. The position is updated to 433 * be incremented with the length of rdata that was used. 434 * @return false on failure. 435 */ 436 static int 437 print_time(struct buffer *output, uint16_t rdlength, const uint8_t *rdata, 438 uint16_t *offset) 439 { 440 time_t time; 441 struct tm tmbuf; 442 struct tm* tm; 443 char buf[15]; 444 445 assert(rdlength >= *offset); 446 if (rdlength - *offset < 4) 447 return 0; 448 time = (time_t)read_uint32(rdata + *offset); 449 tm = gmtime_r(&time, &tmbuf); 450 if (!strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", tm)) 451 return 0; 452 buffer_printf(output, "%s", buf); 453 *offset += 4; 454 return 1; 455 } 456 457 /* 458 * Print base32 output for a b32 field length uint8_t, like for NSEC3. 459 * @param output: the string is output here. 460 * @param rdlength: length of rdata. 461 * @param rdata: the rdata. The rdata+*offset is where the field is. 462 * @param offset: the current position on input. The position is updated to 463 * be incremented with the length of rdata that was used. 464 * @return false on failure. 465 */ 466 static int 467 print_base32(struct buffer *output, uint16_t rdlength, const uint8_t *rdata, 468 uint16_t *offset) 469 { 470 size_t size; 471 int length; 472 if(rdlength - *offset == 0) 473 return 0; 474 size = rdata[*offset]; 475 if (rdlength - ((size_t)*offset) < 1 + size) 476 return 0; 477 478 if (size == 0) { 479 buffer_write(output, "-", 1); 480 *offset += 1; 481 return 1; 482 } 483 484 buffer_reserve(output, size * 2 + 1); 485 length = b32_ntop(rdata + *offset + 1, size, 486 (char *)buffer_current(output), size * 2); 487 if (length == -1) 488 return 0; 489 buffer_skip(output, length); 490 *offset += 1 + size; 491 return 1; 492 } 493 494 /* 495 * Print base64 output for the remainder of rdata. 496 * @param output: the string is output here. 497 * @param rdlength: length of rdata. 498 * @param rdata: the rdata. The rdata+*offset is where the field is. 499 * @param offset: the current position on input. The position is updated to 500 * be incremented with the length of rdata that was used. 501 * @return false on failure. 502 */ 503 static int 504 print_base64(struct buffer *output, uint16_t rdlength, const uint8_t *rdata, 505 uint16_t *offset) 506 { 507 int length; 508 size_t size = rdlength - *offset; 509 if(size == 0) { 510 /* single zero represents empty buffer */ 511 buffer_write(output, "0", 1); 512 return 1; 513 } 514 buffer_reserve(output, size * 2 + 1); 515 length = b64_ntop(rdata + *offset, size, 516 (char *) buffer_current(output), size * 2); 517 if (length == -1) 518 return 0; 519 buffer_skip(output, length); 520 *offset += size; 521 return 1; 522 } 523 524 static void 525 buffer_print_hex(buffer_type *output, const uint8_t *data, size_t size) 526 { 527 static const char hexdigits[] = { 528 '0', '1', '2', '3', '4', '5', '6', '7', 529 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 530 }; 531 size_t i; 532 533 buffer_reserve(output, size * 2); 534 for (i = 0; i < size; ++i) { 535 uint8_t octet = *data++; 536 buffer_write_u8(output, hexdigits[octet >> 4]); 537 buffer_write_u8(output, hexdigits[octet & 0x0f]); 538 } 539 } 540 541 /* 542 * Print base16 output for the remainder of rdata, in hex lowercase. 543 * @param output: the string is output here. 544 * @param rdlength: length of rdata. 545 * @param rdata: the rdata. The rdata+*offset is where the field is. 546 * @param offset: the current position on input. The position is updated to 547 * be incremented with the length of rdata that was used. 548 * @return false on failure. 549 */ 550 static int 551 print_base16(struct buffer *output, uint16_t rdlength, const uint8_t *rdata, 552 uint16_t *offset) 553 { 554 size_t size = rdlength - *offset; 555 if(size == 0) { 556 /* single zero represents empty buffer, such as CDS deletes */ 557 buffer_write(output, "0", 1); 558 return 1; 559 } else { 560 buffer_print_hex(output, rdata+*offset, size); 561 } 562 *offset += size; 563 return 1; 564 } 565 566 /* 567 * Print salt, for NSEC3, in hex lowercase. 568 * @param output: the string is output here. 569 * @param rdlength: length of rdata. 570 * @param rdata: the rdata. The rdata+*offset is where the field is. 571 * @param offset: the current position on input. The position is updated to 572 * be incremented with the length of rdata that was used. 573 * @return false on failure. 574 */ 575 static int 576 print_salt(struct buffer *output, uint16_t rdlength, const uint8_t *rdata, 577 uint16_t *offset) 578 { 579 uint8_t length; 580 assert(rdlength >= *offset); 581 if (rdlength - *offset == 0) 582 return 0; 583 584 length = rdata[*offset]; 585 if (rdlength - *offset < 1 + length) 586 return 0; 587 if (!length) 588 /* NSEC3 salt hex can be empty */ 589 buffer_printf(output, "-"); 590 else 591 buffer_print_hex(output, rdata + *offset + 1, length); 592 *offset += 1 + (uint16_t)length; 593 return 1; 594 } 595 596 /* Return length of nsec type bitmap or -1 on wireformat error. offset is 597 * moved +len. rdlength is the length of the rdata, offset is offset in it. */ 598 static inline int32_t 599 skip_nsec(struct buffer* packet, uint16_t rdlength, uint16_t *offset) 600 { 601 uint16_t length = 0; 602 uint8_t last_window = 0; 603 604 while (rdlength - *offset - length > 2) { 605 uint8_t window = buffer_read_u8(packet); 606 uint8_t blocks = buffer_read_u8(packet); 607 if (length > 0 && window <= last_window) 608 return -1; 609 if (!blocks || blocks > 32) 610 return -1; 611 if (rdlength - *offset - length < 2 + blocks) 612 return -1; 613 buffer_skip(packet, blocks); 614 length += 2 + blocks; 615 last_window = window; 616 } 617 618 *offset += length; 619 if (rdlength != *offset) 620 return -1; 621 622 return length; 623 } 624 625 /* 626 * Print nsec type bitmap, for the remainder of rdata. 627 * @param output: the string is output here. 628 * @param rdlength: length of rdata. 629 * @param rdata: the rdata. The rdata+*offset is where the field is. 630 * @param offset: the current position on input. The position is updated to 631 * be incremented with the length of rdata that was used. 632 * @return false on failure. 633 */ 634 static int 635 print_nsec_bitmap(struct buffer *output, uint16_t rdlength, 636 const uint8_t *rdata, uint16_t *offset) 637 { 638 int insert_space = 0; 639 640 rdata += *offset; 641 while(rdlength - *offset > 0) { 642 uint8_t window, bitmap_size; 643 const uint8_t* bitmap; 644 int i; 645 646 if(rdlength - *offset < 2) 647 return 0; 648 window = rdata[0]; 649 bitmap_size = rdata[1]; 650 *offset += 2; 651 652 if(rdlength - *offset < bitmap_size) 653 return 0; 654 655 bitmap = rdata + 2; 656 rdata += 2; 657 for(i=0; i<((int)bitmap_size)*8; i++) { 658 if (get_bit(bitmap, i)) { 659 buffer_printf(output, 660 "%s%s", 661 insert_space ? " " : "", 662 rrtype_to_string( 663 window * 256 + i)); 664 insert_space = 1; 665 } 666 } 667 rdata += bitmap_size; 668 *offset += bitmap_size; 669 } 670 return 1; 671 } 672 673 /* If an svcparam must have a value */ 674 static int 675 svcparam_must_have_value(uint16_t svcparamkey) 676 { 677 switch (svcparamkey) { 678 case SVCB_KEY_ALPN: 679 case SVCB_KEY_PORT: 680 case SVCB_KEY_IPV4HINT: 681 case SVCB_KEY_IPV6HINT: 682 case SVCB_KEY_MANDATORY: 683 case SVCB_KEY_DOHPATH: 684 case SVCB_KEY_TLS_SUPPORTED_GROUPS: 685 return 1; 686 default: 687 break; 688 } 689 return 0; 690 } 691 692 /* If an svcparam must not have a value */ 693 static int 694 svcparam_must_not_have_value(uint16_t svcparamkey) 695 { 696 switch (svcparamkey) { 697 case SVCB_KEY_NO_DEFAULT_ALPN: 698 case SVCB_KEY_OHTTP: 699 return 1; 700 default: 701 break; 702 } 703 return 0; 704 }; 705 706 /* 707 * Skip over the svcparams in the packet. Moves position. 708 * @param packet: wire packet, position at rdata fields of svcparams. 709 * @param rdlength: remaining rdata length in the packet. 710 * @return 0 on wireformat error. 711 */ 712 static inline int 713 skip_svcparams(struct buffer *packet, uint16_t rdlength) 714 { 715 unsigned pos = 0; 716 uint16_t key, count; 717 while(pos < rdlength) { 718 if(pos+4 > (unsigned)rdlength) 719 return 0; 720 if(!buffer_available(packet, 4)) 721 return 0; 722 key = buffer_read_u16(packet); 723 count = buffer_read_u16(packet); 724 if(count == 0 && svcparam_must_have_value(key)) 725 return 0; 726 if(count != 0 && svcparam_must_not_have_value(key)) 727 return 0; 728 pos += 4; 729 if(pos+count > (unsigned)rdlength) 730 return 0; 731 if(!buffer_available(packet, count)) 732 return 0; 733 buffer_skip(packet, count); 734 pos += count; 735 } 736 return 1; 737 } 738 739 /* 740 * Print svcparamkey name to the buffer, or unknown as key<NUM>. 741 * @param output: printed to string. 742 * @param svcparamkey: the key to print. 743 */ 744 static void 745 buffer_print_svcparamkey(buffer_type *output, uint16_t svcparamkey) 746 { 747 if (svcparamkey < sizeof(svcparams)/sizeof(svcparams[0])) 748 buffer_printf(output, "%s", svcparams[svcparamkey].name); 749 else 750 buffer_printf(output, "key%" PRIu16, svcparamkey); 751 } 752 753 static int 754 print_svcparam_no_value(struct buffer *output, uint16_t svcparamkey, 755 const uint8_t* ATTR_UNUSED(data), uint16_t ATTR_UNUSED(datalen)) 756 { 757 buffer_print_svcparamkey(output, svcparamkey); 758 return 1; 759 } 760 761 static int 762 print_svcparam_mandatory(struct buffer *output, uint16_t svcparamkey, 763 const uint8_t* data, uint16_t datalen) 764 { 765 assert(datalen > 0); /* Guaranteed by svcparam_print */ 766 767 if (datalen % sizeof(uint16_t)) 768 return 0; /* wireformat error, val_len must be multiple of shorts */ 769 buffer_print_svcparamkey(output, svcparamkey); 770 buffer_write_u8(output, '='); 771 buffer_print_svcparamkey(output, read_uint16(data)); 772 data += 2; 773 774 while ((datalen -= sizeof(uint16_t))) { 775 buffer_write_u8(output, ','); 776 buffer_print_svcparamkey(output, read_uint16(data)); 777 data += 2; 778 } 779 780 return 1; 781 } 782 783 static int 784 print_svcparam_alpn(struct buffer *output, uint16_t svcparamkey, 785 const uint8_t* data, uint16_t datalen) 786 { 787 uint8_t *dp = (void *)data; 788 789 assert(datalen > 0); /* Guaranteed by svcparam_print */ 790 791 buffer_print_svcparamkey(output, svcparamkey); 792 buffer_write_u8(output, '='); 793 buffer_write_u8(output, '"'); 794 while (datalen) { 795 uint8_t i, str_len = *dp++; 796 797 if (str_len > --datalen) 798 return 0; 799 800 for (i = 0; i < str_len; i++) { 801 if (dp[i] == '"' || dp[i] == '\\') 802 buffer_printf(output, "\\\\\\%c", dp[i]); 803 804 else if (dp[i] == ',') 805 buffer_printf(output, "\\\\%c", dp[i]); 806 807 else if (!isprint(dp[i])) 808 buffer_printf(output, "\\%03u", (unsigned) dp[i]); 809 810 else 811 buffer_write_u8(output, dp[i]); 812 } 813 dp += str_len; 814 if ((datalen -= str_len)) 815 buffer_write_u8(output, ','); 816 } 817 buffer_write_u8(output, '"'); 818 return 1; 819 } 820 821 static int 822 print_svcparam_port(struct buffer *output, uint16_t svcparamkey, 823 const uint8_t* data, uint16_t datalen) 824 { 825 if (datalen != 2) 826 return 0; /* wireformat error, a short is 2 bytes */ 827 buffer_print_svcparamkey(output, svcparamkey); 828 buffer_printf(output, "=%d", (int)read_uint16(data)); 829 return 1; 830 } 831 832 static int 833 print_svcparam_ipv4hint(struct buffer *output, uint16_t svcparamkey, 834 const uint8_t* data, uint16_t datalen) 835 { 836 char ip_str[INET_ADDRSTRLEN + 1]; 837 838 assert(datalen > 0); /* Guaranteed by svcparam_print */ 839 840 buffer_print_svcparamkey(output, svcparamkey); 841 if ((datalen % IP4ADDRLEN) == 0) { 842 if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) == NULL) 843 return 0; /* wireformat error, incorrect size or inet family */ 844 845 buffer_printf(output, "=%s", ip_str); 846 data += IP4ADDRLEN; 847 848 while ((datalen -= IP4ADDRLEN) > 0) { 849 if (inet_ntop(AF_INET, data, ip_str, sizeof(ip_str)) 850 == NULL) 851 return 0; /* wireformat error, incorrect size or inet family */ 852 853 buffer_printf(output, ",%s", ip_str); 854 data += IP4ADDRLEN; 855 } 856 return 1; 857 } 858 return 0; 859 } 860 861 static int 862 print_svcparam_ech(struct buffer *output, uint16_t svcparamkey, 863 const uint8_t* data, uint16_t datalen) 864 { 865 int length; 866 867 buffer_print_svcparamkey(output, svcparamkey); 868 if(datalen == 0) 869 return 1; 870 buffer_write_u8(output, '='); 871 872 buffer_reserve(output, datalen * 2 + 1); 873 length = b64_ntop(data, datalen, (char*)buffer_current(output), 874 datalen * 2); 875 if (length > 0) { 876 buffer_skip(output, length); 877 } 878 879 return length != -1; 880 } 881 882 static int 883 print_svcparam_ipv6hint(struct buffer *output, uint16_t svcparamkey, 884 const uint8_t* data, uint16_t datalen) 885 { 886 char ip_str[INET6_ADDRSTRLEN + 1]; 887 888 assert(datalen > 0); /* Guaranteed by svcparam_print */ 889 890 buffer_print_svcparamkey(output, svcparamkey); 891 if ((datalen % IP6ADDRLEN) == 0) { 892 if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) == NULL) 893 return 0; /* wireformat error, incorrect size or inet family */ 894 895 buffer_printf(output, "=%s", ip_str); 896 data += IP6ADDRLEN; 897 898 while ((datalen -= IP6ADDRLEN) > 0) { 899 if (inet_ntop(AF_INET6, data, ip_str, sizeof(ip_str)) 900 == NULL) 901 return 0; /* wireformat error, incorrect size or inet family */ 902 903 buffer_printf(output, ",%s", ip_str); 904 data += IP6ADDRLEN; 905 } 906 return 1; 907 } 908 return 0; 909 } 910 911 static int 912 print_svcparam_dohpath(struct buffer *output, uint16_t svcparamkey, 913 const uint8_t* data, uint16_t datalen) 914 { 915 const uint8_t* dp = data; 916 unsigned i; 917 918 buffer_print_svcparamkey(output, svcparamkey); 919 buffer_write(output, "=\"", 2); 920 for (i = 0; i < datalen; i++) { 921 if (dp[i] == '"' || dp[i] == '\\') 922 buffer_printf(output, "\\%c", dp[i]); 923 924 else if (!isprint(dp[i])) 925 buffer_printf(output, "\\%03u", (unsigned) dp[i]); 926 927 else 928 buffer_write_u8(output, dp[i]); 929 } 930 buffer_write_u8(output, '"'); 931 return 1; 932 } 933 934 static int 935 print_svcparam_tls_supported_groups(struct buffer *output, 936 uint16_t svcparamkey, const uint8_t* data, uint16_t datalen) 937 { 938 assert(datalen > 0); /* Guaranteed by svcparam_print */ 939 940 if ((datalen % sizeof(uint16_t)) == 1) 941 return 0; /* A series of uint16_t is an even number of bytes */ 942 943 buffer_print_svcparamkey(output, svcparamkey); 944 buffer_printf(output, "=%d", (int)read_uint16(data)); 945 data += 2; 946 while ((datalen -= sizeof(uint16_t)) > 0) { 947 buffer_printf(output, ",%d", (int)read_uint16(data)); 948 data += 2; 949 } 950 return 1; 951 } 952 953 /* 954 * Print svcparam. 955 * @param output: the string is output here. 956 * @param rdlength: length of rdata. 957 * @param rdata: the rdata. The rdata+*offset is where the field is. 958 * @param offset: the current position on input. The position is updated to 959 * be incremented with the length of rdata that was used. 960 * @return false on failure. 961 */ 962 static int 963 print_svcparam(struct buffer *output, uint16_t rdlength, const uint8_t *rdata, 964 uint16_t *offset) 965 { 966 uint16_t key, length; 967 const uint8_t* dp; 968 unsigned i; 969 970 assert(rdlength >= *offset); 971 if (rdlength - *offset < 4) 972 return 0; 973 974 key = read_uint16(rdata + *offset); 975 length = read_uint16(rdata + *offset + 2); 976 977 if (rdlength - *offset < length + 4) 978 return 0; /* wireformat error */ 979 980 if(length == 0 && svcparam_must_have_value(key)) 981 return 0; 982 if(length != 0 && svcparam_must_not_have_value(key)) 983 return 0; 984 if (key < sizeof(svcparams)/sizeof(svcparams[0])) { 985 if(!svcparams[key].print_rdata(output, key, rdata+*offset+4, length)) 986 return 0; 987 *offset += length+4; 988 return 1; 989 } 990 991 buffer_printf(output, "key%" PRIu16, key); 992 if (!length) { 993 *offset += 4; 994 return 1; 995 } 996 997 buffer_write(output, "=\"", 2); 998 dp = rdata + *offset + 4; 999 1000 for (i = 0; i < length; i++) { 1001 if (dp[i] == '"' || dp[i] == '\\') 1002 buffer_printf(output, "\\%c", dp[i]); 1003 1004 else if (!isprint(dp[i])) 1005 buffer_printf(output, "\\%03u", (unsigned) dp[i]); 1006 1007 else 1008 buffer_write_u8(output, dp[i]); 1009 } 1010 buffer_write_u8(output, '"'); 1011 *offset += length + 4; 1012 return 1; 1013 } 1014 1015 static inline int32_t 1016 read_rdata(struct domain_table *domains, uint16_t rdlength, 1017 struct buffer *packet, struct rr **rr) 1018 { 1019 if (buffer_remaining(packet) < rdlength) 1020 return MALFORMED; 1021 if (!(*rr = region_alloc(domains->region, sizeof(**rr) + rdlength))) 1022 return TRUNCATED; 1023 if(rdlength != 0) 1024 buffer_read(packet, (*rr)->rdata, rdlength); 1025 (*rr)->rdlength = rdlength; 1026 return rdlength; 1027 } 1028 1029 int32_t 1030 read_generic_rdata(struct domain_table *domains, uint16_t rdlength, 1031 struct buffer *packet, struct rr **rr) 1032 { 1033 return read_rdata(domains, rdlength, packet, rr); 1034 } 1035 1036 void 1037 write_generic_rdata(struct query *query, const struct rr *rr) 1038 { 1039 if(rr->rdlength != 0) 1040 buffer_write(query->packet, rr->rdata, rr->rdlength); 1041 } 1042 1043 int 1044 print_generic_rdata(struct buffer *output, const struct rr *rr) 1045 { 1046 const nsd_type_descriptor_type* descriptor = 1047 nsd_type_descriptor(rr->type); 1048 return print_unknown_rdata_field(output, descriptor, rr); 1049 } 1050 1051 int 1052 lookup_rdata_field_entry(const nsd_type_descriptor_type* descriptor, 1053 size_t index, const rr_type* rr, uint16_t offset, uint16_t* field_len, 1054 struct domain** domain) 1055 { 1056 const nsd_rdata_descriptor_type* field = 1057 &descriptor->rdata.fields[index]; 1058 if(field->calculate_length) { 1059 /* Call field length function. */ 1060 int32_t l = field->calculate_length(rr->rdlength, rr->rdata, 1061 offset, domain); 1062 if(l < 0) 1063 return 0; 1064 *field_len = l; 1065 } else if(field->length >= 0) { 1066 *field_len = field->length; 1067 *domain = NULL; 1068 } else { 1069 size_t dlen; 1070 int32_t flen; 1071 if(offset > rr->rdlength) 1072 return 0; 1073 /* Handle the specialized value cases. */ 1074 switch(field->length) { 1075 case RDATA_COMPRESSED_DNAME: 1076 case RDATA_UNCOMPRESSED_DNAME: 1077 if(rr->rdlength - offset < 1078 (uint16_t)sizeof(void*)) 1079 return 0; 1080 *field_len = sizeof(void*); 1081 memcpy(domain, rr->rdata+offset, sizeof(void*)); 1082 break; 1083 case RDATA_LITERAL_DNAME: 1084 dlen = buf_dname_length(rr->rdata+offset, 1085 rr->rdlength-offset); 1086 if(dlen == 0) 1087 return 0; 1088 *field_len = dlen; 1089 *domain = NULL; 1090 break; 1091 case RDATA_STRING: 1092 case RDATA_BINARY: 1093 if(rr->rdlength - offset < 1) 1094 return 0; 1095 flen = (rr->rdata+offset)[0]; 1096 *field_len = flen+1; 1097 *domain = NULL; 1098 break; 1099 case RDATA_IPSECGATEWAY: 1100 case RDATA_AMTRELAY_RELAY: 1101 return 0; /* Has a callback function. */ 1102 case RDATA_REMAINDER: 1103 *field_len = rr->rdlength - offset; 1104 *domain = NULL; 1105 break; 1106 default: 1107 /* Unknown specialized value. */ 1108 return 0; 1109 } 1110 } 1111 if(offset + *field_len > rr->rdlength) 1112 return 0; /* The field does not fit in the rdata. */ 1113 return 1; 1114 } 1115 1116 int 1117 lookup_rdata_field_entry_uncompressed_wire( 1118 const nsd_type_descriptor_type* descriptor, size_t index, 1119 const uint8_t* rdata, uint16_t rdlength, uint16_t offset, 1120 uint16_t* field_len, struct domain** domain) 1121 { 1122 const nsd_rdata_descriptor_type* field = 1123 &descriptor->rdata.fields[index]; 1124 if(field->calculate_length) { 1125 /* Call field length function. */ 1126 int32_t l = field->calculate_length_uncompressed_wire(rdlength, 1127 rdata, offset, domain); 1128 if(l < 0) 1129 return 0; 1130 *field_len = l; 1131 } else if(field->length >= 0) { 1132 *field_len = field->length; 1133 *domain = NULL; 1134 } else { 1135 size_t dlen; 1136 int32_t flen; 1137 if(offset > rdlength) 1138 return 0; 1139 /* Handle the specialized value cases. */ 1140 switch(field->length) { 1141 case RDATA_COMPRESSED_DNAME: 1142 case RDATA_UNCOMPRESSED_DNAME: 1143 /* In the case that the field type is of type dname, 1144 * since this function deals with uncompressed 1145 * wireformat in the rdata buffer, the dname is 1146 * going to be there as an uncompressed wireformat 1147 * dname, for RDATA_COMPRESSED_DNAME and 1148 * RDATA_UNCOMPRESSED_DNAME. */ 1149 case RDATA_LITERAL_DNAME: 1150 dlen = buf_dname_length(rdata+offset, rdlength-offset); 1151 if(dlen == 0) 1152 return 0; 1153 *field_len = dlen; 1154 *domain = NULL; 1155 break; 1156 case RDATA_STRING: 1157 case RDATA_BINARY: 1158 if(rdlength - offset < 1) 1159 return 0; 1160 flen = (rdata+offset)[0]; 1161 *field_len = flen+1; 1162 *domain = NULL; 1163 break; 1164 case RDATA_IPSECGATEWAY: 1165 case RDATA_AMTRELAY_RELAY: 1166 return 0; /* Has a callback function. */ 1167 case RDATA_REMAINDER: 1168 *field_len = rdlength - offset; 1169 *domain = NULL; 1170 break; 1171 default: 1172 /* Unknown specialized value. */ 1173 return 0; 1174 } 1175 } 1176 if(offset + *field_len > rdlength) 1177 return 0; /* The field does not fit in the rdata. */ 1178 return 1; 1179 } 1180 1181 int32_t 1182 rr_calculate_uncompressed_rdata_length(const rr_type* rr) 1183 { 1184 size_t i; 1185 const nsd_type_descriptor_type* descriptor = 1186 nsd_type_descriptor(rr->type); 1187 uint16_t offset = 0; 1188 int32_t result = 0; 1189 if(!descriptor->has_references) 1190 return rr->rdlength; /* It does not really validate the 1191 fields versus the rdlength. */ 1192 for(i=0; i < descriptor->rdata.length; i++) { 1193 uint16_t field_len; 1194 struct domain* domain; 1195 if(rr->rdlength == offset && 1196 descriptor->rdata.fields[i].is_optional) 1197 break; /* There are no more rdata fields. */ 1198 if(!lookup_rdata_field_entry(descriptor, i, rr, offset, 1199 &field_len, &domain)) 1200 return -1; /* malformed rdata buffer */ 1201 if(domain != NULL) { 1202 /* Handle RDATA_COMPRESSED_DNAME and 1203 * RDATA_UNCOMPRESSED_DNAME fields. */ 1204 const struct dname* dname = domain_dname(domain); 1205 result += dname->name_size; 1206 } else { 1207 result += field_len; 1208 } 1209 offset += field_len; 1210 } 1211 return result; 1212 } 1213 1214 void 1215 rr_write_uncompressed_rdata(const rr_type* rr, uint8_t* buf, size_t len) 1216 { 1217 size_t i; 1218 const nsd_type_descriptor_type* descriptor = 1219 nsd_type_descriptor(rr->type); 1220 uint16_t offset = 0; /* The offset in rr->rdatas. */ 1221 size_t pos = 0; /* The position in buf. */ 1222 if(!descriptor->has_references) { 1223 /* It does not really validate the fields versus the 1224 * rdlength. */ 1225 if(rr->rdlength > len) 1226 return; /* buffer too small */ 1227 memcpy(buf, rr->rdata, rr->rdlength); 1228 return; 1229 } 1230 for(i=0; i < descriptor->rdata.length; i++) { 1231 uint16_t field_len; 1232 struct domain* domain; 1233 if(rr->rdlength == offset && 1234 descriptor->rdata.fields[i].is_optional) 1235 break; /* There are no more rdata fields. */ 1236 if(!lookup_rdata_field_entry(descriptor, i, rr, offset, 1237 &field_len, &domain)) 1238 return; /* malformed rdata buffer */ 1239 if(domain != NULL) { 1240 /* Handle RDATA_COMPRESSED_DNAME and 1241 * RDATA_UNCOMPRESSED_DNAME fields. */ 1242 const struct dname* dname = domain_dname(domain); 1243 if(pos + dname->name_size > len) 1244 return; /* buffer too small */ 1245 memcpy(buf+pos, dname_name(dname), dname->name_size); 1246 pos += dname->name_size; 1247 } else { 1248 if(pos + field_len > len) 1249 return; /* buffer too small */ 1250 memcpy(buf+pos, rr->rdata+offset, field_len); 1251 pos += field_len; 1252 } 1253 offset += field_len; 1254 } 1255 } 1256 1257 int print_unknown_rdata_field(buffer_type *output, 1258 const nsd_type_descriptor_type *descriptor, const rr_type *rr) 1259 { 1260 size_t i; 1261 int32_t size; 1262 uint16_t length = 0; 1263 1264 if(!descriptor->has_references) { 1265 /* There are no references to the domain table, the 1266 * rdata can be printed literally. */ 1267 buffer_printf(output, "\\# %lu ", (unsigned long)rr->rdlength); 1268 buffer_print_hex(output, rr->rdata, rr->rdlength); 1269 return 1; 1270 } 1271 1272 size = rr_calculate_uncompressed_rdata_length(rr); 1273 if(size < 0) 1274 return 0; 1275 buffer_printf(output, "\\# %lu ", (unsigned long) size); 1276 1277 for(i=0; i < descriptor->rdata.length; i++) { 1278 uint16_t field_len; 1279 struct domain* domain; 1280 const uint8_t* to_print; 1281 size_t to_print_len; 1282 if(rr->rdlength == length && 1283 descriptor->rdata.fields[i].is_optional) 1284 break; /* There are no more rdata fields. */ 1285 if(!lookup_rdata_field_entry(descriptor, i, rr, length, 1286 &field_len, &domain)) 1287 return 0; /* malformed rdata buffer */ 1288 if(domain != NULL) { 1289 /* Handle RDATA_COMPRESSED_DNAME and 1290 * RDATA_UNCOMPRESSED_DNAME fields. */ 1291 const struct dname* dname = domain_dname(domain); 1292 to_print = dname_name(dname); 1293 to_print_len = dname->name_size; 1294 } else { 1295 to_print = rr->rdata+length; 1296 to_print_len = field_len; 1297 } 1298 buffer_print_hex(output, to_print, to_print_len); 1299 length += field_len; 1300 } 1301 return 1; 1302 } 1303 1304 int print_unknown_rdata(buffer_type *output, 1305 const nsd_type_descriptor_type *descriptor, const rr_type *rr) 1306 { 1307 buffer_printf(output, "\t"); 1308 return print_unknown_rdata_field(output, descriptor, rr); 1309 } 1310 1311 int32_t 1312 read_compressed_name_rdata(struct domain_table *domains, uint16_t rdlength, 1313 struct buffer *packet, struct rr **rr) 1314 { 1315 struct domain *domain; 1316 struct dname_buffer dname; 1317 size_t size; 1318 const size_t mark = buffer_position(packet); 1319 1320 if (!dname_make_from_packet_buffered(&dname, packet, 1, 1) || 1321 rdlength != buffer_position(packet) - mark) 1322 return MALFORMED; 1323 size = sizeof(**rr) + sizeof(void*); 1324 if (!(*rr = region_alloc(domains->region, size))) 1325 return TRUNCATED; 1326 domain = domain_table_insert(domains, (void*)&dname); 1327 domain->usage++; 1328 memcpy((*rr)->rdata, &domain, sizeof(void*)); 1329 (*rr)->rdlength = sizeof(void*); 1330 return rdlength; 1331 } 1332 1333 int32_t 1334 read_uncompressed_name_rdata(struct domain_table *domains, uint16_t rdlength, 1335 struct buffer *packet, struct rr **rr) 1336 { 1337 struct domain *domain; 1338 struct dname_buffer dname; 1339 size_t size; 1340 const size_t mark = buffer_position(packet); 1341 1342 if (!dname_make_from_packet_buffered(&dname, packet, 1343 1 /* Lenient, allows pointers. */, 1) || 1344 rdlength != buffer_position(packet)-mark) 1345 return MALFORMED; 1346 size = sizeof(**rr) + sizeof(void*); 1347 if (!(*rr = region_alloc(domains->region, size))) 1348 return TRUNCATED; 1349 domain = domain_table_insert(domains, (void*)&dname); 1350 domain->usage++; 1351 memcpy((*rr)->rdata, &domain, sizeof(void*)); 1352 (*rr)->rdlength = sizeof(void*); 1353 return rdlength; 1354 } 1355 1356 static void 1357 encode_dname(query_type *q, domain_type *domain) 1358 { 1359 while (domain->parent && query_get_dname_offset(q, domain) == 0) { 1360 query_put_dname_offset(q, domain, buffer_position(q->packet)); 1361 DEBUG(DEBUG_NAME_COMPRESSION, 2, 1362 (LOG_INFO, "dname: %s, number: %lu, offset: %u\n", 1363 domain_to_string(domain), 1364 (unsigned long) domain->number, 1365 query_get_dname_offset(q, domain))); 1366 buffer_write(q->packet, dname_name(domain_dname(domain)), 1367 label_length(dname_name(domain_dname(domain))) + 1U); 1368 domain = domain->parent; 1369 } 1370 if (domain->parent) { 1371 DEBUG(DEBUG_NAME_COMPRESSION, 2, 1372 (LOG_INFO, "dname: %s, number: %lu, pointer: %u\n", 1373 domain_to_string(domain), 1374 (unsigned long) domain->number, 1375 query_get_dname_offset(q, domain))); 1376 assert(query_get_dname_offset(q, domain) <= MAX_COMPRESSION_OFFSET); 1377 buffer_write_u16(q->packet, 1378 0xc000 | query_get_dname_offset(q, domain)); 1379 } else { 1380 buffer_write_u8(q->packet, 0); 1381 } 1382 } 1383 1384 void 1385 write_compressed_name_rdata(struct query *query, const struct rr *rr) 1386 { 1387 struct domain *domain; 1388 assert(rr->rdlength == sizeof(void*)); 1389 memcpy(&domain, rr->rdata, sizeof(void*)); 1390 encode_dname(query, domain); 1391 } 1392 1393 void 1394 write_uncompressed_name_rdata(struct query *query, const struct rr *rr) 1395 { 1396 const struct dname *dname; 1397 struct domain *domain; 1398 assert(rr->rdlength >= sizeof(void*)); 1399 memcpy(&domain, rr->rdata, sizeof(void*)); 1400 dname = domain_dname(domain); 1401 buffer_write(query->packet, dname_name(dname), dname->name_size); 1402 } 1403 1404 int 1405 print_name_rdata(struct buffer *output, const struct rr *rr) 1406 { 1407 uint16_t length = 0; 1408 assert(rr->rdlength == sizeof(void*)); 1409 /* This prints a reference to a name stored as a pointer. */ 1410 return print_domain(output, rr->rdlength, rr->rdata, &length); 1411 } 1412 1413 int32_t 1414 read_a_rdata(struct domain_table *domains, uint16_t rdlength, 1415 struct buffer *packet, struct rr **rr) 1416 { 1417 if (rdlength != 4) 1418 return MALFORMED; 1419 return read_rdata(domains, rdlength, packet, rr); 1420 } 1421 1422 int 1423 print_a_rdata(struct buffer *output, const struct rr *rr) 1424 { 1425 uint16_t length = 0; 1426 assert(rr->rdlength == 4); 1427 return print_ip4(output, rr->rdlength, rr->rdata, &length); 1428 } 1429 1430 int32_t 1431 read_soa_rdata(struct domain_table *domains, uint16_t rdlength, 1432 struct buffer *packet, struct rr **rr) 1433 { 1434 struct domain *primary_domain, *mailbox_domain; 1435 struct dname_buffer primary, mailbox; 1436 size_t size; 1437 1438 /* domain + domain + uint32 + uint32 + uint32 + uint32 + uint32 */ 1439 const size_t mark = buffer_position(packet); 1440 if (!dname_make_from_packet_buffered(&primary, packet, 1, 1) || 1441 !dname_make_from_packet_buffered(&mailbox, packet, 1, 1) || 1442 rdlength != (buffer_position(packet) - mark) + 20) 1443 return MALFORMED; 1444 1445 size = sizeof(**rr) + 2 * sizeof(void*) + 20; 1446 if (!(*rr = region_alloc(domains->region, size))) 1447 return TRUNCATED; 1448 primary_domain = domain_table_insert(domains, (void*)&primary); 1449 primary_domain->usage++; 1450 mailbox_domain = domain_table_insert(domains, (void*)&mailbox); 1451 mailbox_domain->usage++; 1452 1453 memcpy((*rr)->rdata, &primary_domain, sizeof(void*)); 1454 memcpy((*rr)->rdata + sizeof(void*), &mailbox_domain, sizeof(void*)); 1455 buffer_read(packet, (*rr)->rdata + 2 * sizeof(void*), 20); 1456 (*rr)->rdlength = 2 * sizeof(void*) + 20; 1457 return rdlength; 1458 } 1459 1460 void 1461 write_soa_rdata(struct query *query, const struct rr *rr) 1462 { 1463 struct domain *primary, *mailbox; 1464 /* domain + domain + uint32 + uint32 + uint32 + uint32 + uint32 */ 1465 assert(rr->rdlength == 2 * sizeof(void*) + 20); 1466 memcpy(&primary, rr->rdata, sizeof(void*)); 1467 memcpy(&mailbox, rr->rdata + sizeof(void*), sizeof(void*)); 1468 encode_dname(query, primary); 1469 encode_dname(query, mailbox); 1470 buffer_write(query->packet, rr->rdata + (2 * sizeof(void*)), 20); 1471 } 1472 1473 int 1474 print_soa_rdata(struct buffer *output, const struct rr *rr) 1475 { 1476 uint16_t length = 0; 1477 uint32_t serial, refresh, retry, expire, minimum; 1478 assert(rr->rdlength == 2 * sizeof(void*) + 20); 1479 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 1480 return 0; 1481 buffer_printf(output, " "); 1482 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 1483 return 0; 1484 1485 assert(length == 2 * sizeof(void*)); 1486 serial = read_uint32(rr->rdata + length); 1487 refresh = read_uint32(rr->rdata + length + 4); 1488 retry = read_uint32(rr->rdata + length + 8); 1489 expire = read_uint32(rr->rdata + length + 12); 1490 minimum = read_uint32(rr->rdata + length + 16); 1491 1492 buffer_printf( 1493 output, " %" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32, 1494 serial, refresh, retry, expire, minimum); 1495 return 1; 1496 } 1497 1498 int 1499 print_soa_rdata_twoline(struct buffer *output, const struct rr *rr) 1500 { 1501 uint16_t length = 0; 1502 uint32_t serial, refresh, retry, expire, minimum; 1503 assert(rr->rdlength == 2 * sizeof(void*) + 20); 1504 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 1505 return 0; 1506 buffer_printf(output, " "); 1507 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 1508 return 0; 1509 1510 assert(length == 2 * sizeof(void*)); 1511 serial = read_uint32(rr->rdata + length); 1512 refresh = read_uint32(rr->rdata + length + 4); 1513 retry = read_uint32(rr->rdata + length + 8); 1514 expire = read_uint32(rr->rdata + length + 12); 1515 minimum = read_uint32(rr->rdata + length + 16); 1516 1517 buffer_printf( 1518 output, " (\n\t\t%" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 " )", 1519 serial, refresh, retry, expire, minimum); 1520 return 1; 1521 } 1522 1523 int32_t 1524 read_wks_rdata(struct domain_table *domains, uint16_t rdlength, 1525 struct buffer *packet, struct rr **rr) 1526 { 1527 if (rdlength < 5) 1528 return MALFORMED; 1529 return read_rdata(domains, rdlength, packet, rr); 1530 } 1531 1532 /* 1533 * Print protocol and service numbers rather than names for Well-Know Services 1534 * (WKS) RRs. WKS RRs are deprecated, though not technically, and should not 1535 * be used. The parser supports tcp/udp for protocols and a small subset of 1536 * services because getprotobyname and/or getservbyname are marked MT-Unsafe 1537 * and locale. getprotobyname_r and getservbyname_r exist on some platforms, 1538 * but are still marked locale (meaning the locale object is used without 1539 * synchonization, which is a problem for a library). Failure to load a zone 1540 * on a primary server because of an unknown protocol or service name is 1541 * acceptable as the operator can opt to use the numeric value. Failure to 1542 * load a zone on a secondary server is problematic because "unsupported" 1543 * protocols and services might be written. Print the numeric value for 1544 * maximum compatibility. 1545 * 1546 * (see simdzone/generic/wks.h for details). 1547 */ 1548 int 1549 print_wks_rdata(struct buffer *output, const struct rr *rr) 1550 { 1551 uint16_t length = 0; 1552 uint8_t protocol; 1553 int bits; 1554 const uint8_t* bitmap; 1555 1556 if(rr->rdlength < 5) 1557 return 0; 1558 if (!print_ip4(output, rr->rdlength, rr->rdata, &length)) 1559 return 0; 1560 1561 buffer_printf(output, " "); 1562 protocol = rr->rdata[4]; 1563 if(protocol == 6) 1564 buffer_printf(output, "tcp"); 1565 else if(protocol == 17) 1566 buffer_printf(output, "udp"); 1567 else 1568 buffer_printf(output, "%" PRIu8, protocol); 1569 1570 bits = (rr->rdlength - 5) * 8; 1571 bitmap = rr->rdata + 5; 1572 for (int service = 0; service < bits; service++) { 1573 if (get_bit(bitmap, service)) 1574 buffer_printf(output, " %d", service); 1575 } 1576 return 1; 1577 } 1578 1579 int32_t 1580 read_hinfo_rdata(struct domain_table *domains, uint16_t rdlength, 1581 struct buffer *packet, struct rr **rr) 1582 { 1583 uint16_t length = 0; 1584 const size_t mark = buffer_position(packet); 1585 1586 if(!buffer_available(packet, rdlength)) 1587 return MALFORMED; 1588 if (skip_string(packet, rdlength, &length) < 0 1589 || skip_string(packet, rdlength, &length) < 0 1590 || rdlength != length) 1591 return MALFORMED; 1592 buffer_set_position(packet, mark); 1593 return read_rdata(domains, rdlength, packet, rr); 1594 } 1595 1596 int 1597 print_hinfo_rdata(struct buffer *output, const struct rr *rr) 1598 { 1599 uint16_t length = 0; 1600 if (!print_string(output, rr->rdlength, rr->rdata, &length)) 1601 return 0; 1602 buffer_printf(output, " "); 1603 if (!print_string(output, rr->rdlength, rr->rdata, &length)) 1604 return 0; 1605 if(rr->rdlength != length) 1606 return 0; 1607 return 1; 1608 } 1609 1610 int32_t 1611 read_minfo_rdata(struct domain_table *domains, uint16_t rdlength, 1612 struct buffer *packet, struct rr **rr) 1613 { 1614 struct domain *rmailbx_domain, *emailbx_domain; 1615 struct dname_buffer rmailbx, emailbx; 1616 size_t size; 1617 const size_t mark = buffer_position(packet); 1618 1619 if (buffer_remaining(packet) < rdlength || 1620 !dname_make_from_packet_buffered(&rmailbx, packet, 1, 1) || 1621 !dname_make_from_packet_buffered(&emailbx, packet, 1, 1) || 1622 rdlength != buffer_position(packet)-mark) 1623 return MALFORMED; 1624 size = sizeof(**rr) + 2 * sizeof(void*); 1625 if (!(*rr = region_alloc(domains->region, size))) 1626 return TRUNCATED; 1627 rmailbx_domain = domain_table_insert(domains, (void*)&rmailbx); 1628 rmailbx_domain->usage++; 1629 emailbx_domain = domain_table_insert(domains, (void*)&emailbx); 1630 emailbx_domain->usage++; 1631 memcpy((*rr)->rdata, &rmailbx_domain, sizeof(void*)); 1632 memcpy((*rr)->rdata + sizeof(void*), &emailbx_domain, sizeof(void*)); 1633 (*rr)->rdlength = 2 * sizeof(void*); 1634 return rdlength; 1635 } 1636 1637 void 1638 write_minfo_rdata(struct query *query, const struct rr *rr) 1639 { 1640 struct domain *rmailbx, *emailbx; 1641 assert(rr->rdlength == 2 * sizeof(void*)); 1642 memcpy(&rmailbx, rr->rdata, sizeof(void*)); 1643 memcpy(&emailbx, rr->rdata + sizeof(void*), sizeof(void*)); 1644 encode_dname(query, rmailbx); 1645 encode_dname(query, emailbx); 1646 } 1647 1648 int 1649 print_minfo_rdata(struct buffer *output, const struct rr *rr) 1650 { 1651 uint16_t length = 0; 1652 assert(rr->rdlength == 2 * sizeof(void*)); 1653 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 1654 return 0; 1655 buffer_printf(output, " "); 1656 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 1657 return 0; 1658 assert(rr->rdlength == length); 1659 return 1; 1660 } 1661 1662 int32_t 1663 read_mx_rdata(struct domain_table *domains, uint16_t rdlength, 1664 struct buffer *packet, struct rr **rr) 1665 { 1666 struct domain *domain; 1667 struct dname_buffer exchange; 1668 size_t size; 1669 1670 /* short + name */ 1671 const size_t mark = buffer_position(packet); 1672 if (buffer_remaining(packet) < rdlength || rdlength < 2) 1673 return MALFORMED; 1674 buffer_skip(packet, 2); 1675 if (!dname_make_from_packet_buffered(&exchange, packet, 1, 1)) 1676 return MALFORMED; 1677 if (rdlength != buffer_position(packet)-mark) 1678 return MALFORMED; 1679 size = sizeof(**rr) + 2 + sizeof(void*); 1680 if (!(*rr = region_alloc(domains->region, size))) 1681 return -1; 1682 domain = domain_table_insert(domains, (void*)&exchange); 1683 domain->usage++; 1684 buffer_read_at(packet, mark, (*rr)->rdata, 2); 1685 memcpy((*rr)->rdata + 2, &domain, sizeof(void*)); 1686 (*rr)->rdlength = 2 + sizeof(void*); 1687 return rdlength; 1688 } 1689 1690 void 1691 write_mx_rdata(struct query *query, const struct rr *rr) 1692 { 1693 struct domain *domain; 1694 assert(rr->rdlength == 2 + sizeof(void*)); 1695 memcpy(&domain, rr->rdata + 2, sizeof(void*)); 1696 buffer_write(query->packet, rr->rdata, 2); 1697 encode_dname(query, domain); 1698 } 1699 1700 int 1701 print_mx_rdata(struct buffer *output, const struct rr *rr) 1702 { 1703 uint16_t length = 2; 1704 assert(rr->rdlength > length); 1705 buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata)); 1706 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 1707 return 0; 1708 assert(rr->rdlength == length); 1709 return 1; 1710 } 1711 1712 int32_t 1713 read_txt_rdata(struct domain_table *owners, uint16_t rdlength, 1714 struct buffer *packet, struct rr **rr) 1715 { 1716 uint16_t length = 0; 1717 const size_t mark = buffer_position(packet); 1718 if(!buffer_available(packet, rdlength)) 1719 return MALFORMED; 1720 if (skip_strings(packet, rdlength, &length) < 0 || rdlength != length) 1721 return MALFORMED; 1722 buffer_set_position(packet, mark); 1723 return read_rdata(owners, rdlength, packet, rr); 1724 } 1725 1726 int 1727 print_txt_rdata(struct buffer *output, const struct rr *rr) 1728 { 1729 uint16_t length = 0; 1730 if (length < rr->rdlength) { 1731 if (!print_string(output, rr->rdlength, rr->rdata, &length)) 1732 return 0; 1733 while (length < rr->rdlength) { 1734 buffer_printf(output, " "); 1735 if (!print_string(output, rr->rdlength, rr->rdata, 1736 &length)) 1737 return 0; 1738 } 1739 } 1740 return 1; 1741 } 1742 1743 int32_t 1744 read_rp_rdata(struct domain_table *domains, uint16_t rdlength, 1745 struct buffer *packet, struct rr **rr) 1746 { 1747 struct domain *mbox_domain, *txt_domain; 1748 struct dname_buffer mbox, txt; 1749 size_t size; 1750 const size_t mark = buffer_position(packet); 1751 1752 if (buffer_remaining(packet) < rdlength || 1753 !dname_make_from_packet_buffered(&mbox, packet, 1 /*lenient*/, 1) || 1754 !dname_make_from_packet_buffered(&txt, packet, 1 /*lenient*/, 1) || 1755 rdlength != buffer_position(packet)-mark) 1756 return MALFORMED; 1757 size = sizeof(**rr) + 2 * sizeof(void*); 1758 if (!(*rr = region_alloc(domains->region, size))) 1759 return TRUNCATED; 1760 mbox_domain = domain_table_insert(domains, (void*)&mbox); 1761 mbox_domain->usage++; 1762 txt_domain = domain_table_insert(domains, (void*)&txt); 1763 txt_domain->usage++; 1764 memcpy((*rr)->rdata, &mbox_domain, sizeof(void*)); 1765 memcpy((*rr)->rdata + sizeof(void*), &txt_domain, sizeof(void*)); 1766 (*rr)->rdlength = 2 * sizeof(void*); 1767 return rdlength; 1768 } 1769 1770 void 1771 write_rp_rdata(struct query *query, const struct rr *rr) 1772 { 1773 struct domain *mbox_domain, *txt_domain; 1774 const struct dname *mbox, *txt; 1775 1776 assert(rr->rdlength == 2 * sizeof(void*)); 1777 memcpy(&mbox_domain, rr->rdata, sizeof(void*)); 1778 memcpy(&txt_domain, rr->rdata + sizeof(void*), sizeof(void*)); 1779 mbox = domain_dname(mbox_domain); 1780 txt = domain_dname(txt_domain); 1781 buffer_write(query->packet, dname_name(mbox), mbox->name_size); 1782 buffer_write(query->packet, dname_name(txt), txt->name_size); 1783 } 1784 1785 int 1786 print_rp_rdata(struct buffer *output, const struct rr *rr) 1787 { 1788 uint16_t length = 0; 1789 if(!print_domain(output, rr->rdlength, rr->rdata, &length)) 1790 return 0; 1791 buffer_printf(output, " "); 1792 if(!print_domain(output, rr->rdlength, rr->rdata, &length)) 1793 return 0; 1794 assert(rr->rdlength == length); 1795 return 1; 1796 } 1797 1798 int32_t 1799 read_afsdb_rdata(struct domain_table *domains, uint16_t rdlength, 1800 struct buffer *packet, struct rr **rr) 1801 { 1802 struct domain *domain; 1803 struct dname_buffer hostname; 1804 size_t size; 1805 /* short + uncompressed name */ 1806 const size_t mark = buffer_position(packet); 1807 1808 if (buffer_remaining(packet) < rdlength || rdlength < 2) 1809 return MALFORMED; 1810 buffer_skip(packet, 2); 1811 if (!dname_make_from_packet_buffered(&hostname, packet, 1812 1 /*lenient*/, 1) || 1813 rdlength != buffer_position(packet)-mark) 1814 return MALFORMED; 1815 size = sizeof(**rr) + 2 + sizeof(void*); 1816 if (!(*rr = region_alloc(domains->region, size))) 1817 return TRUNCATED; 1818 domain = domain_table_insert(domains, (void*)&hostname); 1819 domain->usage++; 1820 buffer_read_at(packet, mark, (*rr)->rdata, 2); 1821 memcpy((*rr)->rdata + 2, &domain, sizeof(void*)); 1822 (*rr)->rdlength = 2 + sizeof(void*); 1823 return rdlength; 1824 } 1825 1826 void 1827 write_afsdb_rdata(struct query *query, const struct rr *rr) 1828 { 1829 struct domain *domain; 1830 const struct dname *dname; 1831 1832 assert(rr->rdlength == 2 + sizeof(void*)); 1833 memcpy(&domain, rr->rdata + 2, sizeof(void*)); 1834 dname = domain_dname(domain); 1835 buffer_write(query->packet, rr->rdata, 2); 1836 buffer_write(query->packet, dname_name(dname), dname->name_size); 1837 } 1838 1839 int 1840 print_afsdb_rdata(struct buffer *output, const struct rr *rr) 1841 { 1842 uint16_t subtype, length=2; 1843 assert(rr->rdlength == 2 + sizeof(void*)); 1844 subtype = read_uint16(rr->rdata); 1845 buffer_printf(output, "%" PRIu16 " ", subtype); 1846 if(!print_domain(output, rr->rdlength, rr->rdata, &length)) 1847 return 0; 1848 return 1; 1849 } 1850 1851 int32_t 1852 read_x25_rdata(struct domain_table *domains, uint16_t rdlength, 1853 struct buffer *packet, struct rr **rr) 1854 { 1855 uint16_t length = 0; 1856 const size_t mark = buffer_position(packet); 1857 if(!buffer_available(packet, rdlength)) 1858 return MALFORMED; 1859 if (skip_string(packet, rdlength, &length) < 0 || rdlength != length) 1860 return MALFORMED; 1861 buffer_set_position(packet, mark); 1862 return read_rdata(domains, rdlength, packet, rr); 1863 } 1864 1865 int 1866 print_x25_rdata(struct buffer *output, const struct rr *rr) 1867 { 1868 uint16_t length = 0; 1869 if (!print_string(output, rr->rdlength, rr->rdata, &length)) 1870 return 0; 1871 if(rr->rdlength != length) 1872 return 0; 1873 return 1; 1874 } 1875 1876 int32_t 1877 read_isdn_rdata(struct domain_table *domains, uint16_t rdlength, 1878 struct buffer *packet, struct rr **rr) 1879 { 1880 uint16_t length = 0; 1881 const size_t mark = buffer_position(packet); 1882 1883 if(!buffer_available(packet, rdlength)) 1884 return MALFORMED; 1885 if (skip_string(packet, rdlength, &length) < 0) 1886 return MALFORMED; 1887 if(rdlength > length) { 1888 /* Optional subaddress field is present. */ 1889 if (skip_string(packet, rdlength, &length) < 0 1890 || rdlength != length) 1891 return MALFORMED; 1892 } 1893 buffer_set_position(packet, mark); 1894 return read_rdata(domains, rdlength, packet, rr); 1895 } 1896 1897 int 1898 print_isdn_rdata(struct buffer *output, const struct rr *rr) 1899 { 1900 uint16_t length = 0; 1901 if (!print_string(output, rr->rdlength, rr->rdata, &length)) 1902 return 0; 1903 if(rr->rdlength > length) { 1904 /* Optional subaddress field is present. */ 1905 buffer_printf(output, " "); 1906 if (!print_string(output, rr->rdlength, rr->rdata, &length)) 1907 return 0; 1908 } 1909 if(rr->rdlength != length) 1910 return 0; 1911 return 1; 1912 } 1913 1914 int32_t 1915 read_rt_rdata(struct domain_table *domains, uint16_t rdlength, 1916 struct buffer *packet, struct rr **rr) 1917 { 1918 struct domain *domain; 1919 struct dname_buffer dname; 1920 size_t size; 1921 const size_t mark = buffer_position(packet); 1922 1923 if(!buffer_available(packet, rdlength)) 1924 return MALFORMED; 1925 if (rdlength < 2) 1926 return MALFORMED; 1927 buffer_skip(packet, 2); 1928 if (!dname_make_from_packet_buffered(&dname, packet, 1 /*lenient*/, 1)) 1929 return MALFORMED; 1930 if (rdlength != buffer_position(packet)-mark) 1931 return MALFORMED; 1932 size = sizeof(**rr) + 2 + sizeof(void*); 1933 if (!(*rr = region_alloc(domains->region, size))) 1934 return -1; 1935 domain = domain_table_insert(domains, (void*)&dname); 1936 domain->usage++; 1937 buffer_read_at(packet, mark, (*rr)->rdata, 2); 1938 memcpy((*rr)->rdata + 2, &domain, sizeof(void*)); 1939 (*rr)->rdlength = 2 + sizeof(void*); 1940 return rdlength; 1941 } 1942 1943 void 1944 write_rt_rdata(struct query *query, const struct rr *rr) 1945 { 1946 struct domain *domain; 1947 const struct dname *dname; 1948 1949 assert(rr->rdlength == 2 + sizeof(void*)); 1950 memcpy(&domain, rr->rdata + 2, sizeof(void*)); 1951 dname = domain_dname(domain); 1952 buffer_write(query->packet, rr->rdata, 2); 1953 buffer_write(query->packet, dname_name(dname), dname->name_size); 1954 } 1955 1956 int 1957 print_nsap_rdata(struct buffer *output, const struct rr *rr) 1958 { 1959 buffer_printf(output, "0x"); 1960 buffer_print_hex(output, rr->rdata, rr->rdlength); 1961 return 1; 1962 } 1963 1964 int 1965 print_nsap_ptr_rdata(struct buffer *output, const struct rr *rr) 1966 { 1967 uint16_t length = 0; 1968 if(!print_unquoted(output, rr->rdlength, rr->rdata, &length)) 1969 return 0; 1970 if(rr->rdlength != length) 1971 return 0; 1972 return 1; 1973 } 1974 1975 int 1976 print_key_rdata(struct buffer *output, const struct rr *rr) 1977 { 1978 uint16_t length = 4; 1979 if(rr->rdlength < length) 1980 return 0; 1981 buffer_printf( 1982 output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ", 1983 read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]); 1984 if (!print_base64(output, rr->rdlength, rr->rdata, &length)) 1985 return 0; 1986 if(rr->rdlength != length) 1987 return 0; 1988 return 1; 1989 } 1990 1991 int32_t 1992 read_px_rdata(struct domain_table *domains, uint16_t rdlength, 1993 struct buffer *packet, struct rr **rr) 1994 { 1995 struct domain *map822_domain, *mapx400_domain; 1996 struct dname_buffer map822, mapx400; 1997 size_t size; 1998 const size_t mark = buffer_position(packet); 1999 2000 /* short + uncompressed name + uncompressed name */ 2001 if (buffer_remaining(packet) < rdlength || 2002 rdlength < 2) 2003 return MALFORMED; 2004 buffer_skip(packet, 2); 2005 if(!dname_make_from_packet_buffered(&map822, packet, 2006 1 /*lenient*/, 1) || 2007 !dname_make_from_packet_buffered(&mapx400, packet, 2008 1 /*lenient*/, 1) || 2009 rdlength != buffer_position(packet) - mark) 2010 return MALFORMED; 2011 2012 size = sizeof(**rr) + 2 + 2*sizeof(void*); 2013 if (!(*rr = region_alloc(domains->region, size))) 2014 return TRUNCATED; 2015 map822_domain = domain_table_insert(domains, (void*)&map822); 2016 map822_domain->usage++; 2017 mapx400_domain = domain_table_insert(domains, (void*)&mapx400); 2018 mapx400_domain->usage++; 2019 2020 buffer_read_at(packet, mark, (*rr)->rdata, 2); 2021 memcpy((*rr)->rdata+2, &map822_domain, sizeof(void*)); 2022 memcpy((*rr)->rdata+2+sizeof(void*), &mapx400_domain, sizeof(void*)); 2023 (*rr)->rdlength = 2 + 2*sizeof(void*); 2024 return rdlength; 2025 } 2026 2027 void 2028 write_px_rdata(struct query *query, const struct rr *rr) 2029 { 2030 struct domain *map822_domain, *mapx400_domain; 2031 const struct dname *map822, *mapx400; 2032 2033 memcpy(&map822_domain, rr->rdata + 2, sizeof(void*)); 2034 memcpy(&mapx400_domain, rr->rdata + 2 + sizeof(void*), sizeof(void*)); 2035 map822 = domain_dname(map822_domain); 2036 mapx400 = domain_dname(mapx400_domain); 2037 buffer_write(query->packet, rr->rdata, 2); 2038 buffer_write(query->packet, dname_name(map822), map822->name_size); 2039 buffer_write(query->packet, dname_name(mapx400), mapx400->name_size); 2040 } 2041 2042 int 2043 print_px_rdata(struct buffer *output, const struct rr *rr) 2044 { 2045 uint16_t length = 2; 2046 assert(rr->rdlength > 3); 2047 buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata)); 2048 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 2049 return 0; 2050 buffer_printf(output, " "); 2051 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 2052 return 0; 2053 assert(rr->rdlength == length); 2054 return 1; 2055 } 2056 2057 int 2058 print_gpos_rdata(struct buffer *output, const struct rr *rr) 2059 { 2060 uint16_t length = 0; 2061 if(!print_unquoted(output, rr->rdlength, rr->rdata, &length)) 2062 return 0; 2063 buffer_printf(output, " "); 2064 if(!print_unquoted(output, rr->rdlength, rr->rdata, &length)) 2065 return 0; 2066 buffer_printf(output, " "); 2067 if(!print_unquoted(output, rr->rdlength, rr->rdata, &length)) 2068 return 0; 2069 if(rr->rdlength != length) 2070 return 0; 2071 return 1; 2072 } 2073 2074 int32_t 2075 read_aaaa_rdata(struct domain_table *domains, uint16_t rdlength, 2076 struct buffer *packet, struct rr **rr) 2077 { 2078 if (rdlength != 16) 2079 return MALFORMED; 2080 return read_rdata(domains, rdlength, packet, rr); 2081 } 2082 2083 int 2084 print_aaaa_rdata(struct buffer *output, const struct rr *rr) 2085 { 2086 uint16_t length = 0; 2087 assert(rr->rdlength == 16); 2088 return print_ip6(output, rr->rdlength, rr->rdata, &length); 2089 } 2090 2091 int32_t 2092 read_loc_rdata(struct domain_table *domains, uint16_t rdlength, 2093 struct buffer *packet, struct rr **rr) 2094 { 2095 size_t mark; 2096 uint8_t version; 2097 uint16_t size_version_0; 2098 2099 if(!buffer_available(packet, rdlength)) 2100 return MALFORMED; 2101 /* version (byte) */ 2102 if (rdlength < 1) 2103 return MALFORMED; 2104 /* version (byte) + size (byte) 2105 * + horizontal precision (byte) + vertical precision (byte) 2106 * + latitude (uint32) + longitude (uint32) + altitude (uint32) */ 2107 mark = buffer_position(packet); 2108 version = buffer_read_u8_at(packet, mark + 0); 2109 size_version_0 = 16u; 2110 if (version == 0 && rdlength != size_version_0) 2111 return MALFORMED; 2112 return read_rdata(domains, rdlength, packet, rr); 2113 } 2114 2115 /* Print the cm for LOC. */ 2116 static void 2117 loc_cm_print(struct buffer* output, uint8_t mantissa, uint8_t exponent) 2118 { 2119 uint8_t i; 2120 /* is it 0.<two digits> ? */ 2121 if(exponent < 2) { 2122 if(exponent == 1) 2123 mantissa *= 10; 2124 buffer_printf(output, "0.%02ld", (long)mantissa); 2125 return; 2126 } 2127 /* always <digit><string of zeros> */ 2128 buffer_printf(output, "%d", (int)mantissa); 2129 for(i=0; i<exponent-2; i++) 2130 buffer_printf(output, "0"); 2131 } 2132 2133 int 2134 print_loc_rdata(struct buffer *output, const struct rr *rr) 2135 { 2136 /* This does not perform checking (ie degrees < 90 etc). */ 2137 uint8_t version; 2138 uint8_t size; 2139 uint8_t horizontal_precision; 2140 uint8_t vertical_precision; 2141 uint32_t longitude; 2142 uint32_t latitude; 2143 uint32_t altitude; 2144 char northerness; 2145 char easterness; 2146 uint32_t h; 2147 uint32_t m; 2148 double s; 2149 uint32_t equator = (uint32_t)1 << 31; /* 2**31 */ 2150 2151 if(rr->rdlength < 16) 2152 return 0; 2153 version = rr->rdata[0]; 2154 if(version != 0) 2155 return 0; 2156 size = rr->rdata[1]; 2157 horizontal_precision = rr->rdata[2]; 2158 vertical_precision = rr->rdata[3]; 2159 2160 latitude = read_uint32(rr->rdata+4); 2161 longitude = read_uint32(rr->rdata+8); 2162 altitude = read_uint32(rr->rdata+12); 2163 2164 if (latitude > equator) { 2165 northerness = 'N'; 2166 latitude = latitude - equator; 2167 } else { 2168 northerness = 'S'; 2169 latitude = equator - latitude; 2170 } 2171 h = latitude / (1000 * 60 * 60); 2172 latitude = latitude % (1000 * 60 * 60); 2173 m = latitude / (1000 * 60); 2174 latitude = latitude % (1000 * 60); 2175 s = (double) latitude / 1000.0; 2176 buffer_printf(output, "%02u %02u %06.3f %c ", 2177 h, m, s, northerness); 2178 2179 if (longitude > equator) { 2180 easterness = 'E'; 2181 longitude = longitude - equator; 2182 } else { 2183 easterness = 'W'; 2184 longitude = equator - longitude; 2185 } 2186 h = longitude / (1000 * 60 * 60); 2187 longitude = longitude % (1000 * 60 * 60); 2188 m = longitude / (1000 * 60); 2189 longitude = longitude % (1000 * 60); 2190 s = (double) longitude / (1000.0); 2191 buffer_printf(output, "%02u %02u %06.3f %c ", 2192 h, m, s, easterness); 2193 2194 s = ((double) altitude) / 100; 2195 s -= 100000; 2196 2197 if(altitude%100 != 0) 2198 buffer_printf(output, "%.2f", s); 2199 else 2200 buffer_printf(output, "%.0f", s); 2201 buffer_printf(output, "m "); 2202 2203 loc_cm_print(output, (size & 0xf0) >> 4, size & 0x0f); 2204 buffer_printf(output, "m "); 2205 2206 loc_cm_print(output, (horizontal_precision & 0xf0) >> 4, 2207 horizontal_precision & 0x0f); 2208 buffer_printf(output, "m "); 2209 2210 loc_cm_print(output, (vertical_precision & 0xf0) >> 4, 2211 vertical_precision & 0x0f); 2212 buffer_printf(output, "m"); 2213 2214 return 1; 2215 } 2216 2217 int32_t 2218 read_nxt_rdata(struct domain_table *domains, uint16_t rdlength, 2219 struct buffer *packet, struct rr **rr) 2220 { 2221 struct domain *domain; 2222 struct dname_buffer dname; 2223 size_t size; 2224 uint16_t bitmap_size; 2225 const size_t mark = buffer_position(packet); 2226 2227 /* name + nxt */ 2228 if(!buffer_available(packet, rdlength)) 2229 return MALFORMED; 2230 if (!dname_make_from_packet_buffered(&dname, packet, 1, 1)) 2231 return MALFORMED; 2232 if(rdlength < buffer_position(packet) - mark) 2233 return MALFORMED; 2234 bitmap_size = rdlength - (buffer_position(packet) - mark); 2235 size = sizeof(**rr) + sizeof(void*) + bitmap_size; 2236 if (!(*rr = region_alloc(domains->region, size))) 2237 return TRUNCATED; 2238 domain = domain_table_insert(domains, (void*)&dname); 2239 domain->usage++; 2240 memcpy((*rr)->rdata, &domain, sizeof(void*)); 2241 if(bitmap_size != 0) 2242 buffer_read(packet, (*rr)->rdata + sizeof(void*), bitmap_size); 2243 (*rr)->rdlength = sizeof(void*) + bitmap_size; 2244 return rdlength; 2245 } 2246 2247 void 2248 write_nxt_rdata(struct query *query, const struct rr *rr) 2249 { 2250 struct domain *domain; 2251 const struct dname *dname; 2252 2253 assert(rr->rdlength >= sizeof(void*)); 2254 memcpy(&domain, rr->rdata, sizeof(void*)); 2255 dname = domain_dname(domain); 2256 buffer_write(query->packet, dname_name(dname), dname->name_size); 2257 if(rr->rdlength - sizeof(void*) != 0) 2258 buffer_write(query->packet, rr->rdata + sizeof(void*), 2259 rr->rdlength - sizeof(void*)); 2260 } 2261 2262 int 2263 print_nxt_rdata(struct buffer *output, const struct rr *rr) 2264 { 2265 uint16_t length = 0; 2266 int bitmap_size; 2267 const uint8_t* bitmap; 2268 2269 assert(rr->rdlength > sizeof(void*)); 2270 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 2271 return 0; 2272 2273 bitmap_size = rr->rdlength - length; 2274 bitmap = rr->rdata + length; 2275 for (int type = 0; type < bitmap_size * 8; type++) { 2276 if (get_bit(bitmap, type)) { 2277 buffer_printf(output, " %s", rrtype_to_string(type)); 2278 } 2279 } 2280 2281 return 1; 2282 } 2283 2284 int 2285 print_eid_rdata(struct buffer *output, const struct rr *rr) 2286 { 2287 uint16_t length = 0; 2288 if(!print_base16(output, rr->rdlength, rr->rdata, &length)) 2289 return 0; 2290 if(rr->rdlength != length) 2291 return 0; 2292 return 1; 2293 } 2294 2295 int 2296 print_nimloc_rdata(struct buffer *output, const struct rr *rr) 2297 { 2298 uint16_t length = 0; 2299 if(!print_base16(output, rr->rdlength, rr->rdata, &length)) 2300 return 0; 2301 if(rr->rdlength != length) 2302 return 0; 2303 return 1; 2304 } 2305 2306 int32_t 2307 read_srv_rdata(struct domain_table *domains, uint16_t rdlength, 2308 struct buffer *packet, struct rr **rr) 2309 { 2310 struct domain *domain; 2311 struct dname_buffer dname; 2312 size_t size; 2313 const size_t mark = buffer_position(packet); 2314 2315 /* short + short + short + name */ 2316 if (buffer_remaining(packet) < rdlength || rdlength < 6) 2317 return MALFORMED; 2318 buffer_skip(packet, 6); 2319 if (!dname_make_from_packet_buffered(&dname, packet, 2320 1 /* lenient */, 1) || 2321 rdlength != buffer_position(packet)-mark) 2322 return MALFORMED; 2323 size = sizeof(**rr) + 6 + sizeof(void*); 2324 if (!(*rr = region_alloc(domains->region, size))) 2325 return TRUNCATED; 2326 domain = domain_table_insert(domains, (void*)&dname); 2327 domain->usage++; 2328 buffer_read_at(packet, mark, (*rr)->rdata, 6); 2329 memcpy((*rr)->rdata + 6, &domain, sizeof(void*)); 2330 (*rr)->rdlength = 6 + sizeof(void*); 2331 return rdlength; 2332 } 2333 2334 void 2335 write_srv_rdata(struct query *query, const struct rr *rr) 2336 { 2337 struct domain *domain; 2338 const struct dname *dname; 2339 2340 assert(rr->rdlength == 6 + sizeof(void*)); 2341 memcpy(&domain, rr->rdata + 6, sizeof(void*)); 2342 dname = domain_dname(domain); 2343 buffer_write(query->packet, rr->rdata, 6); 2344 buffer_write(query->packet, dname_name(dname), dname->name_size); 2345 } 2346 2347 int 2348 print_srv_rdata(struct buffer *output, const struct rr *rr) 2349 { 2350 uint16_t length = 6; 2351 assert(rr->rdlength > length); 2352 buffer_printf( 2353 output, "%" PRIu16 " %" PRIu16 " %" PRIu16 " ", 2354 read_uint16(rr->rdata), read_uint16(rr->rdata+2), 2355 read_uint16(rr->rdata+4)); 2356 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 2357 return 0; 2358 assert(rr->rdlength == length); 2359 return 1; 2360 } 2361 2362 int 2363 print_atma_rdata(struct buffer *output, const struct rr *rr) 2364 { 2365 uint8_t format; 2366 if(rr->rdlength < 1) 2367 return 0; 2368 format = rr->rdata[0]; 2369 if(format == 0) { 2370 /* AESA format (ATM End System Address). */ 2371 uint16_t length = 1; 2372 if (!print_base16(output, rr->rdlength, rr->rdata, &length)) 2373 return 0; 2374 if(rr->rdlength != length) 2375 return 0; 2376 return 1; 2377 } else if(format == 1) { 2378 /* E.164 format. */ 2379 /* '+' and then digits '0'-'9' from the rdata string. */ 2380 buffer_printf(output, "+"); 2381 for (size_t i = 1; i < rr->rdlength; i++) { 2382 char ch = (char)rr->rdata[i]; 2383 if(!isdigit((unsigned char)ch)) 2384 return 0; 2385 buffer_printf(output, "%c", ch); 2386 } 2387 return 1; 2388 } 2389 /* Unknown format. */ 2390 return 0; 2391 } 2392 2393 int32_t 2394 read_naptr_rdata(struct domain_table *domains, uint16_t rdlength, 2395 struct buffer *packet, struct rr **rr) 2396 { 2397 struct domain *domain; 2398 struct dname_buffer dname; 2399 uint16_t length = 4; 2400 size_t size; 2401 const size_t mark = buffer_position(packet); 2402 2403 /* short + short + text + text + text + name */ 2404 if (buffer_remaining(packet) < rdlength || 2405 rdlength < length) 2406 return MALFORMED; 2407 buffer_skip(packet, 4); 2408 if(skip_string(packet, rdlength, &length) < 0 || 2409 skip_string(packet, rdlength, &length) < 0 || 2410 skip_string(packet, rdlength, &length) < 0 || 2411 !dname_make_from_packet_buffered(&dname, packet, 1, 1) || 2412 rdlength != buffer_position(packet) - mark) 2413 return MALFORMED; 2414 2415 size = sizeof(**rr) + length + sizeof(void*); 2416 if (!(*rr = region_alloc(domains->region, size))) 2417 return TRUNCATED; 2418 domain = domain_table_insert(domains, (void*)&dname); 2419 domain->usage++; 2420 buffer_read_at(packet, mark, (*rr)->rdata, length); 2421 memcpy((*rr)->rdata + length, &domain, sizeof(void*)); 2422 (*rr)->rdlength = length + sizeof(void*); 2423 return rdlength; 2424 } 2425 2426 void 2427 write_naptr_rdata(struct query *query, const struct rr *rr) 2428 { 2429 struct domain *domain; 2430 const struct dname *dname; 2431 uint16_t length; 2432 2433 /* short + short + string + string + string + uncompressed name */ 2434 assert(rr->rdlength >= 7 + sizeof(void*)); 2435 length = rr->rdlength - sizeof(void*); 2436 memcpy(&domain, rr->rdata + length, sizeof(void*)); 2437 dname = domain_dname(domain); 2438 buffer_write(query->packet, rr->rdata, length); 2439 buffer_write(query->packet, dname_name(dname), dname->name_size); 2440 } 2441 2442 int 2443 print_naptr_rdata(struct buffer *output, const struct rr *rr) 2444 { 2445 uint16_t length = 4; 2446 2447 assert(rr->rdlength >= 7 + sizeof(void*)); 2448 buffer_printf( 2449 output, "%" PRIu16 " %" PRIu16 " ", 2450 read_uint16(rr->rdata), read_uint16(rr->rdata+2)); 2451 if (!print_string(output, rr->rdlength, rr->rdata, &length)) 2452 return 0; 2453 buffer_printf(output, " "); 2454 if (!print_string(output, rr->rdlength, rr->rdata, &length)) 2455 return 0; 2456 buffer_printf(output, " "); 2457 if (!print_string(output, rr->rdlength, rr->rdata, &length)) 2458 return 0; 2459 buffer_printf(output, " "); 2460 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 2461 return 0; 2462 assert(rr->rdlength == length); 2463 return 1; 2464 } 2465 2466 int32_t 2467 read_kx_rdata(struct domain_table *domains, uint16_t rdlength, 2468 struct buffer *packet, struct rr **rr) 2469 { 2470 struct domain *domain; 2471 struct dname_buffer dname; 2472 const size_t mark = buffer_position(packet); 2473 size_t size; 2474 2475 /* short + uncompressed name */ 2476 if(buffer_remaining(packet) < rdlength || rdlength < 2) 2477 return MALFORMED; 2478 buffer_skip(packet, 2); 2479 if(!dname_make_from_packet_buffered(&dname, packet, 2480 1 /* lenient */, 1) || 2481 rdlength != buffer_position(packet) - mark) 2482 return MALFORMED; 2483 2484 size = sizeof(**rr) + 2 + sizeof(void*); 2485 if (!(*rr = region_alloc(domains->region, size))) 2486 return TRUNCATED; 2487 domain = domain_table_insert(domains, (void*)&dname); 2488 domain->usage++; 2489 buffer_read_at(packet, mark, (*rr)->rdata, 2); 2490 memcpy((*rr)->rdata + 2, &domain, sizeof(void*)); 2491 (*rr)->rdlength = 2 + sizeof(void*); 2492 return rdlength; 2493 } 2494 2495 void 2496 write_kx_rdata(struct query *query, const struct rr *rr) 2497 { 2498 struct domain *domain; 2499 const struct dname *dname; 2500 2501 /* short + uncompressed name */ 2502 assert(rr->rdlength == 2 + sizeof(void*)); 2503 memcpy(&domain, rr->rdata + 2, sizeof(void*)); 2504 dname = domain_dname(domain); 2505 buffer_write(query->packet, rr->rdata, 2); 2506 buffer_write(query->packet, dname_name(dname), dname->name_size); 2507 } 2508 2509 int32_t 2510 read_cert_rdata(struct domain_table *domains, uint16_t rdlength, 2511 struct buffer *packet, struct rr **rr) 2512 { 2513 /* short + short + byte + binary */ 2514 if (rdlength < 5) 2515 return MALFORMED; 2516 return read_rdata(domains, rdlength, packet, rr); 2517 } 2518 2519 int 2520 print_cert_rdata(struct buffer *output, const struct rr *rr) 2521 { 2522 uint16_t length = 0; 2523 if(rr->rdlength < 5) 2524 return 0; 2525 if(!print_certificate_type(output, rr->rdlength, rr->rdata, &length)) 2526 return 0; 2527 buffer_printf(output, " %" PRIu16 " %" PRIu8 " ", 2528 read_uint16(rr->rdata+2), rr->rdata[4]); 2529 length += 3; 2530 if (!print_base64(output, rr->rdlength, rr->rdata, &length)) 2531 return 0; 2532 if(rr->rdlength != length) 2533 return 0; 2534 return 1; 2535 } 2536 2537 int 2538 print_sink_rdata(struct buffer *output, const struct rr *rr) 2539 { 2540 uint16_t length = 2; 2541 if(rr->rdlength < 2) 2542 return 0; 2543 buffer_printf(output, "%" PRIu8 " %" PRIu8 " ", 2544 rr->rdata[0], rr->rdata[1]); 2545 if (!print_base64(output, rr->rdlength, rr->rdata, &length)) 2546 return 0; 2547 if(rr->rdlength != length) 2548 return 0; 2549 return 1; 2550 } 2551 2552 int32_t 2553 read_apl_rdata(struct domain_table *domains, uint16_t rdlength, 2554 struct buffer *packet, struct rr **rr) 2555 { 2556 uint16_t length = 0; 2557 const uint8_t *rdata = buffer_current(packet); 2558 2559 if (buffer_remaining(packet) < rdlength) 2560 return MALFORMED; 2561 while (rdlength - length >= 4) { 2562 uint8_t afdlength = rdata[length + 3] & APL_LENGTH_MASK; 2563 if (rdlength - (length + 4) < afdlength) 2564 return MALFORMED; 2565 length += 4 + afdlength; 2566 } 2567 2568 if (length != rdlength) 2569 return MALFORMED; 2570 return read_rdata(domains, rdlength, packet, rr); 2571 } 2572 2573 /* 2574 * Print one APL field. 2575 * @param output: string is printed to the buffer. 2576 * @param rdlength: length of rdata. 2577 * @param rdata: the rdata 2578 * @param offset: on input the current position, adjusted on output to 2579 * increment for the rdata used. 2580 * @return false on failure. 2581 */ 2582 static int 2583 print_apl(struct buffer *output, size_t rdlength, const uint8_t *rdata, 2584 uint16_t *offset) 2585 { 2586 size_t size = rdlength - *offset; 2587 uint16_t address_family; 2588 uint8_t prefix, length, negated; 2589 int af; 2590 char text_address[INET6_ADDRSTRLEN + 1]; 2591 uint8_t address[16]; 2592 2593 if (size < 4) 2594 return 0; 2595 2596 address_family = read_uint16(rdata + *offset); 2597 prefix = rdata[*offset + 2]; 2598 length = rdata[*offset + 3] & APL_LENGTH_MASK; 2599 negated = rdata[*offset + 3] & APL_NEGATION_MASK; 2600 af = -1; 2601 2602 switch (address_family) { 2603 case 1: af = AF_INET; break; 2604 case 2: af = AF_INET6; break; 2605 } 2606 2607 if (af == -1 || size - 4 < length) 2608 return 0; 2609 2610 memset(address, 0, sizeof(address)); 2611 memmove(address, rdata + *offset + 4, length); 2612 2613 if (!inet_ntop(af, address, text_address, sizeof(text_address))) 2614 return 0; 2615 2616 buffer_printf( 2617 output, "%s%" PRIu16 ":%s/%" PRIu8, 2618 (negated ? "!" : ""), address_family, text_address, prefix); 2619 *offset += 4 + length; 2620 return 1; 2621 } 2622 2623 int 2624 print_apl_rdata(struct buffer *output, const struct rr *rr) 2625 { 2626 uint16_t length = 0; 2627 2628 while (length < rr->rdlength) { 2629 if(length != 0) 2630 buffer_printf(output, " "); 2631 if (!print_apl(output, rr->rdlength, rr->rdata, &length)) 2632 return 0; 2633 } 2634 if(rr->rdlength != length) 2635 return 0; 2636 return 1; 2637 } 2638 2639 int32_t 2640 read_ds_rdata(struct domain_table *domains, uint16_t rdlength, 2641 struct buffer *packet, struct rr **rr) 2642 { 2643 /* short + byte + byte + binary */ 2644 if (rdlength < 4) 2645 return MALFORMED; 2646 return read_rdata(domains, rdlength, packet, rr); 2647 } 2648 2649 int 2650 print_ds_rdata(struct buffer *output, const struct rr *rr) 2651 { 2652 uint16_t length = 4; 2653 2654 if(rr->rdlength < length) 2655 return 0; 2656 buffer_printf( 2657 output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ", 2658 read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]); 2659 if (!print_base16(output, rr->rdlength, rr->rdata, &length)) 2660 return 0; 2661 if(rr->rdlength != length) 2662 return 0; 2663 return 1; 2664 } 2665 2666 int32_t 2667 read_sshfp_rdata(struct domain_table *domains, uint16_t rdlength, 2668 struct buffer *packet, struct rr **rr) 2669 { 2670 /* byte + byte + binary */ 2671 if (rdlength < 2) 2672 return MALFORMED; 2673 return read_rdata(domains, rdlength, packet, rr); 2674 } 2675 2676 int 2677 print_sshfp_rdata(struct buffer *output, const struct rr *rr) 2678 { 2679 uint16_t length = 2; 2680 uint8_t algorithm, ftype; 2681 2682 if(rr->rdlength < length) 2683 return 0; 2684 algorithm = rr->rdata[0]; 2685 ftype = rr->rdata[1]; 2686 2687 buffer_printf(output, "%" PRIu8 " %" PRIu8 " ", algorithm, ftype); 2688 if (!print_base16(output, rr->rdlength, rr->rdata, &length)) 2689 return 0; 2690 if(rr->rdlength != length) 2691 return 0; 2692 return 1; 2693 } 2694 2695 int32_t 2696 read_ipseckey_rdata(struct domain_table *domains, uint16_t rdlength, 2697 struct buffer *packet, struct rr **rr) 2698 { 2699 struct dname_buffer gateway; 2700 const uint8_t *gateway_rdata; 2701 uint8_t gateway_length = 0; 2702 const size_t mark = buffer_position(packet); 2703 uint16_t keylen; 2704 2705 /* byte + byte + byte + gateway + binary */ 2706 if (buffer_remaining(packet) < rdlength || rdlength < 3) 2707 return MALFORMED; 2708 2709 buffer_skip(packet, 3); 2710 2711 switch (buffer_read_u8_at(packet, mark + 1)) { 2712 case IPSECKEY_NOGATEWAY: 2713 gateway_length = 0; 2714 gateway_rdata = NULL; 2715 break; 2716 case IPSECKEY_IP4: 2717 gateway_length = 4; 2718 gateway_rdata = buffer_current(packet); 2719 if (rdlength < 3 + gateway_length) 2720 return MALFORMED; 2721 buffer_skip(packet, gateway_length); 2722 break; 2723 case IPSECKEY_IP6: 2724 gateway_length = 16; 2725 gateway_rdata = buffer_current(packet); 2726 if (rdlength < 3 + gateway_length) 2727 return MALFORMED; 2728 buffer_skip(packet, gateway_length); 2729 break; 2730 case IPSECKEY_DNAME: 2731 /* The dname is stored as literal dname. On the wire 2732 * skip possibly compressed format, in the rdata there 2733 * is an uncompressed wire format. */ 2734 if (!dname_make_from_packet_buffered(&gateway, packet, 2735 1 /* lenient */, 1)) 2736 return MALFORMED; 2737 if(rdlength < buffer_position(packet) - mark) 2738 return MALFORMED; 2739 gateway_length = gateway.dname.name_size; 2740 gateway_rdata = dname_name((void*)&gateway); 2741 break; 2742 default: 2743 return MALFORMED; 2744 } 2745 keylen = rdlength - (buffer_position(packet)-mark); 2746 2747 if (!(*rr = region_alloc(domains->region, 2748 sizeof(**rr) + 3 + gateway_length + keylen))) 2749 return TRUNCATED; 2750 2751 buffer_read_at(packet, mark, (*rr)->rdata, 3); 2752 if(gateway_rdata) 2753 memcpy((*rr)->rdata + 3, gateway_rdata, gateway_length); 2754 if(keylen != 0) 2755 buffer_read(packet, (*rr)->rdata + 3 + gateway_length, keylen); 2756 (*rr)->rdlength = 3 + gateway_length + keylen; 2757 return rdlength; 2758 } 2759 2760 int 2761 print_ipseckey_rdata(struct buffer *output, const struct rr *rr) 2762 { 2763 uint16_t length = 3; 2764 uint8_t gateway_type; 2765 2766 if(rr->rdlength < length) 2767 return 0; 2768 buffer_printf( 2769 output, "%" PRIu8 " %" PRIu8 " %" PRIu8 " ", 2770 rr->rdata[0], rr->rdata[1], rr->rdata[2]); 2771 gateway_type = rr->rdata[1]; 2772 switch (gateway_type) { 2773 case IPSECKEY_NOGATEWAY: 2774 buffer_printf(output, "."); 2775 break; 2776 case IPSECKEY_IP4: 2777 if (!print_ip4(output, rr->rdlength, rr->rdata, &length)) 2778 return 0; 2779 break; 2780 case IPSECKEY_IP6: 2781 if (!print_ip6(output, rr->rdlength, rr->rdata, &length)) 2782 return 0; 2783 break; 2784 case IPSECKEY_DNAME: 2785 if (!print_name_literal(output, rr->rdlength, rr->rdata, 2786 &length)) 2787 return 0; 2788 break; 2789 default: 2790 return 0; 2791 } 2792 2793 if(rr->rdlength > length) { 2794 /* Print key field in base64. */ 2795 buffer_printf(output, " "); 2796 if (!print_base64(output, rr->rdlength, rr->rdata, &length)) 2797 return 0; 2798 } 2799 if(rr->rdlength != length) 2800 return 0; 2801 return 1; 2802 } 2803 2804 int32_t 2805 ipseckey_gateway_length(uint16_t rdlength, const uint8_t *rdata, 2806 uint16_t offset, struct domain** domain) 2807 { 2808 /* The ipseckey gateway length depends only on earlier bytes, so both 2809 * the in-memory and uncompressed wireformat refer to the same 2810 * earlier bytes. Also the domain name is stored literally, so it 2811 * does not need to return a reference. */ 2812 uint8_t gateway_type; 2813 *domain = NULL; 2814 /* Calculate the gateway length, based on the gateway type. 2815 * That is stored in an earlier field. */ 2816 if(rdlength < 3 || offset < 3) 2817 return -1; /* too short */ 2818 gateway_type = rdata[1]; 2819 switch(gateway_type) { 2820 case IPSECKEY_NOGATEWAY: 2821 return 0; 2822 case IPSECKEY_IP4: 2823 return 4; 2824 case IPSECKEY_IP6: 2825 return 16; 2826 case IPSECKEY_DNAME: 2827 return buf_dname_length(rdata+offset, rdlength-offset); 2828 default: 2829 /* Unknown gateway type. */ 2830 break; 2831 } 2832 return -1; 2833 } 2834 2835 int32_t 2836 read_rrsig_rdata(struct domain_table *domains, uint16_t rdlength, 2837 struct buffer *packet, struct rr **rr) 2838 { 2839 struct dname_buffer signer; 2840 const size_t mark = buffer_position(packet); 2841 uint16_t memrdlen, b64len; 2842 2843 /* short + byte + byte + uint32 + uint32 + uint32 + short */ 2844 if (buffer_remaining(packet) < rdlength || rdlength < 18) 2845 return MALFORMED; 2846 buffer_skip(packet, 18); 2847 if (!dname_make_from_packet_buffered(&signer, packet, 2848 1 /* lenient */, 1)) 2849 return MALFORMED; 2850 if (rdlength < buffer_position(packet) - mark) 2851 return MALFORMED; 2852 memrdlen = 18 + signer.dname.name_size; 2853 b64len = rdlength - (buffer_position(packet) - mark); 2854 if (!(*rr = region_alloc(domains->region, sizeof(**rr) + memrdlen + b64len))) 2855 return TRUNCATED; 2856 buffer_read_at(packet, mark, (*rr)->rdata, 18); 2857 memcpy((*rr)->rdata + 18, dname_name((void*)&signer), 2858 signer.dname.name_size); 2859 if(b64len != 0) 2860 buffer_read(packet, (*rr)->rdata+memrdlen, b64len); 2861 (*rr)->rdlength = memrdlen + b64len; 2862 return rdlength; 2863 } 2864 2865 int 2866 print_rrsig_rdata(struct buffer *output, const struct rr *rr) 2867 { 2868 uint16_t length = 8; 2869 2870 if(rr->rdlength < 18) 2871 return 0; 2872 buffer_printf( 2873 output, "%s %" PRIu8 " %" PRIu8 " %" PRIu32 " ", 2874 rrtype_to_string(read_uint16(rr->rdata)), rr->rdata[2], 2875 rr->rdata[3], read_uint32(rr->rdata+4)); 2876 if (!print_time(output, rr->rdlength, rr->rdata, &length)) 2877 return 0; 2878 buffer_printf(output, " "); 2879 if (!print_time(output, rr->rdlength, rr->rdata, &length)) 2880 return 0; 2881 2882 buffer_printf(output, " %" PRIu16 " ", read_uint16(rr->rdata+length)); 2883 length += 2; 2884 2885 if (!print_name_literal(output, rr->rdlength, rr->rdata, &length)) 2886 return 0; 2887 buffer_printf(output, " "); 2888 if (!print_base64(output, rr->rdlength, rr->rdata, &length)) 2889 return 0; 2890 if(rr->rdlength != length) 2891 return 0; 2892 return 1; 2893 } 2894 2895 int32_t 2896 read_nsec_rdata(struct domain_table *domains, uint16_t rdlength, 2897 struct buffer *packet, struct rr **rr) 2898 { 2899 struct dname_buffer next; 2900 uint16_t length, memrdlen, bitmaplen; 2901 size_t bitmapmark; 2902 const size_t mark = buffer_position(packet); 2903 2904 /* uncompressed name + nsec */ 2905 if(buffer_remaining(packet) < rdlength || 2906 !dname_make_from_packet_buffered(&next, packet, 2907 1 /* lenient */, 1) || 2908 rdlength < buffer_position(packet) - mark) 2909 return MALFORMED; 2910 2911 bitmapmark = buffer_position(packet); 2912 length = bitmapmark - mark; 2913 if (skip_nsec(packet, rdlength, &length) < 0 2914 || rdlength != length) 2915 return MALFORMED; 2916 bitmaplen = buffer_position(packet) - bitmapmark; 2917 memrdlen = next.dname.name_size + bitmaplen; 2918 if (!(*rr = region_alloc(domains->region, sizeof(**rr) + memrdlen))) 2919 return TRUNCATED; 2920 memcpy((*rr)->rdata, dname_name((void*)&next), next.dname.name_size); 2921 if(bitmaplen != 0) 2922 buffer_read_at(packet, bitmapmark, 2923 (*rr)->rdata + next.dname.name_size, bitmaplen); 2924 (*rr)->rdlength = memrdlen; 2925 return rdlength; 2926 } 2927 2928 int 2929 print_nsec_rdata(struct buffer *output, const struct rr *rr) 2930 { 2931 uint16_t length = 0; 2932 2933 if (!print_name_literal(output, rr->rdlength, rr->rdata, &length)) 2934 return 0; 2935 buffer_printf(output, " "); 2936 if (!print_nsec_bitmap(output, rr->rdlength, rr->rdata, &length)) 2937 return 0; 2938 if(rr->rdlength != length) 2939 return 0; 2940 return 1; 2941 } 2942 2943 int32_t 2944 read_dnskey_rdata(struct domain_table *domains, uint16_t rdlength, 2945 struct buffer *packet, struct rr **rr) 2946 { 2947 /* short + byte + byte + binary of remainder */ 2948 if (rdlength < 4) 2949 return MALFORMED; 2950 return read_rdata(domains, rdlength, packet, rr); 2951 } 2952 2953 int 2954 print_dnskey_rdata(struct buffer *output, const struct rr *rr) 2955 { 2956 uint16_t length = 4; 2957 2958 if(rr->rdlength < length) 2959 return 0; 2960 buffer_printf( 2961 output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ", 2962 read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]); 2963 if (!print_base64(output, rr->rdlength, rr->rdata, &length)) 2964 return 0; 2965 if(rr->rdlength != length) 2966 return 0; 2967 return 1; 2968 } 2969 2970 int32_t 2971 read_dhcid_rdata(struct domain_table *domains, uint16_t rdlength, 2972 struct buffer *packet, struct rr **rr) 2973 { 2974 /* short + byte + digest */ 2975 if (rdlength < 3) 2976 return MALFORMED; 2977 return read_rdata(domains, rdlength, packet, rr); 2978 } 2979 2980 int 2981 print_dhcid_rdata(struct buffer *output, const struct rr *rr) 2982 { 2983 uint16_t length = 0; 2984 2985 if (!print_base64(output, rr->rdlength, rr->rdata, &length)) 2986 return 0; 2987 if(rr->rdlength != length) 2988 return 0; 2989 return 1; 2990 } 2991 2992 int32_t 2993 read_nsec3_rdata(struct domain_table *domains, uint16_t rdlength, 2994 struct buffer *packet, struct rr **rr) 2995 { 2996 uint16_t length = 4; 2997 /* byte + byte + short + string + string + binary */ 2998 const size_t mark = buffer_position(packet); 2999 3000 if (buffer_remaining(packet) < rdlength || rdlength < length) 3001 return MALFORMED; 3002 buffer_skip(packet, length); 3003 if (skip_string(packet, rdlength, &length) < 0 || 3004 skip_string(packet, rdlength, &length) < 0 || 3005 skip_nsec(packet, rdlength, &length) < 0 || 3006 rdlength != length) 3007 return MALFORMED; 3008 buffer_set_position(packet, mark); 3009 return read_rdata(domains, rdlength, packet, rr); 3010 } 3011 3012 int 3013 print_nsec3_rdata(struct buffer *output, const struct rr *rr) 3014 { 3015 uint16_t length = 4; 3016 3017 if(rr->rdlength < length) 3018 return 0; 3019 buffer_printf( 3020 output, "%" PRIu8 " %" PRIu8 " %" PRIu16 " ", 3021 rr->rdata[0], rr->rdata[1], read_uint16(rr->rdata + 2)); 3022 if (!print_salt(output, rr->rdlength, rr->rdata, &length)) 3023 return 0; 3024 buffer_printf(output, " "); 3025 if (!print_base32(output, rr->rdlength, rr->rdata, &length)) 3026 return 0; 3027 buffer_printf(output, " "); 3028 if (!print_nsec_bitmap(output, rr->rdlength, rr->rdata, &length)) 3029 return 0; 3030 if(rr->rdlength != length) 3031 return 0; 3032 return 1; 3033 } 3034 3035 int32_t 3036 read_nsec3param_rdata(struct domain_table *domains, uint16_t rdlength, 3037 struct buffer *packet, struct rr **rr) 3038 { 3039 uint16_t length = 4; 3040 /* byte + byte + short + string */ 3041 const size_t mark = buffer_position(packet); 3042 3043 if (buffer_remaining(packet) < rdlength || rdlength < length) 3044 return MALFORMED; 3045 buffer_skip(packet, length); 3046 if (skip_string(packet, rdlength, &length) < 0 || 3047 rdlength != length) 3048 return MALFORMED; 3049 buffer_set_position(packet, mark); 3050 return read_rdata(domains, rdlength, packet, rr); 3051 } 3052 3053 int 3054 print_nsec3param_rdata(struct buffer *output, const struct rr *rr) 3055 { 3056 uint16_t length = 4; 3057 3058 if(rr->rdlength < length) 3059 return 0; 3060 buffer_printf( 3061 output, "%" PRIu8 " %" PRIu8 " %" PRIu16 " ", 3062 rr->rdata[0], rr->rdata[1], read_uint16(rr->rdata + 2)); 3063 3064 if (!print_salt(output, rr->rdlength, rr->rdata, &length)) 3065 return 0; 3066 if(rr->rdlength != length) 3067 return 0; 3068 return 1; 3069 } 3070 3071 int32_t 3072 read_tlsa_rdata(struct domain_table *domains, uint16_t rdlength, 3073 struct buffer *packet, struct rr **rr) 3074 { 3075 /* byte + byte + byte + binary */ 3076 if (rdlength < 3) 3077 return MALFORMED; 3078 return read_rdata(domains, rdlength, packet, rr); 3079 } 3080 3081 int 3082 print_tlsa_rdata(struct buffer *output, const struct rr *rr) 3083 { 3084 uint16_t length = 3; 3085 3086 if(rr->rdlength < length) 3087 return 0; 3088 buffer_printf( 3089 output, "%" PRIu8 " %" PRIu8 " %" PRIu8 " ", 3090 rr->rdata[0], rr->rdata[1], rr->rdata[2]); 3091 3092 if (!print_base16(output, rr->rdlength, rr->rdata, &length)) 3093 return 0; 3094 if(rr->rdlength != length) 3095 return 0; 3096 return 1; 3097 } 3098 3099 int32_t 3100 read_hip_rdata(struct domain_table *domains, uint16_t rdlength, 3101 struct buffer *packet, struct rr **rr) 3102 { 3103 /* byte (hit length) + byte (PK algorithm) + short (PK length) + 3104 * HIT(hex) + pubkey(base64) + rendezvous servers(literal dnames) */ 3105 if (rdlength < 4) 3106 return MALFORMED; 3107 return read_rdata(domains, rdlength, packet, rr); 3108 } 3109 3110 int 3111 print_hip_rdata(struct buffer *output, const struct rr *rr) 3112 { 3113 /* byte (hit length) + byte (PK algorithm) + short (PK length) + 3114 * HIT(hex) + pubkey(base64) + rendezvous servers(literal dnames) */ 3115 uint8_t hit_length, pk_algorithm; 3116 uint16_t pk_length; 3117 uint16_t length = 4; 3118 3119 if(rr->rdlength < length) 3120 return 0; 3121 hit_length = rr->rdata[0]; 3122 pk_algorithm = rr->rdata[1]; 3123 pk_length = read_uint16(rr->rdata+2); 3124 buffer_printf(output, "%" PRIu8 " ", pk_algorithm); 3125 if(!print_base16(output, length+hit_length, rr->rdata, &length)) 3126 return 0; 3127 buffer_printf(output, " "); 3128 if(!print_base64(output, length+pk_length, rr->rdata, &length)) 3129 return 0; 3130 while(length < rr->rdlength) { 3131 buffer_printf(output, " "); 3132 if(!print_name_literal(output, rr->rdlength, rr->rdata, 3133 &length)) 3134 return 0; 3135 } 3136 if(rr->rdlength != length) 3137 return 0; 3138 return 1; 3139 } 3140 3141 int32_t 3142 read_rkey_rdata(struct domain_table *domains, uint16_t rdlength, 3143 struct buffer *packet, struct rr **rr) 3144 { 3145 /* short + byte + byte + binary of remainder */ 3146 if (rdlength < 4) 3147 return MALFORMED; 3148 return read_rdata(domains, rdlength, packet, rr); 3149 } 3150 3151 int 3152 print_rkey_rdata(struct buffer *output, const struct rr *rr) 3153 { 3154 uint16_t length = 4; 3155 3156 if(rr->rdlength < length) 3157 return 0; 3158 buffer_printf( 3159 output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ", 3160 read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]); 3161 if (!print_base64(output, rr->rdlength, rr->rdata, &length)) 3162 return 0; 3163 if(rr->rdlength != length) 3164 return 0; 3165 return 1; 3166 } 3167 3168 int32_t 3169 read_talink_rdata(struct domain_table *domains, uint16_t rdlength, 3170 struct buffer *packet, struct rr **rr) 3171 { 3172 struct dname_buffer prev, next; 3173 const size_t mark = buffer_position(packet); 3174 if(!buffer_available(packet, rdlength)) 3175 return MALFORMED; 3176 if(!dname_make_from_packet_buffered(&prev, packet, 3177 1 /* lenient */, 1)) 3178 return MALFORMED; 3179 if(buffer_position(packet)-mark > rdlength) 3180 return MALFORMED; 3181 if(!dname_make_from_packet_buffered(&next, packet, 3182 1 /* lenient */, 1)) 3183 return MALFORMED; 3184 if(buffer_position(packet)-mark != rdlength) 3185 return MALFORMED; 3186 if (!(*rr = region_alloc(domains->region, 3187 sizeof(**rr) + prev.dname.name_size + next.dname.name_size))) 3188 return TRUNCATED; 3189 memcpy((*rr)->rdata, dname_name((void*)&prev), prev.dname.name_size); 3190 memcpy((*rr)->rdata + prev.dname.name_size, dname_name((void*)&next), 3191 next.dname.name_size); 3192 (*rr)->rdlength = prev.dname.name_size + next.dname.name_size; 3193 return rdlength; 3194 } 3195 3196 int 3197 print_talink_rdata(struct buffer *output, const struct rr *rr) 3198 { 3199 uint16_t length = 0; 3200 if(!print_name_literal(output, rr->rdlength, rr->rdata, &length)) 3201 return 0; 3202 buffer_printf(output, " "); 3203 if(!print_name_literal(output, rr->rdlength, rr->rdata, &length)) 3204 return 0; 3205 if(rr->rdlength != length) 3206 return 0; 3207 return 1; 3208 } 3209 3210 int 3211 print_openpgpkey_rdata(struct buffer *output, const struct rr *rr) 3212 { 3213 uint16_t length = 0; 3214 3215 if (!print_base64(output, rr->rdlength, rr->rdata, &length)) 3216 return 0; 3217 if(rr->rdlength != length) 3218 return 0; 3219 return 1; 3220 } 3221 3222 int32_t 3223 read_csync_rdata(struct domain_table *domains, uint16_t rdlength, 3224 struct buffer *packet, struct rr **rr) 3225 { 3226 /* long + short + binary bitmap in remainder */ 3227 if (rdlength < 6) 3228 return MALFORMED; 3229 return read_rdata(domains, rdlength, packet, rr); 3230 } 3231 3232 int 3233 print_csync_rdata(struct buffer *output, const struct rr *rr) 3234 { 3235 uint16_t length = 6; 3236 3237 if(rr->rdlength < length) 3238 return 0; 3239 buffer_printf( 3240 output, "%" PRIu32 " %" PRIu16 " ", 3241 read_uint32(rr->rdata), read_uint16(rr->rdata + 4)); 3242 if (!print_nsec_bitmap(output, rr->rdlength, rr->rdata, &length)) 3243 return 0; 3244 if(rr->rdlength != length) 3245 return 0; 3246 return 1; 3247 } 3248 3249 int32_t 3250 read_zonemd_rdata(struct domain_table *domains, uint16_t rdlength, 3251 struct buffer *packet, struct rr **rr) 3252 { 3253 /* long + byte + byte + binary */ 3254 if (rdlength < 6) 3255 return MALFORMED; 3256 return read_rdata(domains, rdlength, packet, rr); 3257 } 3258 3259 int 3260 print_zonemd_rdata(struct buffer *output, const struct rr *rr) 3261 { 3262 uint16_t length = 6; 3263 3264 if(rr->rdlength < length) 3265 return 0; 3266 buffer_printf( 3267 output, "%" PRIu32 " %" PRIu8 " %" PRIu8 " ", 3268 read_uint32(rr->rdata), rr->rdata[4], rr->rdata[5]); 3269 if (!print_base16(output, rr->rdlength, rr->rdata, &length)) 3270 return 0; 3271 if(rr->rdlength != length) 3272 return 0; 3273 return 1; 3274 } 3275 3276 int32_t 3277 read_svcb_rdata(struct domain_table *domains, uint16_t rdlength, 3278 struct buffer *packet, struct rr **rr) 3279 { 3280 struct domain *domain; 3281 struct dname_buffer target; 3282 uint16_t length = 2, svcparams_length = 0; 3283 uint16_t size; 3284 const size_t mark = buffer_position(packet); 3285 3286 /* short + name + svc_params */ 3287 if (buffer_remaining(packet) < rdlength || rdlength < length) 3288 return MALFORMED; 3289 buffer_skip(packet, length); 3290 if (!dname_make_from_packet_buffered(&target, packet, 3291 1 /* lenient */, 1)) 3292 return MALFORMED; 3293 if(rdlength < buffer_position(packet) - mark) 3294 return MALFORMED; 3295 length = buffer_position(packet)-mark; 3296 /* For secondary, the server should accept the wireformat more 3297 * leniently. So this check is skipped. */ 3298 /* 3299 if(!skip_svcparams(packet, rdlength-length)) 3300 return MALFORMED; 3301 if(rdlength < buffer_position(packet) - mark) 3302 return MALFORMED; 3303 */ 3304 svcparams_length = rdlength - length; 3305 buffer_skip(packet, svcparams_length); 3306 3307 size = sizeof(**rr) + 2 + sizeof(void*) + svcparams_length; 3308 if (!(*rr = region_alloc(domains->region, size))) 3309 return TRUNCATED; 3310 domain = domain_table_insert(domains, (void*)&target); 3311 domain->usage++; 3312 buffer_read_at(packet, mark, (*rr)->rdata, 2); 3313 memcpy((*rr)->rdata + 2, &domain, sizeof(void*)); 3314 if(svcparams_length != 0) 3315 buffer_read_at(packet, mark + length, 3316 (*rr)->rdata + 2 + sizeof(void*), svcparams_length); 3317 (*rr)->rdlength = 2 + sizeof(void*) + svcparams_length; 3318 return rdlength; 3319 } 3320 3321 void 3322 write_svcb_rdata(struct query *query, const struct rr *rr) 3323 { 3324 struct domain *domain; 3325 const struct dname *target; 3326 uint8_t length; 3327 3328 assert(rr->rdlength >= 2 + sizeof(void*)); 3329 memcpy(&domain, rr->rdata + 2, sizeof(void*)); 3330 target = domain_dname(domain); 3331 buffer_write(query->packet, rr->rdata, 2); 3332 buffer_write(query->packet, dname_name(target), target->name_size); 3333 length = 2 + sizeof(void*); 3334 if(rr->rdlength > length) 3335 buffer_write(query->packet, rr->rdata + length, 3336 rr->rdlength - length); 3337 } 3338 3339 int 3340 print_svcb_rdata(struct buffer *output, const struct rr *rr) 3341 { 3342 uint16_t length = 2; 3343 3344 assert(rr->rdlength > length); /* It has 2+sizeof(void*) at least. */ 3345 buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata)); 3346 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 3347 return 0; 3348 while (length < rr->rdlength) { 3349 buffer_printf(output, " "); 3350 if (!print_svcparam(output, rr->rdlength, rr->rdata, &length)) 3351 return 0; 3352 } 3353 if(rr->rdlength != length) 3354 return 0; 3355 return 1; 3356 } 3357 3358 int32_t 3359 read_dsync_rdata(struct domain_table *domains, uint16_t rdlength, 3360 struct buffer *packet, struct rr **rr) 3361 { 3362 struct dname_buffer target; 3363 uint16_t length = 5; 3364 const size_t mark = buffer_position(packet); 3365 3366 /* type + byte + short + literaldname */ 3367 if (buffer_remaining(packet) < rdlength || rdlength < length) 3368 return MALFORMED; 3369 buffer_skip(packet, length); 3370 if(!dname_make_from_packet_buffered(&target, packet, 3371 1 /* lenient */, 1) || 3372 rdlength != buffer_position(packet) - mark) 3373 return MALFORMED; 3374 length += target.dname.name_size; 3375 3376 if (!(*rr = region_alloc(domains->region, sizeof(**rr)+length))) 3377 return TRUNCATED; 3378 buffer_read_at(packet, mark, (*rr)->rdata, 5); 3379 memcpy((*rr)->rdata + 5, dname_name((void*)&target), 3380 target.dname.name_size); 3381 (*rr)->rdlength = length; 3382 return rdlength; 3383 } 3384 3385 int 3386 print_dsync_rdata(struct buffer *output, const struct rr *rr) 3387 { 3388 uint16_t length = 5; 3389 if(rr->rdlength < length) 3390 return 0; 3391 buffer_printf(output, "%s %" PRIu8 " %" PRIu16 " ", 3392 rrtype_to_string(read_uint16(rr->rdata)), rr->rdata[2], 3393 read_uint16(rr->rdata+3)); 3394 if(!print_name_literal(output, rr->rdlength, rr->rdata, &length)) 3395 return 0; 3396 if(rr->rdlength != length) 3397 return 0; 3398 return 1; 3399 } 3400 3401 int32_t 3402 read_nid_rdata(struct domain_table *domains, uint16_t rdlength, 3403 struct buffer *packet, struct rr **rr) 3404 { 3405 if (rdlength != 10) 3406 return MALFORMED; 3407 return read_rdata(domains, rdlength, packet, rr); 3408 } 3409 3410 int 3411 print_nid_rdata(struct buffer *output, const struct rr *rr) 3412 { 3413 uint16_t length = 2; 3414 3415 if(rr->rdlength != 10) 3416 return 0; 3417 buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata)); 3418 if (!print_ilnp64(output, rr->rdlength, rr->rdata, &length)) 3419 return 0; 3420 if(rr->rdlength != length) 3421 return 0; 3422 return 1; 3423 } 3424 3425 int32_t 3426 read_l32_rdata(struct domain_table *domains, uint16_t rdlength, 3427 struct buffer *packet, struct rr **rr) 3428 { 3429 if (rdlength != 6) 3430 return MALFORMED; 3431 return read_rdata(domains, rdlength, packet, rr); 3432 } 3433 3434 int 3435 print_l32_rdata(struct buffer *output, const struct rr *rr) 3436 { 3437 uint16_t length = 2; 3438 3439 if(rr->rdlength != 6) 3440 return 0; 3441 buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata)); 3442 if (!print_ip4(output, rr->rdlength, rr->rdata, &length)) 3443 return 0; 3444 if(rr->rdlength != length) 3445 return 0; 3446 return 1; 3447 } 3448 3449 int32_t 3450 read_l64_rdata(struct domain_table *domains, uint16_t rdlength, 3451 struct buffer *packet, struct rr **rr) 3452 { 3453 if (rdlength != 10) 3454 return MALFORMED; 3455 return read_rdata(domains, rdlength, packet, rr); 3456 } 3457 3458 int 3459 print_l64_rdata(struct buffer *output, const struct rr *rr) 3460 { 3461 uint16_t length = 2; 3462 3463 if(rr->rdlength != 10) 3464 return 0; 3465 buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata)); 3466 if (!print_ilnp64(output, rr->rdlength, rr->rdata, &length)) 3467 return 0; 3468 if(rr->rdlength != length) 3469 return 0; 3470 return 1; 3471 } 3472 3473 int32_t 3474 read_lp_rdata(struct domain_table *domains, uint16_t rdlength, 3475 struct buffer *packet, struct rr **rr) 3476 { 3477 struct domain *domain; 3478 struct dname_buffer target; 3479 size_t size; 3480 /* short + name */ 3481 const size_t mark = buffer_position(packet); 3482 3483 if (buffer_remaining(packet) < rdlength || rdlength < 2) 3484 return MALFORMED; 3485 buffer_skip(packet, 2); 3486 if (!dname_make_from_packet_buffered(&target, packet, 3487 1 /* lenient */, 1) || 3488 rdlength != buffer_position(packet) - mark) 3489 return MALFORMED; 3490 size = sizeof(**rr) + 2 + sizeof(void*); 3491 if (!(*rr = region_alloc(domains->region, size))) 3492 return TRUNCATED; 3493 domain = domain_table_insert(domains, (void*)&target); 3494 domain->usage++; 3495 buffer_read_at(packet, mark, (*rr)->rdata, 2); 3496 memcpy((*rr)->rdata + 2, &domain, sizeof(void*)); 3497 (*rr)->rdlength = 2 + sizeof(void*); 3498 return rdlength; 3499 } 3500 3501 void 3502 write_lp_rdata(struct query *query, const struct rr *rr) 3503 { 3504 struct domain *domain; 3505 const struct dname *dname; 3506 3507 /* short + uncompressed name */ 3508 assert(rr->rdlength == 2 + sizeof(void*)); 3509 memcpy(&domain, rr->rdata + 2, sizeof(void*)); 3510 dname = domain_dname(domain); 3511 buffer_write(query->packet, rr->rdata, 2); 3512 buffer_write(query->packet, dname_name(dname), dname->name_size); 3513 } 3514 3515 int 3516 print_lp_rdata(struct buffer *output, const struct rr *rr) 3517 { 3518 uint16_t length = 2; 3519 3520 assert(rr->rdlength == 2 + sizeof(void*)); 3521 buffer_printf(output, "%" PRIu16 " ", read_uint16(rr->rdata)); 3522 if (!print_domain(output, rr->rdlength, rr->rdata, &length)) 3523 return 0; 3524 assert(rr->rdlength == length); 3525 return 1; 3526 } 3527 3528 int32_t 3529 read_eui48_rdata(struct domain_table *domains, uint16_t rdlength, 3530 struct buffer *packet, struct rr **rr) 3531 { 3532 if (rdlength != 6) 3533 return MALFORMED; 3534 return read_rdata(domains, rdlength, packet, rr); 3535 } 3536 3537 int 3538 print_eui48_rdata(struct buffer *output, const struct rr *rr) 3539 { 3540 const uint8_t *x = rr->rdata; 3541 if(rr->rdlength != 6) 3542 return 0; 3543 buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", 3544 x[0], x[1], x[2], x[3], x[4], x[5]); 3545 return 1; 3546 } 3547 3548 int32_t 3549 read_eui64_rdata(struct domain_table *domains, uint16_t rdlength, 3550 struct buffer *packet, struct rr **rr) 3551 { 3552 if (rdlength != 8) 3553 return MALFORMED; 3554 return read_rdata(domains, rdlength, packet, rr); 3555 } 3556 3557 int 3558 print_eui64_rdata(struct buffer *output, const struct rr *rr) 3559 { 3560 const uint8_t *x = rr->rdata; 3561 if(rr->rdlength != 8) 3562 return 0; 3563 buffer_printf(output, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", 3564 x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]); 3565 return 1; 3566 } 3567 3568 int32_t 3569 read_uri_rdata(struct domain_table *domains, uint16_t rdlength, 3570 struct buffer *packet, struct rr **rr) 3571 { 3572 /* short + short + long string */ 3573 if (rdlength < 4) 3574 return MALFORMED; 3575 return read_rdata(domains, rdlength, packet, rr); 3576 } 3577 3578 int 3579 print_uri_rdata(struct buffer *output, const struct rr *rr) 3580 { 3581 uint16_t length = 4; 3582 3583 if(rr->rdlength < length) 3584 return 0; 3585 buffer_printf( 3586 output, "%" PRIu16 " %" PRIu16 " ", 3587 read_uint16(rr->rdata), read_uint16(rr->rdata + 2)); 3588 if(!print_text(output, rr->rdlength, rr->rdata, &length)) 3589 return 0; 3590 if(rr->rdlength != length) 3591 return 0; 3592 return 1; 3593 } 3594 3595 int 3596 print_resinfo_rdata(struct buffer *output, const struct rr *rr) 3597 { 3598 uint16_t length = 0; 3599 if(!print_unquoteds(output, rr->rdlength, rr->rdata, &length)) 3600 return 0; 3601 if(rr->rdlength != length) 3602 return 0; 3603 return 1; 3604 } 3605 3606 int32_t 3607 read_caa_rdata(struct domain_table *domains, uint16_t rdlength, 3608 struct buffer *packet, struct rr **rr) 3609 { 3610 const size_t mark = buffer_position(packet); 3611 uint16_t length = 1; 3612 3613 /* byte + string + long string */ 3614 if (buffer_remaining(packet) < rdlength || rdlength < 2) 3615 return MALFORMED; 3616 buffer_skip(packet, 1); 3617 if (skip_string(packet, rdlength, &length) < 0 || rdlength < length) 3618 return MALFORMED; 3619 buffer_set_position(packet, mark); 3620 return read_rdata(domains, rdlength, packet, rr); 3621 } 3622 3623 int 3624 print_caa_rdata(struct buffer *output, const struct rr *rr) 3625 { 3626 uint16_t length = 1; 3627 3628 if(rr->rdlength < 2) 3629 return 0; 3630 buffer_printf(output, "%" PRIu8 " ", rr->rdata[0]); 3631 3632 length = 2 + rr->rdata[1]; 3633 if (rr->rdlength < length) 3634 return 0; 3635 3636 for (uint16_t i = 2; i < length; ++i) { 3637 char ch = (char) rr->rdata[i]; 3638 if (isdigit((unsigned char)ch) || islower((unsigned char)ch)) 3639 buffer_printf(output, "%c", ch); 3640 else return 0; 3641 } 3642 3643 buffer_printf(output, " "); 3644 if (!print_text(output, rr->rdlength, rr->rdata, &length)) 3645 return 0; 3646 if(rr->rdlength != length) 3647 return 0; 3648 return 1; 3649 } 3650 3651 int 3652 print_doa_rdata(struct buffer *output, const struct rr *rr) 3653 { 3654 uint16_t length = 9; 3655 if(rr->rdlength < length) 3656 return 0; 3657 buffer_printf(output, "%" PRIu32 " %" PRIu32 " %" PRIu8 " ", 3658 read_uint32(rr->rdata), read_uint32(rr->rdata+4), 3659 rr->rdata[8]); 3660 if(!print_string(output, rr->rdlength, rr->rdata, &length)) 3661 return 0; 3662 buffer_printf(output, " "); 3663 if(rr->rdlength == length) { 3664 /* The base64 string is empty, and DOA uses '-' for that. */ 3665 buffer_printf(output, "-"); 3666 } else { 3667 if(!print_base64(output, rr->rdlength, rr->rdata, &length)) 3668 return 0; 3669 } 3670 if(rr->rdlength != length) 3671 return 0; 3672 return 1; 3673 } 3674 3675 int32_t 3676 read_amtrelay_rdata(struct domain_table *domains, uint16_t rdlength, 3677 struct buffer *packet, struct rr **rr) 3678 { 3679 struct dname_buffer relay; 3680 const uint8_t *relay_rdata; 3681 uint8_t relay_length = 0; 3682 const size_t mark = buffer_position(packet); 3683 3684 /* byte + byte + relay */ 3685 if (buffer_remaining(packet) < rdlength || rdlength < 2) 3686 return MALFORMED; 3687 3688 buffer_skip(packet, 2); 3689 3690 switch (buffer_read_u8_at(packet, mark + 1)&AMTRELAY_TYPE_MASK) { 3691 case AMTRELAY_NOGATEWAY: 3692 relay_length = 0; 3693 relay_rdata = NULL; 3694 break; 3695 case AMTRELAY_IP4: 3696 relay_length = 4; 3697 relay_rdata = buffer_current(packet); 3698 if (rdlength < 2 + relay_length) 3699 return MALFORMED; 3700 buffer_skip(packet, relay_length); 3701 break; 3702 case AMTRELAY_IP6: 3703 relay_length = 16; 3704 relay_rdata = buffer_current(packet); 3705 if (rdlength < 2 + relay_length) 3706 return MALFORMED; 3707 buffer_skip(packet, relay_length); 3708 break; 3709 case AMTRELAY_DNAME: 3710 /* The dname is stored as literal dname. On the wire 3711 * skip possibly compressed format, in the rdata there 3712 * is an uncompressed wire format. */ 3713 if(!dname_make_from_packet_buffered(&relay, packet, 3714 1 /* lenient */, 1)) 3715 return MALFORMED; 3716 if(rdlength < buffer_position(packet) - mark) 3717 return MALFORMED; 3718 relay_length = relay.dname.name_size; 3719 relay_rdata = dname_name((void*)&relay); 3720 break; 3721 default: 3722 return MALFORMED; 3723 } 3724 if(rdlength != buffer_position(packet) - mark) 3725 return MALFORMED; /* trailing bytes */ 3726 3727 if (!(*rr = region_alloc(domains->region, 3728 sizeof(**rr) + 2 + relay_length))) 3729 return TRUNCATED; 3730 3731 buffer_read_at(packet, mark, (*rr)->rdata, 2); 3732 if(relay_rdata) 3733 memcpy((*rr)->rdata + 2, relay_rdata, relay_length); 3734 (*rr)->rdlength = 2 + relay_length; 3735 return rdlength; 3736 } 3737 3738 int 3739 print_amtrelay_rdata(struct buffer *output, const struct rr *rr) 3740 { 3741 uint16_t length = 2; 3742 uint8_t relay_type; 3743 3744 if(rr->rdlength < length) 3745 return 0; 3746 relay_type = rr->rdata[1]&AMTRELAY_TYPE_MASK; 3747 buffer_printf(output, "%" PRIu8 " %c %" PRIu8, 3748 rr->rdata[0], 3749 (rr->rdata[1] & AMTRELAY_DISCOVERY_OPTIONAL_MASK ? '1' : '0'), 3750 relay_type); 3751 switch(relay_type) { 3752 case AMTRELAY_NOGATEWAY: 3753 buffer_printf(output, " ."); 3754 break; 3755 case AMTRELAY_IP4: 3756 buffer_printf(output, " "); 3757 if(!print_ip4(output, rr->rdlength, rr->rdata, &length)) 3758 return 0; 3759 break; 3760 case AMTRELAY_IP6: 3761 buffer_printf(output, " "); 3762 if(!print_ip6(output, rr->rdlength, rr->rdata, &length)) 3763 return 0; 3764 break; 3765 case AMTRELAY_DNAME: 3766 buffer_printf(output, " "); 3767 if(!print_name_literal(output, rr->rdlength, rr->rdata, 3768 &length)) 3769 return 0; 3770 break; 3771 default: 3772 return 0; 3773 } 3774 3775 if(rr->rdlength != length) 3776 return 0; 3777 return 1; 3778 } 3779 3780 int32_t 3781 amtrelay_relay_length(uint16_t rdlength, const uint8_t *rdata, uint16_t offset, 3782 struct domain** domain) 3783 { 3784 /* The amtrelay relay length depends only on earlier bytes, so both 3785 * the in-memory and uncompressed wireformat refer to the same 3786 * earlier bytes. Also the domain name is stored literally, so it 3787 * does not need to return a reference. */ 3788 uint8_t relay_type; 3789 *domain = NULL; 3790 /* Calculate the relay length, based on the relay type. 3791 * That is stored in an earlier field. */ 3792 if(rdlength < 2 || offset < 2) 3793 return -1; /* too short */ 3794 relay_type = rdata[1]&AMTRELAY_TYPE_MASK; 3795 switch(relay_type) { 3796 case AMTRELAY_NOGATEWAY: 3797 return 0; 3798 case AMTRELAY_IP4: 3799 return 4; 3800 case AMTRELAY_IP6: 3801 return 16; 3802 case AMTRELAY_DNAME: 3803 return buf_dname_length(rdata+offset, rdlength-offset); 3804 default: 3805 /* Unknown relay type. */ 3806 break; 3807 } 3808 return -1; 3809 } 3810 3811 int 3812 print_ipn_rdata(struct buffer *output, const struct rr *rr) 3813 { 3814 uint64_t data; 3815 3816 if(rr->rdlength < sizeof(data)) 3817 return 0; 3818 data = read_uint64(rr->rdata); 3819 buffer_printf(output, "%llu", (unsigned long long) data); 3820 return 1; 3821 } 3822 3823 int32_t 3824 read_dlv_rdata(struct domain_table *domains, uint16_t rdlength, 3825 struct buffer *packet, struct rr **rr) 3826 { 3827 /* short + byte + byte + binary */ 3828 if (rdlength < 4) 3829 return MALFORMED; 3830 return read_rdata(domains, rdlength, packet, rr); 3831 } 3832 3833 int 3834 print_dlv_rdata(struct buffer *output, const struct rr *rr) 3835 { 3836 uint16_t length = 4; 3837 3838 if(rr->rdlength < length) 3839 return 0; 3840 buffer_printf( 3841 output, "%" PRIu16 " %" PRIu8 " %" PRIu8 " ", 3842 read_uint16(rr->rdata), rr->rdata[2], rr->rdata[3]); 3843 if (!print_base16(output, rr->rdlength, rr->rdata, &length)) 3844 return 0; 3845 if(rr->rdlength != length) 3846 return 0; 3847 return 1; 3848 } 3849 3850 int 3851 print_rdata(buffer_type *output, const nsd_type_descriptor_type *descriptor, 3852 const rr_type *rr) 3853 { 3854 size_t saved_position = buffer_position(output); 3855 /* If print_rdata is going to print "", omit the tab printout. */ 3856 if(!(rr->type == TYPE_APL && rr->rdlength == 0)) 3857 buffer_printf(output, "\t"); 3858 if(!descriptor->print_rdata(output, rr)) { 3859 buffer_set_position(output, saved_position); 3860 return 0; 3861 } 3862 return 1; 3863 } 3864 3865 /* 3866 * Compare two wireformat byte strings. In canonical order for this comparison. 3867 * Sorts equal as equal, and if there is a prefix match, the shorter one is 3868 * before the longer one; so it sorts like normalized domain names, 3869 * ab ac acd ace ad ae af. And ab < abc , abc < ac . 3870 * @param b1: byte string1. 3871 * @param len1: length of b1. 3872 * @param b2: byte string2. 3873 * @param len2: length of b2 3874 * @return comparison, -1, 0, 1. 3875 */ 3876 static int 3877 compare_bytestring(const uint8_t* b1, uint16_t len1, const uint8_t* b2, 3878 uint16_t len2) 3879 { 3880 uint16_t blen; 3881 int res; 3882 3883 if(len1 == 0 && len2 == 0) 3884 return 0; 3885 if(len1 == 0 && len2 != 0) 3886 return -1; 3887 if(len1 != 0 && len2 == 0) 3888 return 1; 3889 blen = len1; 3890 if(len2 < blen) 3891 blen = len2; 3892 res = memcmp(b1, b2, blen); 3893 if(res != 0) 3894 return res; 3895 if(len1 < len2) 3896 return -1; 3897 if(len1 > len2) 3898 return 1; 3899 /* len1 == len2 and equal. */ 3900 return 0; 3901 } 3902 3903 int 3904 equal_rr_rdata(const nsd_type_descriptor_type *descriptor, 3905 const struct rr *rr1, const struct rr *rr2) 3906 { 3907 size_t i; 3908 uint16_t offset = 0; 3909 int res; 3910 3911 if(!descriptor->has_references) { 3912 /* Compare the wireformat of the rdata. */ 3913 res = compare_bytestring(rr1->rdata, rr1->rdlength, 3914 rr2->rdata, rr2->rdlength); 3915 if(res != 0) 3916 return 0; 3917 return 1; 3918 } 3919 3920 for(i=0; i < descriptor->rdata.length; i++) { 3921 uint16_t field_len1, field_len2; 3922 struct domain* domain1, *domain2; 3923 int malf1 = 0, malf2 = 0; 3924 /* The fields are equal up to this point. */ 3925 if((rr1->rdlength == offset || rr2->rdlength == offset) && 3926 descriptor->rdata.fields[i].is_optional) { 3927 /* There are no more rdata fields. */ 3928 /* Check lengths. */ 3929 if(rr1->rdlength == rr2->rdlength) 3930 return 1; 3931 else 3932 return 0; 3933 } 3934 if(!lookup_rdata_field_entry(descriptor, i, rr1, offset, 3935 &field_len1, &domain1)) 3936 malf1 = 1; /* malformed rdata buffer */ 3937 if(!lookup_rdata_field_entry(descriptor, i, rr2, offset, 3938 &field_len2, &domain2)) 3939 malf2 = 1; /* malformed rdata buffer */ 3940 if(malf1 || malf2) { 3941 /* Malformed entries sort last, and are sorted 3942 * equal with other malformed entries. */ 3943 if(malf1 && malf2) 3944 return 1; 3945 else 3946 return 0; 3947 } 3948 /* Compare the two fields. */ 3949 /* If they have a different type field, they are not the 3950 * same. */ 3951 if(domain1 && !domain2) 3952 return 0; 3953 if(!domain1 && domain2) 3954 return 0; 3955 if(domain1 && domain2) { 3956 /* Handle RDATA_COMPRESSED_DNAME and 3957 * RDATA_UNCOMPRESSED_DNAME fields. */ 3958 res = dname_compare(domain_dname(domain1), 3959 domain_dname(domain2)); 3960 if(res != 0) 3961 return 0; 3962 } else { 3963 res = compare_bytestring(rr1->rdata + offset, 3964 field_len1, rr2->rdata + offset, field_len2); 3965 if(res != 0) 3966 return 0; 3967 } 3968 /* The fields are equal, field_len1 == field_len2. */ 3969 offset += field_len1; 3970 } 3971 return 1; 3972 } 3973 3974 int 3975 equal_rr_rdata_uncompressed_wire(const nsd_type_descriptor_type *descriptor, 3976 const struct rr *rr1, const uint8_t* rr2_rdata, uint16_t rr2_rdlen) 3977 { 3978 size_t i; 3979 uint16_t offset1 = 0, offset2 = 0; 3980 int res; 3981 3982 if(!descriptor->has_references) { 3983 /* Compare the wireformat of the rdata. */ 3984 res = compare_bytestring(rr1->rdata, rr1->rdlength, 3985 rr2_rdata, rr2_rdlen); 3986 if(res != 0) 3987 return 0; 3988 return 1; 3989 } 3990 3991 for(i=0; i < descriptor->rdata.length; i++) { 3992 uint16_t field_len1, field_len2; 3993 struct domain* domain1, *domain2; 3994 int malf1 = 0, malf2 = 0; 3995 /* The fields are equal up to this point. */ 3996 if((rr1->rdlength == offset1 || rr2_rdlen == offset2) && 3997 descriptor->rdata.fields[i].is_optional) { 3998 /* There are no more rdata fields. */ 3999 /* Check lengths. */ 4000 int remain1 = rr1->rdlength - offset1; 4001 int remain2 = rr2_rdlen - offset2; 4002 if(remain1 < remain2) 4003 return 0; 4004 if(remain1 > remain2) 4005 return 0; 4006 /* It is equal. */ 4007 return 1; 4008 } 4009 if(!lookup_rdata_field_entry(descriptor, i, rr1, offset1, 4010 &field_len1, &domain1)) 4011 malf1 = 1; /* malformed rdata buffer */ 4012 if(!lookup_rdata_field_entry_uncompressed_wire(descriptor, i, 4013 rr2_rdata, rr2_rdlen, offset2, &field_len2, &domain2)) 4014 malf2 = 1; /* malformed rdata buffer */ 4015 if(malf1 || malf2) { 4016 /* Malformed entries sort last, and are sorted 4017 * equal with other malformed entries. */ 4018 if(!malf1 && malf2) 4019 return 0; 4020 if(malf1 && !malf2) 4021 return 0; 4022 return 1; 4023 } 4024 /* Compare the two fields. */ 4025 /* If they have a different type field, they are not the 4026 * same. */ 4027 if(domain1) { 4028 if(domain2) { 4029 /* Handle RDATA_COMPRESSED_DNAME and 4030 * RDATA_UNCOMPRESSED_DNAME fields. */ 4031 res = dname_compare(domain_dname(domain1), 4032 domain_dname(domain2)); 4033 if(res != 0) 4034 return 0; 4035 } else { 4036 uint16_t dname_len2 = buf_dname_length( 4037 rr2_rdata+offset2, 4038 rr2_rdlen-offset2); 4039 if(domain_dname(domain1)->name_size != 4040 dname_len2) { 4041 /* not the same length dnames. */ 4042 return 0; 4043 } 4044 if(!dname_equal_nocase( 4045 (uint8_t*)dname_name(domain_dname( 4046 domain1)), 4047 (uint8_t*)rr2_rdata+offset2, 4048 dname_len2)) { 4049 /* name comparison not equal. */ 4050 return 0; 4051 } 4052 } 4053 } else { 4054 if(domain2) { 4055 uint16_t dname_len1 = buf_dname_length( 4056 rr1->rdata + offset1, 4057 rr1->rdlength-offset1); 4058 if(dname_len1 != 4059 domain_dname(domain2)->name_size) { 4060 /* not the same length dnames. */ 4061 return 0; 4062 } 4063 if(!dname_equal_nocase( 4064 (uint8_t*)rr1->rdata+offset1, 4065 (uint8_t*)dname_name(domain_dname( 4066 domain2)), 4067 dname_len1)) { 4068 /* name comparison not equal. */ 4069 return 0; 4070 } 4071 } else { 4072 res = compare_bytestring(rr1->rdata + offset1, 4073 field_len1, rr2_rdata + offset2, 4074 field_len2); 4075 if(res != 0) 4076 return 0; 4077 } 4078 } 4079 offset1 += field_len1; 4080 offset2 += field_len2; 4081 } 4082 return 1; 4083 } 4084 4085 struct domain* 4086 retrieve_rdata_ref_domain_offset(const struct rr* rr, uint16_t offset) 4087 { 4088 struct domain *domain; 4089 if(rr->rdlength < offset+sizeof(void*)) 4090 return NULL; 4091 memcpy(&domain, rr->rdata+offset, sizeof(void*)); 4092 return domain; 4093 } 4094 4095 struct domain* 4096 retrieve_rdata_ref_domain(const struct rr* rr) 4097 { 4098 struct domain *domain; 4099 if(rr->rdlength < sizeof(void*)) 4100 return NULL; 4101 memcpy(&domain, rr->rdata, sizeof(void*)); 4102 return domain; 4103 } 4104 4105 struct domain* 4106 retrieve_ns_ref_domain(const struct rr* rr) 4107 { 4108 assert(rr->type == TYPE_NS); 4109 return retrieve_rdata_ref_domain(rr); 4110 } 4111 4112 struct domain* 4113 retrieve_cname_ref_domain(const struct rr* rr) 4114 { 4115 assert(rr->type == TYPE_CNAME); 4116 return retrieve_rdata_ref_domain(rr); 4117 } 4118 4119 struct domain* 4120 retrieve_dname_ref_domain(const struct rr* rr) 4121 { 4122 assert(rr->type == TYPE_DNAME); 4123 return retrieve_rdata_ref_domain(rr); 4124 } 4125 4126 struct domain* 4127 retrieve_mb_ref_domain(const struct rr* rr) 4128 { 4129 assert(rr->type == TYPE_MB); 4130 return retrieve_rdata_ref_domain(rr); 4131 } 4132 4133 struct domain* 4134 retrieve_mx_ref_domain(const struct rr* rr) 4135 { 4136 assert(rr->type == TYPE_MX); 4137 return retrieve_rdata_ref_domain_offset(rr, 2); 4138 } 4139 4140 struct domain* 4141 retrieve_kx_ref_domain(const struct rr* rr) 4142 { 4143 assert(rr->type == TYPE_KX); 4144 return retrieve_rdata_ref_domain_offset(rr, 2); 4145 } 4146 4147 struct domain* 4148 retrieve_rt_ref_domain(const struct rr* rr) 4149 { 4150 assert(rr->type == TYPE_RT); 4151 return retrieve_rdata_ref_domain_offset(rr, 2); 4152 } 4153 4154 struct domain* 4155 retrieve_srv_ref_domain(const struct rr* rr) 4156 { 4157 assert(rr->type == TYPE_SRV); 4158 return retrieve_rdata_ref_domain_offset(rr, 6); 4159 } 4160 4161 struct domain* 4162 retrieve_ptr_ref_domain(const struct rr* rr) 4163 { 4164 assert(rr->type == TYPE_PTR); 4165 return retrieve_rdata_ref_domain(rr); 4166 } 4167 4168 int 4169 retrieve_soa_rdata_serial(const struct rr* rr, uint32_t* serial) 4170 { 4171 assert(rr->type == TYPE_SOA); 4172 if(rr->rdlength < 20 + 2*sizeof(void*)) 4173 return 0; 4174 /* primary mail serial[4] refresh[4] retry[4] expire[4] minimum[4] */ 4175 *serial = read_uint32(rr->rdata+2*sizeof(void*)); 4176 return 1; 4177 } 4178 4179 int 4180 retrieve_soa_rdata_minttl(const struct rr* rr, uint32_t* minttl) 4181 { 4182 assert(rr->type == TYPE_SOA); 4183 if(rr->rdlength < 20 + 2*sizeof(void*)) 4184 return 0; 4185 /* primary mail serial[4] refresh[4] retry[4] expire[4] minimum[4] */ 4186 *minttl = read_uint32(rr->rdata+2*sizeof(void*)+16); 4187 return 1; 4188 } 4189 4190 struct dname* retrieve_cname_ref_dname(const struct rr* rr) 4191 { 4192 struct domain* domain; 4193 assert(rr->type == TYPE_CNAME); 4194 domain = retrieve_rdata_ref_domain(rr); 4195 if(!domain) 4196 return NULL; 4197 return domain_dname(domain); 4198 } 4199 4200 void 4201 rr_lower_usage(namedb_type* db, rr_type* rr) 4202 { 4203 const nsd_type_descriptor_type *descriptor = 4204 nsd_type_descriptor(rr->type); 4205 uint16_t offset = 0; 4206 size_t i; 4207 for(i=0; i<descriptor->rdata.length; i++) { 4208 uint16_t field_len; 4209 struct domain* domain; 4210 if(rr->rdlength == offset && 4211 descriptor->rdata.fields[i].is_optional) 4212 break; 4213 if(!lookup_rdata_field_entry(descriptor, i, rr, offset, 4214 &field_len, &domain)) 4215 break; 4216 if(domain) { 4217 assert(domain->usage > 0); 4218 domain->usage --; 4219 if(domain->usage == 0) 4220 domain_table_deldomain(db, 4221 domain); 4222 } 4223 offset += field_len; 4224 } 4225 } 4226 4227 const char* 4228 read_rdata_fail_str(int32_t code) 4229 { 4230 switch(code) { 4231 case TRUNCATED: 4232 return "out of memory"; 4233 case MALFORMED: 4234 return "malformed rdata fields"; 4235 default: 4236 break; 4237 } 4238 return "failed to read rdata fields"; 4239 } 4240