ares_dns_parse.c (37028B)
1 /* MIT License 2 * 3 * Copyright (c) 2023 Brad House 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a copy 6 * of this software and associated documentation files (the "Software"), to deal 7 * in the Software without restriction, including without limitation the rights 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 * copies of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 * SPDX-License-Identifier: MIT 25 */ 26 #include "ares_private.h" 27 #include <limits.h> 28 #ifdef HAVE_STDINT_H 29 # include <stdint.h> 30 #endif 31 32 static size_t ares_dns_rr_remaining_len(const ares_buf_t *buf, size_t orig_len, 33 size_t rdlength) 34 { 35 size_t used_len = orig_len - ares_buf_len(buf); 36 if (used_len >= rdlength) { 37 return 0; 38 } 39 return rdlength - used_len; 40 } 41 42 static ares_status_t ares_dns_parse_and_set_dns_name(ares_buf_t *buf, 43 ares_bool_t is_hostname, 44 ares_dns_rr_t *rr, 45 ares_dns_rr_key_t key) 46 { 47 ares_status_t status; 48 char *name = NULL; 49 50 status = ares_dns_name_parse(buf, &name, is_hostname); 51 if (status != ARES_SUCCESS) { 52 return status; 53 } 54 55 status = ares_dns_rr_set_str_own(rr, key, name); 56 if (status != ARES_SUCCESS) { 57 ares_free(name); 58 return status; 59 } 60 return ARES_SUCCESS; 61 } 62 63 static ares_status_t ares_dns_parse_and_set_dns_str(ares_buf_t *buf, 64 size_t max_len, 65 ares_dns_rr_t *rr, 66 ares_dns_rr_key_t key, 67 ares_bool_t blank_allowed) 68 { 69 ares_status_t status; 70 char *str = NULL; 71 72 status = ares_buf_parse_dns_str(buf, max_len, &str); 73 if (status != ARES_SUCCESS) { 74 return status; 75 } 76 77 if (!blank_allowed && ares_strlen(str) == 0) { 78 ares_free(str); 79 return ARES_EBADRESP; 80 } 81 82 status = ares_dns_rr_set_str_own(rr, key, str); 83 if (status != ARES_SUCCESS) { 84 ares_free(str); 85 return status; 86 } 87 return ARES_SUCCESS; 88 } 89 90 static ares_status_t 91 ares_dns_parse_and_set_dns_abin(ares_buf_t *buf, size_t max_len, 92 ares_dns_rr_t *rr, ares_dns_rr_key_t key, 93 ares_bool_t validate_printable) 94 { 95 ares_status_t status; 96 ares_dns_multistring_t *strs = NULL; 97 98 status = 99 ares_dns_multistring_parse_buf(buf, max_len, &strs, validate_printable); 100 if (status != ARES_SUCCESS) { 101 return status; 102 } 103 104 status = ares_dns_rr_set_abin_own(rr, key, strs); 105 if (status != ARES_SUCCESS) { 106 ares_dns_multistring_destroy(strs); 107 return status; 108 } 109 return ARES_SUCCESS; 110 } 111 112 static ares_status_t ares_dns_parse_and_set_be32(ares_buf_t *buf, 113 ares_dns_rr_t *rr, 114 ares_dns_rr_key_t key) 115 { 116 ares_status_t status; 117 unsigned int u32; 118 119 status = ares_buf_fetch_be32(buf, &u32); 120 if (status != ARES_SUCCESS) { 121 return status; 122 } 123 124 return ares_dns_rr_set_u32(rr, key, u32); 125 } 126 127 static ares_status_t ares_dns_parse_and_set_be16(ares_buf_t *buf, 128 ares_dns_rr_t *rr, 129 ares_dns_rr_key_t key) 130 { 131 ares_status_t status; 132 unsigned short u16; 133 134 status = ares_buf_fetch_be16(buf, &u16); 135 if (status != ARES_SUCCESS) { 136 return status; 137 } 138 139 return ares_dns_rr_set_u16(rr, key, u16); 140 } 141 142 static ares_status_t ares_dns_parse_and_set_u8(ares_buf_t *buf, 143 ares_dns_rr_t *rr, 144 ares_dns_rr_key_t key) 145 { 146 ares_status_t status; 147 unsigned char u8; 148 149 status = ares_buf_fetch_bytes(buf, &u8, 1); 150 if (status != ARES_SUCCESS) { 151 return status; 152 } 153 154 return ares_dns_rr_set_u8(rr, key, u8); 155 } 156 157 static ares_status_t ares_dns_parse_rr_a(ares_buf_t *buf, ares_dns_rr_t *rr, 158 size_t rdlength) 159 { 160 struct in_addr addr; 161 ares_status_t status; 162 163 (void)rdlength; /* Not needed */ 164 165 status = ares_buf_fetch_bytes(buf, (unsigned char *)&addr, sizeof(addr)); 166 if (status != ARES_SUCCESS) { 167 return status; 168 } 169 170 return ares_dns_rr_set_addr(rr, ARES_RR_A_ADDR, &addr); 171 } 172 173 static ares_status_t ares_dns_parse_rr_ns(ares_buf_t *buf, ares_dns_rr_t *rr, 174 size_t rdlength) 175 { 176 (void)rdlength; /* Not needed */ 177 178 return ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, 179 ARES_RR_NS_NSDNAME); 180 } 181 182 static ares_status_t ares_dns_parse_rr_cname(ares_buf_t *buf, ares_dns_rr_t *rr, 183 size_t rdlength) 184 { 185 (void)rdlength; /* Not needed */ 186 187 return ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, 188 ARES_RR_CNAME_CNAME); 189 } 190 191 static ares_status_t ares_dns_parse_rr_soa(ares_buf_t *buf, ares_dns_rr_t *rr, 192 size_t rdlength) 193 { 194 ares_status_t status; 195 196 (void)rdlength; /* Not needed */ 197 198 /* MNAME */ 199 status = 200 ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, ARES_RR_SOA_MNAME); 201 if (status != ARES_SUCCESS) { 202 return status; 203 } 204 205 /* RNAME */ 206 status = 207 ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, ARES_RR_SOA_RNAME); 208 if (status != ARES_SUCCESS) { 209 return status; 210 } 211 212 /* SERIAL */ 213 status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SOA_SERIAL); 214 if (status != ARES_SUCCESS) { 215 return status; 216 } 217 218 /* REFRESH */ 219 status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SOA_REFRESH); 220 if (status != ARES_SUCCESS) { 221 return status; 222 } 223 224 /* RETRY */ 225 status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SOA_RETRY); 226 if (status != ARES_SUCCESS) { 227 return status; 228 } 229 230 /* EXPIRE */ 231 status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SOA_EXPIRE); 232 if (status != ARES_SUCCESS) { 233 return status; 234 } 235 236 /* MINIMUM */ 237 return ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SOA_MINIMUM); 238 } 239 240 static ares_status_t ares_dns_parse_rr_ptr(ares_buf_t *buf, ares_dns_rr_t *rr, 241 size_t rdlength) 242 { 243 (void)rdlength; /* Not needed */ 244 245 return ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, 246 ARES_RR_PTR_DNAME); 247 } 248 249 static ares_status_t ares_dns_parse_rr_hinfo(ares_buf_t *buf, ares_dns_rr_t *rr, 250 size_t rdlength) 251 { 252 ares_status_t status; 253 size_t orig_len = ares_buf_len(buf); 254 255 (void)rdlength; /* Not needed */ 256 257 /* CPU */ 258 status = ares_dns_parse_and_set_dns_str( 259 buf, ares_dns_rr_remaining_len(buf, orig_len, rdlength), rr, 260 ARES_RR_HINFO_CPU, ARES_TRUE); 261 if (status != ARES_SUCCESS) { 262 return status; 263 } 264 265 /* OS */ 266 status = ares_dns_parse_and_set_dns_str( 267 buf, ares_dns_rr_remaining_len(buf, orig_len, rdlength), rr, 268 ARES_RR_HINFO_OS, ARES_TRUE); 269 270 return status; 271 } 272 273 static ares_status_t ares_dns_parse_rr_mx(ares_buf_t *buf, ares_dns_rr_t *rr, 274 size_t rdlength) 275 { 276 ares_status_t status; 277 278 (void)rdlength; /* Not needed */ 279 280 /* PREFERENCE */ 281 status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_MX_PREFERENCE); 282 if (status != ARES_SUCCESS) { 283 return status; 284 } 285 286 /* EXCHANGE */ 287 return ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, 288 ARES_RR_MX_EXCHANGE); 289 } 290 291 static ares_status_t ares_dns_parse_rr_txt(ares_buf_t *buf, ares_dns_rr_t *rr, 292 size_t rdlength) 293 { 294 return ares_dns_parse_and_set_dns_abin(buf, rdlength, rr, ARES_RR_TXT_DATA, 295 ARES_FALSE); 296 } 297 298 static ares_status_t ares_dns_parse_rr_sig(ares_buf_t *buf, ares_dns_rr_t *rr, 299 size_t rdlength) 300 { 301 ares_status_t status; 302 size_t orig_len = ares_buf_len(buf); 303 size_t len; 304 unsigned char *data; 305 306 status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_SIG_TYPE_COVERED); 307 if (status != ARES_SUCCESS) { 308 return status; 309 } 310 311 status = ares_dns_parse_and_set_u8(buf, rr, ARES_RR_SIG_ALGORITHM); 312 if (status != ARES_SUCCESS) { 313 return status; 314 } 315 316 status = ares_dns_parse_and_set_u8(buf, rr, ARES_RR_SIG_LABELS); 317 if (status != ARES_SUCCESS) { 318 return status; 319 } 320 321 status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SIG_ORIGINAL_TTL); 322 if (status != ARES_SUCCESS) { 323 return status; 324 } 325 326 status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SIG_EXPIRATION); 327 if (status != ARES_SUCCESS) { 328 return status; 329 } 330 331 status = ares_dns_parse_and_set_be32(buf, rr, ARES_RR_SIG_INCEPTION); 332 if (status != ARES_SUCCESS) { 333 return status; 334 } 335 336 status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_SIG_KEY_TAG); 337 if (status != ARES_SUCCESS) { 338 return status; 339 } 340 341 status = ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, 342 ARES_RR_SIG_SIGNERS_NAME); 343 if (status != ARES_SUCCESS) { 344 return status; 345 } 346 347 len = ares_dns_rr_remaining_len(buf, orig_len, rdlength); 348 if (len == 0) { 349 return ARES_EBADRESP; 350 } 351 352 status = ares_buf_fetch_bytes_dup(buf, len, ARES_FALSE, &data); 353 if (status != ARES_SUCCESS) { 354 return status; 355 } 356 357 status = ares_dns_rr_set_bin_own(rr, ARES_RR_SIG_SIGNATURE, data, len); 358 if (status != ARES_SUCCESS) { 359 ares_free(data); 360 return status; 361 } 362 363 return ARES_SUCCESS; 364 } 365 366 static ares_status_t ares_dns_parse_rr_aaaa(ares_buf_t *buf, ares_dns_rr_t *rr, 367 size_t rdlength) 368 { 369 struct ares_in6_addr addr; 370 ares_status_t status; 371 372 (void)rdlength; /* Not needed */ 373 374 status = ares_buf_fetch_bytes(buf, (unsigned char *)&addr, sizeof(addr)); 375 if (status != ARES_SUCCESS) { 376 return status; 377 } 378 379 return ares_dns_rr_set_addr6(rr, ARES_RR_AAAA_ADDR, &addr); 380 } 381 382 static ares_status_t ares_dns_parse_rr_srv(ares_buf_t *buf, ares_dns_rr_t *rr, 383 size_t rdlength) 384 { 385 ares_status_t status; 386 387 (void)rdlength; /* Not needed */ 388 389 /* PRIORITY */ 390 status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_SRV_PRIORITY); 391 if (status != ARES_SUCCESS) { 392 return status; 393 } 394 395 /* WEIGHT */ 396 status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_SRV_WEIGHT); 397 if (status != ARES_SUCCESS) { 398 return status; 399 } 400 401 /* PORT */ 402 status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_SRV_PORT); 403 if (status != ARES_SUCCESS) { 404 return status; 405 } 406 407 /* TARGET */ 408 return ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, 409 ARES_RR_SRV_TARGET); 410 } 411 412 static ares_status_t ares_dns_parse_rr_naptr(ares_buf_t *buf, ares_dns_rr_t *rr, 413 size_t rdlength) 414 { 415 ares_status_t status; 416 size_t orig_len = ares_buf_len(buf); 417 418 /* ORDER */ 419 status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_NAPTR_ORDER); 420 if (status != ARES_SUCCESS) { 421 return status; 422 } 423 424 /* PREFERENCE */ 425 status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_NAPTR_PREFERENCE); 426 if (status != ARES_SUCCESS) { 427 return status; 428 } 429 430 /* FLAGS */ 431 status = ares_dns_parse_and_set_dns_str( 432 buf, ares_dns_rr_remaining_len(buf, orig_len, rdlength), rr, 433 ARES_RR_NAPTR_FLAGS, ARES_TRUE); 434 if (status != ARES_SUCCESS) { 435 return status; 436 } 437 438 /* SERVICES */ 439 status = ares_dns_parse_and_set_dns_str( 440 buf, ares_dns_rr_remaining_len(buf, orig_len, rdlength), rr, 441 ARES_RR_NAPTR_SERVICES, ARES_TRUE); 442 if (status != ARES_SUCCESS) { 443 return status; 444 } 445 446 /* REGEXP */ 447 status = ares_dns_parse_and_set_dns_str( 448 buf, ares_dns_rr_remaining_len(buf, orig_len, rdlength), rr, 449 ARES_RR_NAPTR_REGEXP, ARES_TRUE); 450 if (status != ARES_SUCCESS) { 451 return status; 452 } 453 454 /* REPLACEMENT */ 455 return ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, 456 ARES_RR_NAPTR_REPLACEMENT); 457 } 458 459 static ares_status_t ares_dns_parse_rr_opt(ares_buf_t *buf, ares_dns_rr_t *rr, 460 size_t rdlength, 461 unsigned short raw_class, 462 unsigned int raw_ttl) 463 { 464 ares_status_t status; 465 size_t orig_len = ares_buf_len(buf); 466 unsigned short rcode_high; 467 468 status = ares_dns_rr_set_u16(rr, ARES_RR_OPT_UDP_SIZE, raw_class); 469 if (status != ARES_SUCCESS) { 470 return status; 471 } 472 473 /* First 8 bits of TTL are an extended RCODE, and they go in the higher order 474 * after the original 4-bit rcode */ 475 rcode_high = (unsigned short)((raw_ttl >> 20) & 0x0FF0); 476 rr->parent->raw_rcode |= rcode_high; 477 478 status = ares_dns_rr_set_u8(rr, ARES_RR_OPT_VERSION, 479 (unsigned char)(raw_ttl >> 16) & 0xFF); 480 if (status != ARES_SUCCESS) { 481 return status; 482 } 483 484 status = ares_dns_rr_set_u16(rr, ARES_RR_OPT_FLAGS, 485 (unsigned short)(raw_ttl & 0xFFFF)); 486 if (status != ARES_SUCCESS) { 487 return status; 488 } 489 490 /* Parse options */ 491 while (ares_dns_rr_remaining_len(buf, orig_len, rdlength)) { 492 unsigned short opt = 0; 493 unsigned short len = 0; 494 unsigned char *val = NULL; 495 496 /* Fetch be16 option */ 497 status = ares_buf_fetch_be16(buf, &opt); 498 if (status != ARES_SUCCESS) { 499 return status; 500 } 501 502 /* Fetch be16 length */ 503 status = ares_buf_fetch_be16(buf, &len); 504 if (status != ARES_SUCCESS) { 505 return status; 506 } 507 508 if (len) { 509 status = ares_buf_fetch_bytes_dup(buf, len, ARES_TRUE, &val); 510 if (status != ARES_SUCCESS) { 511 return status; 512 } 513 } 514 515 status = ares_dns_rr_set_opt_own(rr, ARES_RR_OPT_OPTIONS, opt, val, len); 516 if (status != ARES_SUCCESS) { 517 return status; 518 } 519 } 520 521 return ARES_SUCCESS; 522 } 523 524 static ares_status_t ares_dns_parse_rr_tlsa(ares_buf_t *buf, ares_dns_rr_t *rr, 525 size_t rdlength) 526 { 527 ares_status_t status; 528 size_t orig_len = ares_buf_len(buf); 529 size_t len; 530 unsigned char *data; 531 532 status = ares_dns_parse_and_set_u8(buf, rr, ARES_RR_TLSA_CERT_USAGE); 533 if (status != ARES_SUCCESS) { 534 return status; 535 } 536 537 status = ares_dns_parse_and_set_u8(buf, rr, ARES_RR_TLSA_SELECTOR); 538 if (status != ARES_SUCCESS) { 539 return status; 540 } 541 542 status = ares_dns_parse_and_set_u8(buf, rr, ARES_RR_TLSA_MATCH); 543 if (status != ARES_SUCCESS) { 544 return status; 545 } 546 547 len = ares_dns_rr_remaining_len(buf, orig_len, rdlength); 548 if (len == 0) { 549 return ARES_EBADRESP; 550 } 551 552 status = ares_buf_fetch_bytes_dup(buf, len, ARES_FALSE, &data); 553 if (status != ARES_SUCCESS) { 554 return status; 555 } 556 557 status = ares_dns_rr_set_bin_own(rr, ARES_RR_TLSA_DATA, data, len); 558 if (status != ARES_SUCCESS) { 559 ares_free(data); 560 return status; 561 } 562 563 return ARES_SUCCESS; 564 } 565 566 static ares_status_t ares_dns_parse_rr_svcb(ares_buf_t *buf, ares_dns_rr_t *rr, 567 size_t rdlength) 568 { 569 ares_status_t status; 570 size_t orig_len = ares_buf_len(buf); 571 572 status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_SVCB_PRIORITY); 573 if (status != ARES_SUCCESS) { 574 return status; 575 } 576 577 status = 578 ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, ARES_RR_SVCB_TARGET); 579 if (status != ARES_SUCCESS) { 580 return status; 581 } 582 583 /* Parse params */ 584 while (ares_dns_rr_remaining_len(buf, orig_len, rdlength)) { 585 unsigned short opt = 0; 586 unsigned short len = 0; 587 unsigned char *val = NULL; 588 589 /* Fetch be16 option */ 590 status = ares_buf_fetch_be16(buf, &opt); 591 if (status != ARES_SUCCESS) { 592 return status; 593 } 594 595 /* Fetch be16 length */ 596 status = ares_buf_fetch_be16(buf, &len); 597 if (status != ARES_SUCCESS) { 598 return status; 599 } 600 601 if (len) { 602 status = ares_buf_fetch_bytes_dup(buf, len, ARES_TRUE, &val); 603 if (status != ARES_SUCCESS) { 604 return status; 605 } 606 } 607 608 status = ares_dns_rr_set_opt_own(rr, ARES_RR_SVCB_PARAMS, opt, val, len); 609 if (status != ARES_SUCCESS) { 610 return status; 611 } 612 } 613 614 return ARES_SUCCESS; 615 } 616 617 static ares_status_t ares_dns_parse_rr_https(ares_buf_t *buf, ares_dns_rr_t *rr, 618 size_t rdlength) 619 { 620 ares_status_t status; 621 size_t orig_len = ares_buf_len(buf); 622 623 status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_HTTPS_PRIORITY); 624 if (status != ARES_SUCCESS) { 625 return status; 626 } 627 628 status = 629 ares_dns_parse_and_set_dns_name(buf, ARES_FALSE, rr, ARES_RR_HTTPS_TARGET); 630 if (status != ARES_SUCCESS) { 631 return status; 632 } 633 634 /* Parse params */ 635 while (ares_dns_rr_remaining_len(buf, orig_len, rdlength)) { 636 unsigned short opt = 0; 637 unsigned short len = 0; 638 unsigned char *val = NULL; 639 640 /* Fetch be16 option */ 641 status = ares_buf_fetch_be16(buf, &opt); 642 if (status != ARES_SUCCESS) { 643 return status; 644 } 645 646 /* Fetch be16 length */ 647 status = ares_buf_fetch_be16(buf, &len); 648 if (status != ARES_SUCCESS) { 649 return status; 650 } 651 652 if (len) { 653 status = ares_buf_fetch_bytes_dup(buf, len, ARES_TRUE, &val); 654 if (status != ARES_SUCCESS) { 655 return status; 656 } 657 } 658 659 status = ares_dns_rr_set_opt_own(rr, ARES_RR_HTTPS_PARAMS, opt, val, len); 660 if (status != ARES_SUCCESS) { 661 return status; 662 } 663 } 664 665 return ARES_SUCCESS; 666 } 667 668 static ares_status_t ares_dns_parse_rr_uri(ares_buf_t *buf, ares_dns_rr_t *rr, 669 size_t rdlength) 670 { 671 char *name = NULL; 672 ares_status_t status; 673 size_t orig_len = ares_buf_len(buf); 674 size_t remaining_len; 675 676 /* PRIORITY */ 677 status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_URI_PRIORITY); 678 if (status != ARES_SUCCESS) { 679 return status; 680 } 681 682 /* WEIGHT */ 683 status = ares_dns_parse_and_set_be16(buf, rr, ARES_RR_URI_WEIGHT); 684 if (status != ARES_SUCCESS) { 685 return status; 686 } 687 688 /* TARGET -- not in string format, rest of buffer, required to be 689 * non-zero length */ 690 remaining_len = ares_dns_rr_remaining_len(buf, orig_len, rdlength); 691 if (remaining_len == 0) { 692 status = ARES_EBADRESP; 693 return status; 694 } 695 696 /* NOTE: Not in DNS string format */ 697 status = ares_buf_fetch_str_dup(buf, remaining_len, &name); 698 if (status != ARES_SUCCESS) { 699 return status; 700 } 701 702 if (!ares_str_isprint(name, remaining_len)) { 703 ares_free(name); 704 return ARES_EBADRESP; 705 } 706 707 status = ares_dns_rr_set_str_own(rr, ARES_RR_URI_TARGET, name); 708 if (status != ARES_SUCCESS) { 709 ares_free(name); 710 return status; 711 } 712 name = NULL; 713 714 return ARES_SUCCESS; 715 } 716 717 static ares_status_t ares_dns_parse_rr_caa(ares_buf_t *buf, ares_dns_rr_t *rr, 718 size_t rdlength) 719 { 720 unsigned char *data = NULL; 721 size_t data_len = 0; 722 ares_status_t status; 723 size_t orig_len = ares_buf_len(buf); 724 725 /* CRITICAL */ 726 status = ares_dns_parse_and_set_u8(buf, rr, ARES_RR_CAA_CRITICAL); 727 if (status != ARES_SUCCESS) { 728 return status; 729 } 730 731 /* Tag */ 732 status = ares_dns_parse_and_set_dns_str( 733 buf, ares_dns_rr_remaining_len(buf, orig_len, rdlength), rr, 734 ARES_RR_CAA_TAG, ARES_FALSE); 735 if (status != ARES_SUCCESS) { 736 return status; 737 } 738 739 /* Value - binary! (remaining buffer */ 740 data_len = ares_dns_rr_remaining_len(buf, orig_len, rdlength); 741 if (data_len == 0) { 742 status = ARES_EBADRESP; 743 return status; 744 } 745 status = ares_buf_fetch_bytes_dup(buf, data_len, ARES_TRUE, &data); 746 if (status != ARES_SUCCESS) { 747 return status; 748 } 749 750 status = ares_dns_rr_set_bin_own(rr, ARES_RR_CAA_VALUE, data, data_len); 751 if (status != ARES_SUCCESS) { 752 ares_free(data); 753 return status; 754 } 755 data = NULL; 756 757 return ARES_SUCCESS; 758 } 759 760 static ares_status_t ares_dns_parse_rr_raw_rr(ares_buf_t *buf, 761 ares_dns_rr_t *rr, 762 size_t rdlength, 763 unsigned short raw_type) 764 { 765 ares_status_t status; 766 unsigned char *bytes = NULL; 767 768 if (rdlength == 0) { 769 return ARES_SUCCESS; 770 } 771 772 status = ares_buf_fetch_bytes_dup(buf, rdlength, ARES_FALSE, &bytes); 773 if (status != ARES_SUCCESS) { 774 return status; 775 } 776 777 /* Can't fail */ 778 status = ares_dns_rr_set_u16(rr, ARES_RR_RAW_RR_TYPE, raw_type); 779 if (status != ARES_SUCCESS) { 780 ares_free(bytes); 781 return status; 782 } 783 784 status = ares_dns_rr_set_bin_own(rr, ARES_RR_RAW_RR_DATA, bytes, rdlength); 785 if (status != ARES_SUCCESS) { 786 ares_free(bytes); 787 return status; 788 } 789 790 return ARES_SUCCESS; 791 } 792 793 static ares_status_t ares_dns_parse_header(ares_buf_t *buf, unsigned int flags, 794 ares_dns_record_t **dnsrec, 795 unsigned short *qdcount, 796 unsigned short *ancount, 797 unsigned short *nscount, 798 unsigned short *arcount) 799 { 800 ares_status_t status = ARES_EBADRESP; 801 unsigned short u16; 802 unsigned short id; 803 unsigned short dns_flags = 0; 804 ares_dns_opcode_t opcode; 805 unsigned short rcode; 806 807 (void)flags; /* currently unused */ 808 809 if (buf == NULL || dnsrec == NULL || qdcount == NULL || ancount == NULL || 810 nscount == NULL || arcount == NULL) { 811 return ARES_EFORMERR; 812 } 813 814 *dnsrec = NULL; 815 816 /* 817 * RFC 1035 4.1.1. Header section format. 818 * and Updated by RFC 2065 to add AD and CD bits. 819 * 1 1 1 1 1 1 820 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 821 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 822 * | ID | 823 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 824 * |QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE | 825 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 826 * | QDCOUNT | 827 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 828 * | ANCOUNT | 829 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 830 * | NSCOUNT | 831 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 832 * | ARCOUNT | 833 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 834 */ 835 836 /* ID */ 837 status = ares_buf_fetch_be16(buf, &id); 838 if (status != ARES_SUCCESS) { 839 goto fail; 840 } 841 842 /* Flags */ 843 status = ares_buf_fetch_be16(buf, &u16); 844 if (status != ARES_SUCCESS) { 845 goto fail; 846 } 847 848 /* QR */ 849 if (u16 & 0x8000) { 850 dns_flags |= ARES_FLAG_QR; 851 } 852 853 /* OPCODE */ 854 opcode = (u16 >> 11) & 0xf; 855 856 /* AA */ 857 if (u16 & 0x400) { 858 dns_flags |= ARES_FLAG_AA; 859 } 860 861 /* TC */ 862 if (u16 & 0x200) { 863 dns_flags |= ARES_FLAG_TC; 864 } 865 866 /* RD */ 867 if (u16 & 0x100) { 868 dns_flags |= ARES_FLAG_RD; 869 } 870 871 /* RA */ 872 if (u16 & 0x80) { 873 dns_flags |= ARES_FLAG_RA; 874 } 875 876 /* Z -- unused */ 877 878 /* AD */ 879 if (u16 & 0x20) { 880 dns_flags |= ARES_FLAG_AD; 881 } 882 883 /* CD */ 884 if (u16 & 0x10) { 885 dns_flags |= ARES_FLAG_CD; 886 } 887 888 /* RCODE */ 889 rcode = u16 & 0xf; 890 891 /* QDCOUNT */ 892 status = ares_buf_fetch_be16(buf, qdcount); 893 if (status != ARES_SUCCESS) { 894 goto fail; 895 } 896 897 /* ANCOUNT */ 898 status = ares_buf_fetch_be16(buf, ancount); 899 if (status != ARES_SUCCESS) { 900 goto fail; 901 } 902 903 /* NSCOUNT */ 904 status = ares_buf_fetch_be16(buf, nscount); 905 if (status != ARES_SUCCESS) { 906 goto fail; 907 } 908 909 /* ARCOUNT */ 910 status = ares_buf_fetch_be16(buf, arcount); 911 if (status != ARES_SUCCESS) { 912 goto fail; 913 } 914 915 status = ares_dns_record_create(dnsrec, id, dns_flags, opcode, 916 ARES_RCODE_NOERROR /* Temporary */); 917 if (status != ARES_SUCCESS) { 918 goto fail; 919 } 920 921 (*dnsrec)->raw_rcode = rcode; 922 923 if (*ancount > 0) { 924 status = 925 ares_dns_record_rr_prealloc(*dnsrec, ARES_SECTION_ANSWER, *ancount); 926 if (status != ARES_SUCCESS) { 927 goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ 928 } 929 } 930 931 if (*nscount > 0) { 932 status = 933 ares_dns_record_rr_prealloc(*dnsrec, ARES_SECTION_AUTHORITY, *nscount); 934 if (status != ARES_SUCCESS) { 935 goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ 936 } 937 } 938 939 if (*arcount > 0) { 940 status = 941 ares_dns_record_rr_prealloc(*dnsrec, ARES_SECTION_ADDITIONAL, *arcount); 942 if (status != ARES_SUCCESS) { 943 goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ 944 } 945 } 946 947 return ARES_SUCCESS; 948 949 fail: 950 ares_dns_record_destroy(*dnsrec); 951 *dnsrec = NULL; 952 *qdcount = 0; 953 *ancount = 0; 954 *nscount = 0; 955 *arcount = 0; 956 957 return status; 958 } 959 960 static ares_status_t 961 ares_dns_parse_rr_data(ares_buf_t *buf, size_t rdlength, ares_dns_rr_t *rr, 962 ares_dns_rec_type_t type, unsigned short raw_type, 963 unsigned short raw_class, unsigned int raw_ttl) 964 { 965 switch (type) { 966 case ARES_REC_TYPE_A: 967 return ares_dns_parse_rr_a(buf, rr, rdlength); 968 case ARES_REC_TYPE_NS: 969 return ares_dns_parse_rr_ns(buf, rr, rdlength); 970 case ARES_REC_TYPE_CNAME: 971 return ares_dns_parse_rr_cname(buf, rr, rdlength); 972 case ARES_REC_TYPE_SOA: 973 return ares_dns_parse_rr_soa(buf, rr, rdlength); 974 case ARES_REC_TYPE_PTR: 975 return ares_dns_parse_rr_ptr(buf, rr, rdlength); 976 case ARES_REC_TYPE_HINFO: 977 return ares_dns_parse_rr_hinfo(buf, rr, rdlength); 978 case ARES_REC_TYPE_MX: 979 return ares_dns_parse_rr_mx(buf, rr, rdlength); 980 case ARES_REC_TYPE_TXT: 981 return ares_dns_parse_rr_txt(buf, rr, rdlength); 982 case ARES_REC_TYPE_SIG: 983 return ares_dns_parse_rr_sig(buf, rr, rdlength); 984 case ARES_REC_TYPE_AAAA: 985 return ares_dns_parse_rr_aaaa(buf, rr, rdlength); 986 case ARES_REC_TYPE_SRV: 987 return ares_dns_parse_rr_srv(buf, rr, rdlength); 988 case ARES_REC_TYPE_NAPTR: 989 return ares_dns_parse_rr_naptr(buf, rr, rdlength); 990 case ARES_REC_TYPE_ANY: 991 return ARES_EBADRESP; 992 case ARES_REC_TYPE_OPT: 993 return ares_dns_parse_rr_opt(buf, rr, rdlength, raw_class, raw_ttl); 994 case ARES_REC_TYPE_TLSA: 995 return ares_dns_parse_rr_tlsa(buf, rr, rdlength); 996 case ARES_REC_TYPE_SVCB: 997 return ares_dns_parse_rr_svcb(buf, rr, rdlength); 998 case ARES_REC_TYPE_HTTPS: 999 return ares_dns_parse_rr_https(buf, rr, rdlength); 1000 case ARES_REC_TYPE_URI: 1001 return ares_dns_parse_rr_uri(buf, rr, rdlength); 1002 case ARES_REC_TYPE_CAA: 1003 return ares_dns_parse_rr_caa(buf, rr, rdlength); 1004 case ARES_REC_TYPE_RAW_RR: 1005 return ares_dns_parse_rr_raw_rr(buf, rr, rdlength, raw_type); 1006 } 1007 return ARES_EFORMERR; 1008 } 1009 1010 static ares_status_t ares_dns_parse_qd(ares_buf_t *buf, 1011 ares_dns_record_t *dnsrec) 1012 { 1013 char *name = NULL; 1014 unsigned short u16; 1015 ares_status_t status; 1016 ares_dns_rec_type_t type; 1017 ares_dns_class_t qclass; 1018 /* The question section is used to carry the "question" in most queries, 1019 * i.e., the parameters that define what is being asked. The section 1020 * contains QDCOUNT (usually 1) entries, each of the following format: 1021 * 1 1 1 1 1 1 1022 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 1023 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 1024 * | | 1025 * / QNAME / 1026 * / / 1027 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 1028 * | QTYPE | 1029 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 1030 * | QCLASS | 1031 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 1032 */ 1033 1034 /* Name */ 1035 status = ares_dns_name_parse(buf, &name, ARES_FALSE); 1036 if (status != ARES_SUCCESS) { 1037 goto done; 1038 } 1039 1040 /* Type */ 1041 status = ares_buf_fetch_be16(buf, &u16); 1042 if (status != ARES_SUCCESS) { 1043 goto done; 1044 } 1045 type = u16; 1046 1047 /* Class */ 1048 status = ares_buf_fetch_be16(buf, &u16); 1049 if (status != ARES_SUCCESS) { 1050 goto done; 1051 } 1052 qclass = u16; 1053 1054 /* Add question */ 1055 status = ares_dns_record_query_add(dnsrec, name, type, qclass); 1056 if (status != ARES_SUCCESS) { 1057 goto done; 1058 } 1059 1060 done: 1061 ares_free(name); 1062 return status; 1063 } 1064 1065 static ares_status_t ares_dns_parse_rr(ares_buf_t *buf, unsigned int flags, 1066 ares_dns_section_t sect, 1067 ares_dns_record_t *dnsrec) 1068 { 1069 char *name = NULL; 1070 unsigned short u16; 1071 unsigned short raw_type; 1072 ares_status_t status; 1073 ares_dns_rec_type_t type; 1074 ares_dns_class_t qclass; 1075 unsigned int ttl; 1076 size_t rdlength; 1077 ares_dns_rr_t *rr = NULL; 1078 size_t remaining_len = 0; 1079 size_t processed_len = 0; 1080 ares_bool_t namecomp; 1081 1082 /* All RRs have the same top level format shown below: 1083 * 1 1 1 1 1 1 1084 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 1085 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 1086 * | | 1087 * / / 1088 * / NAME / 1089 * | | 1090 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 1091 * | TYPE | 1092 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 1093 * | CLASS | 1094 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 1095 * | TTL | 1096 * | | 1097 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 1098 * | RDLENGTH | 1099 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| 1100 * / RDATA / 1101 * / / 1102 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 1103 */ 1104 1105 /* Name */ 1106 status = ares_dns_name_parse(buf, &name, ARES_FALSE); 1107 if (status != ARES_SUCCESS) { 1108 goto done; 1109 } 1110 1111 /* Type */ 1112 status = ares_buf_fetch_be16(buf, &u16); 1113 if (status != ARES_SUCCESS) { 1114 goto done; 1115 } 1116 type = u16; 1117 raw_type = u16; /* Only used for raw rr data */ 1118 1119 /* Class */ 1120 status = ares_buf_fetch_be16(buf, &u16); 1121 if (status != ARES_SUCCESS) { 1122 goto done; 1123 } 1124 qclass = u16; 1125 1126 /* TTL */ 1127 status = ares_buf_fetch_be32(buf, &ttl); 1128 if (status != ARES_SUCCESS) { 1129 goto done; 1130 } 1131 1132 /* Length */ 1133 status = ares_buf_fetch_be16(buf, &u16); 1134 if (status != ARES_SUCCESS) { 1135 goto done; 1136 } 1137 rdlength = u16; 1138 1139 if (!ares_dns_rec_type_isvalid(type, ARES_FALSE)) { 1140 type = ARES_REC_TYPE_RAW_RR; 1141 } 1142 1143 namecomp = ares_dns_rec_allow_name_comp(type); 1144 if (sect == ARES_SECTION_ANSWER && 1145 (flags & 1146 (namecomp ? ARES_DNS_PARSE_AN_BASE_RAW : ARES_DNS_PARSE_AN_EXT_RAW))) { 1147 type = ARES_REC_TYPE_RAW_RR; 1148 } 1149 if (sect == ARES_SECTION_AUTHORITY && 1150 (flags & 1151 (namecomp ? ARES_DNS_PARSE_NS_BASE_RAW : ARES_DNS_PARSE_NS_EXT_RAW))) { 1152 type = ARES_REC_TYPE_RAW_RR; 1153 } 1154 if (sect == ARES_SECTION_ADDITIONAL && 1155 (flags & 1156 (namecomp ? ARES_DNS_PARSE_AR_BASE_RAW : ARES_DNS_PARSE_AR_EXT_RAW))) { 1157 type = ARES_REC_TYPE_RAW_RR; 1158 } 1159 1160 /* Pull into another buffer for safety */ 1161 if (rdlength > ares_buf_len(buf)) { 1162 status = ARES_EBADRESP; 1163 goto done; 1164 } 1165 1166 /* Add the base rr */ 1167 status = 1168 ares_dns_record_rr_add(&rr, dnsrec, sect, name, type, 1169 type == ARES_REC_TYPE_OPT ? ARES_CLASS_IN : qclass, 1170 type == ARES_REC_TYPE_OPT ? 0 : ttl); 1171 if (status != ARES_SUCCESS) { 1172 goto done; 1173 } 1174 1175 /* Record the current remaining length in the buffer so we can tell how 1176 * much was processed */ 1177 remaining_len = ares_buf_len(buf); 1178 1179 /* Fill in the data for the rr */ 1180 status = ares_dns_parse_rr_data(buf, rdlength, rr, type, raw_type, 1181 (unsigned short)qclass, ttl); 1182 if (status != ARES_SUCCESS) { 1183 goto done; 1184 } 1185 1186 /* Determine how many bytes were processed */ 1187 processed_len = remaining_len - ares_buf_len(buf); 1188 1189 /* If too many bytes were processed, error! */ 1190 if (processed_len > rdlength) { 1191 status = ARES_EBADRESP; 1192 goto done; 1193 } 1194 1195 /* If too few bytes were processed, consume the unprocessed data for this 1196 * record as the parser may not have wanted/needed to use it */ 1197 if (processed_len < rdlength) { 1198 ares_buf_consume(buf, rdlength - processed_len); 1199 } 1200 1201 1202 done: 1203 ares_free(name); 1204 return status; 1205 } 1206 1207 static ares_status_t ares_dns_parse_buf(ares_buf_t *buf, unsigned int flags, 1208 ares_dns_record_t **dnsrec) 1209 { 1210 ares_status_t status; 1211 unsigned short qdcount; 1212 unsigned short ancount; 1213 unsigned short nscount; 1214 unsigned short arcount; 1215 unsigned short i; 1216 1217 if (buf == NULL || dnsrec == NULL) { 1218 return ARES_EFORMERR; /* LCOV_EXCL_LINE: DefensiveCoding */ 1219 } 1220 1221 /* Maximum DNS packet size is 64k, even over TCP */ 1222 if (ares_buf_len(buf) > 0xFFFF) { 1223 return ARES_EFORMERR; 1224 } 1225 1226 /* All communications inside of the domain protocol are carried in a single 1227 * format called a message. The top level format of message is divided 1228 * into 5 sections (some of which are empty in certain cases) shown below: 1229 * 1230 * +---------------------+ 1231 * | Header | 1232 * +---------------------+ 1233 * | Question | the question for the name server 1234 * +---------------------+ 1235 * | Answer | RRs answering the question 1236 * +---------------------+ 1237 * | Authority | RRs pointing toward an authority 1238 * +---------------------+ 1239 * | Additional | RRs holding additional information 1240 * +---------------------+ 1241 */ 1242 1243 /* Parse header */ 1244 status = ares_dns_parse_header(buf, flags, dnsrec, &qdcount, &ancount, 1245 &nscount, &arcount); 1246 if (status != ARES_SUCCESS) { 1247 goto fail; 1248 } 1249 1250 /* Must have questions */ 1251 if (qdcount == 0) { 1252 status = ARES_EBADRESP; 1253 goto fail; 1254 } 1255 1256 /* XXX: this should be controlled by a flag in case we want to allow 1257 * multiple questions. I think mDNS allows this */ 1258 if (qdcount > 1) { 1259 status = ARES_EBADRESP; 1260 goto fail; 1261 } 1262 1263 /* Parse questions */ 1264 for (i = 0; i < qdcount; i++) { 1265 status = ares_dns_parse_qd(buf, *dnsrec); 1266 if (status != ARES_SUCCESS) { 1267 goto fail; 1268 } 1269 } 1270 1271 /* Parse Answers */ 1272 for (i = 0; i < ancount; i++) { 1273 status = ares_dns_parse_rr(buf, flags, ARES_SECTION_ANSWER, *dnsrec); 1274 if (status != ARES_SUCCESS) { 1275 goto fail; 1276 } 1277 } 1278 1279 /* Parse Authority */ 1280 for (i = 0; i < nscount; i++) { 1281 status = ares_dns_parse_rr(buf, flags, ARES_SECTION_AUTHORITY, *dnsrec); 1282 if (status != ARES_SUCCESS) { 1283 goto fail; 1284 } 1285 } 1286 1287 /* Parse Additional */ 1288 for (i = 0; i < arcount; i++) { 1289 status = ares_dns_parse_rr(buf, flags, ARES_SECTION_ADDITIONAL, *dnsrec); 1290 if (status != ARES_SUCCESS) { 1291 goto fail; 1292 } 1293 } 1294 1295 /* Finalize rcode now that if we have OPT it is processed */ 1296 if (!ares_dns_rcode_isvalid((*dnsrec)->raw_rcode)) { 1297 (*dnsrec)->rcode = ARES_RCODE_SERVFAIL; 1298 } else { 1299 (*dnsrec)->rcode = (ares_dns_rcode_t)(*dnsrec)->raw_rcode; 1300 } 1301 1302 return ARES_SUCCESS; 1303 1304 fail: 1305 ares_dns_record_destroy(*dnsrec); 1306 *dnsrec = NULL; 1307 return status; 1308 } 1309 1310 ares_status_t ares_dns_parse(const unsigned char *buf, size_t buf_len, 1311 unsigned int flags, ares_dns_record_t **dnsrec) 1312 { 1313 ares_buf_t *parser = NULL; 1314 ares_status_t status; 1315 1316 if (buf == NULL || buf_len == 0 || dnsrec == NULL) { 1317 return ARES_EFORMERR; 1318 } 1319 1320 parser = ares_buf_create_const(buf, buf_len); 1321 if (parser == NULL) { 1322 return ARES_ENOMEM; 1323 } 1324 1325 status = ares_dns_parse_buf(parser, flags, dnsrec); 1326 ares_buf_destroy(parser); 1327 1328 return status; 1329 }