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_setup.h" 27#include "ares.h" 28#include "ares_private.h" 29 30ares_bool_t ares_dns_opcode_isvalid(ares_dns_opcode_t opcode) 31{ 32 switch (opcode) { 33 case ARES_OPCODE_QUERY: 34 case ARES_OPCODE_IQUERY: 35 case ARES_OPCODE_STATUS: 36 case ARES_OPCODE_NOTIFY: 37 case ARES_OPCODE_UPDATE: 38 return ARES_TRUE; 39 } 40 return ARES_FALSE; 41} 42 43ares_bool_t ares_dns_rcode_isvalid(ares_dns_rcode_t rcode) 44{ 45 switch (rcode) { 46 case ARES_RCODE_NOERROR: 47 case ARES_RCODE_FORMERR: 48 case ARES_RCODE_SERVFAIL: 49 case ARES_RCODE_NXDOMAIN: 50 case ARES_RCODE_NOTIMP: 51 case ARES_RCODE_REFUSED: 52 case ARES_RCODE_YXDOMAIN: 53 case ARES_RCODE_YXRRSET: 54 case ARES_RCODE_NXRRSET: 55 case ARES_RCODE_NOTAUTH: 56 case ARES_RCODE_NOTZONE: 57 case ARES_RCODE_DSOTYPEI: 58 case ARES_RCODE_BADSIG: 59 case ARES_RCODE_BADKEY: 60 case ARES_RCODE_BADTIME: 61 case ARES_RCODE_BADMODE: 62 case ARES_RCODE_BADNAME: 63 case ARES_RCODE_BADALG: 64 case ARES_RCODE_BADTRUNC: 65 case ARES_RCODE_BADCOOKIE: 66 return ARES_TRUE; 67 } 68 return ARES_FALSE; 69} 70 71ares_bool_t ares_dns_flags_arevalid(unsigned short flags) 72{ 73 unsigned short allflags = ARES_FLAG_QR | ARES_FLAG_AA | ARES_FLAG_TC | 74 ARES_FLAG_RD | ARES_FLAG_RA | ARES_FLAG_AD | 75 ARES_FLAG_CD; 76 77 if (flags & ~allflags) { 78 return ARES_FALSE; 79 } 80 81 return ARES_TRUE; 82} 83 84ares_bool_t ares_dns_rec_type_isvalid(ares_dns_rec_type_t type, 85 ares_bool_t is_query) 86{ 87 switch (type) { 88 case ARES_REC_TYPE_A: 89 case ARES_REC_TYPE_NS: 90 case ARES_REC_TYPE_CNAME: 91 case ARES_REC_TYPE_SOA: 92 case ARES_REC_TYPE_PTR: 93 case ARES_REC_TYPE_HINFO: 94 case ARES_REC_TYPE_MX: 95 case ARES_REC_TYPE_TXT: 96 case ARES_REC_TYPE_AAAA: 97 case ARES_REC_TYPE_SRV: 98 case ARES_REC_TYPE_NAPTR: 99 case ARES_REC_TYPE_OPT: 100 case ARES_REC_TYPE_TLSA: 101 case ARES_REC_TYPE_SVCB: 102 case ARES_REC_TYPE_HTTPS: 103 case ARES_REC_TYPE_ANY: 104 case ARES_REC_TYPE_URI: 105 case ARES_REC_TYPE_CAA: 106 return ARES_TRUE; 107 case ARES_REC_TYPE_RAW_RR: 108 return is_query ? ARES_FALSE : ARES_TRUE; 109 default: 110 break; 111 } 112 return is_query ? ARES_TRUE : ARES_FALSE; 113} 114 115ares_bool_t ares_dns_rec_type_allow_name_compression(ares_dns_rec_type_t type) 116{ 117 /* Only record types defined in RFC1035 allow name compression within the 118 * RDATA. Otherwise nameservers that don't understand an RR may not be 119 * able to pass along the RR in a proper manner */ 120 switch (type) { 121 case ARES_REC_TYPE_A: 122 case ARES_REC_TYPE_NS: 123 case ARES_REC_TYPE_CNAME: 124 case ARES_REC_TYPE_SOA: 125 case ARES_REC_TYPE_PTR: 126 case ARES_REC_TYPE_HINFO: 127 case ARES_REC_TYPE_MX: 128 case ARES_REC_TYPE_TXT: 129 return ARES_TRUE; 130 default: 131 break; 132 } 133 return ARES_FALSE; 134} 135 136ares_bool_t ares_dns_class_isvalid(ares_dns_class_t qclass, 137 ares_bool_t is_query) 138{ 139 switch (qclass) { 140 case ARES_CLASS_IN: 141 case ARES_CLASS_CHAOS: 142 case ARES_CLASS_HESOID: 143 case ARES_CLASS_NONE: 144 return ARES_TRUE; 145 case ARES_CLASS_ANY: 146 return is_query ? ARES_TRUE : ARES_FALSE; 147 } 148 return ARES_FALSE; 149} 150 151ares_bool_t ares_dns_section_isvalid(ares_dns_section_t sect) 152{ 153 switch (sect) { 154 case ARES_SECTION_ANSWER: 155 case ARES_SECTION_AUTHORITY: 156 case ARES_SECTION_ADDITIONAL: 157 return ARES_TRUE; 158 } 159 return ARES_FALSE; 160} 161 162ares_dns_rec_type_t ares_dns_rr_key_to_rec_type(ares_dns_rr_key_t key) 163{ 164 /* NOTE: due to the way we've numerated the keys, we can simply divide by 165 * 100 to get the type rather than having to do a huge switch 166 * statement. That said, we do then validate the type returned is 167 * valid in case something completely bogus is passed in */ 168 ares_dns_rec_type_t type = key / 100; 169 if (!ares_dns_rec_type_isvalid(type, ARES_FALSE)) { 170 return 0; 171 } 172 return type; 173} 174 175const char *ares_dns_rec_type_tostr(ares_dns_rec_type_t type) 176{ 177 switch (type) { 178 case ARES_REC_TYPE_A: 179 return "A"; 180 case ARES_REC_TYPE_NS: 181 return "NS"; 182 case ARES_REC_TYPE_CNAME: 183 return "CNAME"; 184 case ARES_REC_TYPE_SOA: 185 return "SOA"; 186 case ARES_REC_TYPE_PTR: 187 return "PTR"; 188 case ARES_REC_TYPE_HINFO: 189 return "HINFO"; 190 case ARES_REC_TYPE_MX: 191 return "MX"; 192 case ARES_REC_TYPE_TXT: 193 return "TXT"; 194 case ARES_REC_TYPE_AAAA: 195 return "AAAA"; 196 case ARES_REC_TYPE_SRV: 197 return "SRV"; 198 case ARES_REC_TYPE_NAPTR: 199 return "NAPTR"; 200 case ARES_REC_TYPE_OPT: 201 return "OPT"; 202 case ARES_REC_TYPE_TLSA: 203 return "TLSA"; 204 case ARES_REC_TYPE_SVCB: 205 return "SVCB"; 206 case ARES_REC_TYPE_HTTPS: 207 return "HTTPS"; 208 case ARES_REC_TYPE_ANY: 209 return "ANY"; 210 case ARES_REC_TYPE_URI: 211 return "URI"; 212 case ARES_REC_TYPE_CAA: 213 return "CAA"; 214 case ARES_REC_TYPE_RAW_RR: 215 return "RAWRR"; 216 } 217 return "UNKNOWN"; 218} 219 220const char *ares_dns_class_tostr(ares_dns_class_t qclass) 221{ 222 switch (qclass) { 223 case ARES_CLASS_IN: 224 return "IN"; 225 case ARES_CLASS_CHAOS: 226 return "CH"; 227 case ARES_CLASS_HESOID: 228 return "HS"; 229 case ARES_CLASS_ANY: 230 return "ANY"; 231 case ARES_CLASS_NONE: 232 return "NONE"; 233 } 234 return "UNKNOWN"; 235} 236 237const char *ares_dns_opcode_tostr(ares_dns_opcode_t opcode) 238{ 239 switch (opcode) { 240 case ARES_OPCODE_QUERY: 241 return "QUERY"; 242 case ARES_OPCODE_IQUERY: 243 return "IQUERY"; 244 case ARES_OPCODE_STATUS: 245 return "STATUS"; 246 case ARES_OPCODE_NOTIFY: 247 return "NOTIFY"; 248 case ARES_OPCODE_UPDATE: 249 return "UPDATE"; 250 } 251 return "UNKNOWN"; 252} 253 254const char *ares_dns_rr_key_tostr(ares_dns_rr_key_t key) 255{ 256 switch (key) { 257 case ARES_RR_A_ADDR: 258 return "ADDR"; 259 260 case ARES_RR_NS_NSDNAME: 261 return "NSDNAME"; 262 263 case ARES_RR_CNAME_CNAME: 264 return "CNAME"; 265 266 case ARES_RR_SOA_MNAME: 267 return "MNAME"; 268 269 case ARES_RR_SOA_RNAME: 270 return "RNAME"; 271 272 case ARES_RR_SOA_SERIAL: 273 return "SERIAL"; 274 275 case ARES_RR_SOA_REFRESH: 276 return "REFRESH"; 277 278 case ARES_RR_SOA_RETRY: 279 return "RETRY"; 280 281 case ARES_RR_SOA_EXPIRE: 282 return "EXPIRE"; 283 284 case ARES_RR_SOA_MINIMUM: 285 return "MINIMUM"; 286 287 case ARES_RR_PTR_DNAME: 288 return "DNAME"; 289 290 case ARES_RR_AAAA_ADDR: 291 return "ADDR"; 292 293 case ARES_RR_HINFO_CPU: 294 return "CPU"; 295 296 case ARES_RR_HINFO_OS: 297 return "OS"; 298 299 case ARES_RR_MX_PREFERENCE: 300 return "PREFERENCE"; 301 302 case ARES_RR_MX_EXCHANGE: 303 return "EXCHANGE"; 304 305 case ARES_RR_TXT_DATA: 306 return "DATA"; 307 308 case ARES_RR_SRV_PRIORITY: 309 return "PRIORITY"; 310 311 case ARES_RR_SRV_WEIGHT: 312 return "WEIGHT"; 313 314 case ARES_RR_SRV_PORT: 315 return "PORT"; 316 317 case ARES_RR_SRV_TARGET: 318 return "TARGET"; 319 320 case ARES_RR_NAPTR_ORDER: 321 return "ORDER"; 322 323 case ARES_RR_NAPTR_PREFERENCE: 324 return "PREFERENCE"; 325 326 case ARES_RR_NAPTR_FLAGS: 327 return "FLAGS"; 328 329 case ARES_RR_NAPTR_SERVICES: 330 return "SERVICES"; 331 332 case ARES_RR_NAPTR_REGEXP: 333 return "REGEXP"; 334 335 case ARES_RR_NAPTR_REPLACEMENT: 336 return "REPLACEMENT"; 337 338 case ARES_RR_OPT_UDP_SIZE: 339 return "UDP_SIZE"; 340 341 case ARES_RR_OPT_VERSION: 342 return "VERSION"; 343 344 case ARES_RR_OPT_FLAGS: 345 return "FLAGS"; 346 347 case ARES_RR_OPT_OPTIONS: 348 return "OPTIONS"; 349 350 case ARES_RR_TLSA_CERT_USAGE: 351 return "CERT_USAGE"; 352 353 case ARES_RR_TLSA_SELECTOR: 354 return "SELECTOR"; 355 356 case ARES_RR_TLSA_MATCH: 357 return "MATCH"; 358 359 case ARES_RR_TLSA_DATA: 360 return "DATA"; 361 362 case ARES_RR_SVCB_PRIORITY: 363 return "PRIORITY"; 364 365 case ARES_RR_SVCB_TARGET: 366 return "TARGET"; 367 368 case ARES_RR_SVCB_PARAMS: 369 return "PARAMS"; 370 371 case ARES_RR_HTTPS_PRIORITY: 372 return "PRIORITY"; 373 374 case ARES_RR_HTTPS_TARGET: 375 return "TARGET"; 376 377 case ARES_RR_HTTPS_PARAMS: 378 return "PARAMS"; 379 380 case ARES_RR_URI_PRIORITY: 381 return "PRIORITY"; 382 383 case ARES_RR_URI_WEIGHT: 384 return "WEIGHT"; 385 386 case ARES_RR_URI_TARGET: 387 return "TARGET"; 388 389 case ARES_RR_CAA_CRITICAL: 390 return "CRITICAL"; 391 392 case ARES_RR_CAA_TAG: 393 return "TAG"; 394 395 case ARES_RR_CAA_VALUE: 396 return "VALUE"; 397 398 case ARES_RR_RAW_RR_TYPE: 399 return "TYPE"; 400 401 case ARES_RR_RAW_RR_DATA: 402 return "DATA"; 403 } 404 405 return "UNKNOWN"; 406} 407 408ares_dns_datatype_t ares_dns_rr_key_datatype(ares_dns_rr_key_t key) 409{ 410 switch (key) { 411 case ARES_RR_A_ADDR: 412 return ARES_DATATYPE_INADDR; 413 414 case ARES_RR_AAAA_ADDR: 415 return ARES_DATATYPE_INADDR6; 416 417 case ARES_RR_NS_NSDNAME: 418 case ARES_RR_CNAME_CNAME: 419 case ARES_RR_SOA_MNAME: 420 case ARES_RR_SOA_RNAME: 421 case ARES_RR_PTR_DNAME: 422 case ARES_RR_MX_EXCHANGE: 423 case ARES_RR_SRV_TARGET: 424 case ARES_RR_SVCB_TARGET: 425 case ARES_RR_HTTPS_TARGET: 426 case ARES_RR_NAPTR_REPLACEMENT: 427 case ARES_RR_URI_TARGET: 428 return ARES_DATATYPE_NAME; 429 430 case ARES_RR_HINFO_CPU: 431 case ARES_RR_HINFO_OS: 432 case ARES_RR_NAPTR_FLAGS: 433 case ARES_RR_NAPTR_SERVICES: 434 case ARES_RR_NAPTR_REGEXP: 435 case ARES_RR_CAA_TAG: 436 return ARES_DATATYPE_STR; 437 438 case ARES_RR_SOA_SERIAL: 439 case ARES_RR_SOA_REFRESH: 440 case ARES_RR_SOA_RETRY: 441 case ARES_RR_SOA_EXPIRE: 442 case ARES_RR_SOA_MINIMUM: 443 return ARES_DATATYPE_U32; 444 445 case ARES_RR_MX_PREFERENCE: 446 case ARES_RR_SRV_PRIORITY: 447 case ARES_RR_SRV_WEIGHT: 448 case ARES_RR_SRV_PORT: 449 case ARES_RR_NAPTR_ORDER: 450 case ARES_RR_NAPTR_PREFERENCE: 451 case ARES_RR_OPT_UDP_SIZE: 452 case ARES_RR_OPT_FLAGS: 453 case ARES_RR_SVCB_PRIORITY: 454 case ARES_RR_HTTPS_PRIORITY: 455 case ARES_RR_URI_PRIORITY: 456 case ARES_RR_URI_WEIGHT: 457 case ARES_RR_RAW_RR_TYPE: 458 return ARES_DATATYPE_U16; 459 460 case ARES_RR_OPT_VERSION: 461 case ARES_RR_TLSA_CERT_USAGE: 462 case ARES_RR_TLSA_SELECTOR: 463 case ARES_RR_TLSA_MATCH: 464 case ARES_RR_CAA_CRITICAL: 465 return ARES_DATATYPE_U8; 466 467 case ARES_RR_CAA_VALUE: 468 case ARES_RR_TXT_DATA: 469 return ARES_DATATYPE_BINP; 470 471 case ARES_RR_TLSA_DATA: 472 case ARES_RR_RAW_RR_DATA: 473 return ARES_DATATYPE_BIN; 474 475 case ARES_RR_OPT_OPTIONS: 476 case ARES_RR_SVCB_PARAMS: 477 case ARES_RR_HTTPS_PARAMS: 478 return ARES_DATATYPE_OPT; 479 } 480 481 return 0; 482} 483 484static const ares_dns_rr_key_t rr_a_keys[] = { ARES_RR_A_ADDR }; 485static const ares_dns_rr_key_t rr_ns_keys[] = { ARES_RR_NS_NSDNAME }; 486static const ares_dns_rr_key_t rr_cname_keys[] = { ARES_RR_CNAME_CNAME }; 487static const ares_dns_rr_key_t rr_soa_keys[] = { 488 ARES_RR_SOA_MNAME, ARES_RR_SOA_RNAME, ARES_RR_SOA_SERIAL, 489 ARES_RR_SOA_REFRESH, ARES_RR_SOA_RETRY, ARES_RR_SOA_EXPIRE, 490 ARES_RR_SOA_MINIMUM 491}; 492static const ares_dns_rr_key_t rr_ptr_keys[] = { ARES_RR_PTR_DNAME }; 493static const ares_dns_rr_key_t rr_hinfo_keys[] = { ARES_RR_HINFO_CPU, 494 ARES_RR_HINFO_OS }; 495static const ares_dns_rr_key_t rr_mx_keys[] = { ARES_RR_MX_PREFERENCE, 496 ARES_RR_MX_EXCHANGE }; 497static const ares_dns_rr_key_t rr_txt_keys[] = { ARES_RR_TXT_DATA }; 498static const ares_dns_rr_key_t rr_aaaa_keys[] = { ARES_RR_AAAA_ADDR }; 499static const ares_dns_rr_key_t rr_srv_keys[] = { 500 ARES_RR_SRV_PRIORITY, ARES_RR_SRV_WEIGHT, ARES_RR_SRV_PORT, ARES_RR_SRV_TARGET 501}; 502static const ares_dns_rr_key_t rr_naptr_keys[] = { 503 ARES_RR_NAPTR_ORDER, ARES_RR_NAPTR_PREFERENCE, ARES_RR_NAPTR_FLAGS, 504 ARES_RR_NAPTR_SERVICES, ARES_RR_NAPTR_REGEXP, ARES_RR_NAPTR_REPLACEMENT 505}; 506static const ares_dns_rr_key_t rr_opt_keys[] = { ARES_RR_OPT_UDP_SIZE, 507 ARES_RR_OPT_VERSION, 508 ARES_RR_OPT_FLAGS, 509 ARES_RR_OPT_OPTIONS }; 510static const ares_dns_rr_key_t rr_tlsa_keys[] = { ARES_RR_TLSA_CERT_USAGE, 511 ARES_RR_TLSA_SELECTOR, 512 ARES_RR_TLSA_MATCH, 513 ARES_RR_TLSA_DATA }; 514static const ares_dns_rr_key_t rr_svcb_keys[] = { ARES_RR_SVCB_PRIORITY, 515 ARES_RR_SVCB_TARGET, 516 ARES_RR_SVCB_PARAMS }; 517static const ares_dns_rr_key_t rr_https_keys[] = { ARES_RR_HTTPS_PRIORITY, 518 ARES_RR_HTTPS_TARGET, 519 ARES_RR_HTTPS_PARAMS }; 520static const ares_dns_rr_key_t rr_uri_keys[] = { ARES_RR_URI_PRIORITY, 521 ARES_RR_URI_WEIGHT, 522 ARES_RR_URI_TARGET }; 523static const ares_dns_rr_key_t rr_caa_keys[] = { ARES_RR_CAA_CRITICAL, 524 ARES_RR_CAA_TAG, 525 ARES_RR_CAA_VALUE }; 526static const ares_dns_rr_key_t rr_raw_rr_keys[] = { ARES_RR_RAW_RR_TYPE, 527 ARES_RR_RAW_RR_DATA }; 528 529const ares_dns_rr_key_t *ares_dns_rr_get_keys(ares_dns_rec_type_t type, 530 size_t *cnt) 531{ 532 if (cnt == NULL) { 533 return NULL; 534 } 535 536 *cnt = 0; 537 538 switch (type) { 539 case ARES_REC_TYPE_A: 540 *cnt = sizeof(rr_a_keys) / sizeof(*rr_a_keys); 541 return rr_a_keys; 542 case ARES_REC_TYPE_NS: 543 *cnt = sizeof(rr_ns_keys) / sizeof(*rr_ns_keys); 544 return rr_ns_keys; 545 case ARES_REC_TYPE_CNAME: 546 *cnt = sizeof(rr_cname_keys) / sizeof(*rr_cname_keys); 547 return rr_cname_keys; 548 case ARES_REC_TYPE_SOA: 549 *cnt = sizeof(rr_soa_keys) / sizeof(*rr_soa_keys); 550 return rr_soa_keys; 551 case ARES_REC_TYPE_PTR: 552 *cnt = sizeof(rr_ptr_keys) / sizeof(*rr_ptr_keys); 553 return rr_ptr_keys; 554 case ARES_REC_TYPE_HINFO: 555 *cnt = sizeof(rr_hinfo_keys) / sizeof(*rr_hinfo_keys); 556 return rr_hinfo_keys; 557 case ARES_REC_TYPE_MX: 558 *cnt = sizeof(rr_mx_keys) / sizeof(*rr_mx_keys); 559 return rr_mx_keys; 560 case ARES_REC_TYPE_TXT: 561 *cnt = sizeof(rr_txt_keys) / sizeof(*rr_txt_keys); 562 return rr_txt_keys; 563 case ARES_REC_TYPE_AAAA: 564 *cnt = sizeof(rr_aaaa_keys) / sizeof(*rr_aaaa_keys); 565 return rr_aaaa_keys; 566 case ARES_REC_TYPE_SRV: 567 *cnt = sizeof(rr_srv_keys) / sizeof(*rr_srv_keys); 568 return rr_srv_keys; 569 case ARES_REC_TYPE_NAPTR: 570 *cnt = sizeof(rr_naptr_keys) / sizeof(*rr_naptr_keys); 571 return rr_naptr_keys; 572 case ARES_REC_TYPE_OPT: 573 *cnt = sizeof(rr_opt_keys) / sizeof(*rr_opt_keys); 574 return rr_opt_keys; 575 case ARES_REC_TYPE_TLSA: 576 *cnt = sizeof(rr_tlsa_keys) / sizeof(*rr_tlsa_keys); 577 return rr_tlsa_keys; 578 case ARES_REC_TYPE_SVCB: 579 *cnt = sizeof(rr_svcb_keys) / sizeof(*rr_svcb_keys); 580 return rr_svcb_keys; 581 case ARES_REC_TYPE_HTTPS: 582 *cnt = sizeof(rr_https_keys) / sizeof(*rr_https_keys); 583 return rr_https_keys; 584 case ARES_REC_TYPE_ANY: 585 /* Not real */ 586 break; 587 case ARES_REC_TYPE_URI: 588 *cnt = sizeof(rr_uri_keys) / sizeof(*rr_uri_keys); 589 return rr_uri_keys; 590 case ARES_REC_TYPE_CAA: 591 *cnt = sizeof(rr_caa_keys) / sizeof(*rr_caa_keys); 592 return rr_caa_keys; 593 case ARES_REC_TYPE_RAW_RR: 594 *cnt = sizeof(rr_raw_rr_keys) / sizeof(*rr_raw_rr_keys); 595 return rr_raw_rr_keys; 596 } 597 598 return NULL; 599} 600 601ares_bool_t ares_dns_class_fromstr(ares_dns_class_t *qclass, const char *str) 602{ 603 size_t i; 604 605 static const struct { 606 const char *name; 607 ares_dns_class_t qclass; 608 } list[] = { 609 {"IN", ARES_CLASS_IN }, 610 { "CH", ARES_CLASS_CHAOS }, 611 { "HS", ARES_CLASS_HESOID}, 612 { "NONE", ARES_CLASS_NONE }, 613 { "ANY", ARES_CLASS_ANY }, 614 { NULL, 0 } 615 }; 616 617 if (qclass == NULL || str == NULL) { 618 return ARES_FALSE; 619 } 620 621 for (i = 0; list[i].name != NULL; i++) { 622 if (strcasecmp(list[i].name, str) == 0) { 623 *qclass = list[i].qclass; 624 return ARES_TRUE; 625 } 626 } 627 return ARES_FALSE; 628} 629 630ares_bool_t ares_dns_rec_type_fromstr(ares_dns_rec_type_t *qtype, 631 const char *str) 632{ 633 size_t i; 634 635 static const struct { 636 const char *name; 637 ares_dns_rec_type_t type; 638 } list[] = { 639 {"A", ARES_REC_TYPE_A }, 640 { "NS", ARES_REC_TYPE_NS }, 641 { "CNAME", ARES_REC_TYPE_CNAME }, 642 { "SOA", ARES_REC_TYPE_SOA }, 643 { "PTR", ARES_REC_TYPE_PTR }, 644 { "HINFO", ARES_REC_TYPE_HINFO }, 645 { "MX", ARES_REC_TYPE_MX }, 646 { "TXT", ARES_REC_TYPE_TXT }, 647 { "AAAA", ARES_REC_TYPE_AAAA }, 648 { "SRV", ARES_REC_TYPE_SRV }, 649 { "NAPTR", ARES_REC_TYPE_NAPTR }, 650 { "OPT", ARES_REC_TYPE_OPT }, 651 { "TLSA", ARES_REC_TYPE_TLSA }, 652 { "SVCB", ARES_REC_TYPE_SVCB }, 653 { "HTTPS", ARES_REC_TYPE_HTTPS }, 654 { "ANY", ARES_REC_TYPE_ANY }, 655 { "URI", ARES_REC_TYPE_URI }, 656 { "CAA", ARES_REC_TYPE_CAA }, 657 { "RAW_RR", ARES_REC_TYPE_RAW_RR}, 658 { NULL, 0 } 659 }; 660 661 if (qtype == NULL || str == NULL) { 662 return ARES_FALSE; 663 } 664 665 for (i = 0; list[i].name != NULL; i++) { 666 if (strcasecmp(list[i].name, str) == 0) { 667 *qtype = list[i].type; 668 return ARES_TRUE; 669 } 670 } 671 return ARES_FALSE; 672} 673 674const char *ares_dns_section_tostr(ares_dns_section_t section) 675{ 676 switch (section) { 677 case ARES_SECTION_ANSWER: 678 return "ANSWER"; 679 case ARES_SECTION_AUTHORITY: 680 return "AUTHORITY"; 681 case ARES_SECTION_ADDITIONAL: 682 return "ADDITIONAL"; 683 } 684 return "UNKNOWN"; 685} 686 687static ares_dns_opt_datatype_t ares_dns_opt_get_type_opt(unsigned short opt) 688{ 689 ares_opt_param_t param = (ares_opt_param_t)opt; 690 switch (param) { 691 case ARES_OPT_PARAM_LLQ: 692 /* Really it is u16 version, u16 opcode, u16 error, u64 id, u32 lease */ 693 return ARES_OPT_DATATYPE_BIN; 694 case ARES_OPT_PARAM_UL: 695 return ARES_OPT_DATATYPE_U32; 696 case ARES_OPT_PARAM_NSID: 697 return ARES_OPT_DATATYPE_BIN; 698 case ARES_OPT_PARAM_DAU: 699 return ARES_OPT_DATATYPE_U8_LIST; 700 case ARES_OPT_PARAM_DHU: 701 return ARES_OPT_DATATYPE_U8_LIST; 702 case ARES_OPT_PARAM_N3U: 703 return ARES_OPT_DATATYPE_U8_LIST; 704 case ARES_OPT_PARAM_EDNS_CLIENT_SUBNET: 705 /* Really it is a u16 address family, u8 source prefix length, 706 * u8 scope prefix length, address */ 707 return ARES_OPT_DATATYPE_BIN; 708 case ARES_OPT_PARAM_EDNS_EXPIRE: 709 return ARES_OPT_DATATYPE_U32; 710 case ARES_OPT_PARAM_COOKIE: 711 /* 8 bytes for client, 16-40 bytes for server */ 712 return ARES_OPT_DATATYPE_BIN; 713 case ARES_OPT_PARAM_EDNS_TCP_KEEPALIVE: 714 /* Timeout in 100ms intervals */ 715 return ARES_OPT_DATATYPE_U16; 716 case ARES_OPT_PARAM_PADDING: 717 /* Arbitrary padding */ 718 return ARES_OPT_DATATYPE_BIN; 719 case ARES_OPT_PARAM_CHAIN: 720 return ARES_OPT_DATATYPE_NAME; 721 case ARES_OPT_PARAM_EDNS_KEY_TAG: 722 return ARES_OPT_DATATYPE_U16_LIST; 723 case ARES_OPT_PARAM_EXTENDED_DNS_ERROR: 724 /* Really 16bit code followed by textual message */ 725 return ARES_OPT_DATATYPE_BIN; 726 } 727 return ARES_OPT_DATATYPE_BIN; 728} 729 730static ares_dns_opt_datatype_t ares_dns_opt_get_type_svcb(unsigned short opt) 731{ 732 ares_svcb_param_t param = (ares_svcb_param_t)opt; 733 switch (param) { 734 case ARES_SVCB_PARAM_NO_DEFAULT_ALPN: 735 return ARES_OPT_DATATYPE_NONE; 736 case ARES_SVCB_PARAM_ECH: 737 return ARES_OPT_DATATYPE_BIN; 738 case ARES_SVCB_PARAM_MANDATORY: 739 return ARES_OPT_DATATYPE_U16_LIST; 740 case ARES_SVCB_PARAM_ALPN: 741 return ARES_OPT_DATATYPE_STR_LIST; 742 case ARES_SVCB_PARAM_PORT: 743 return ARES_OPT_DATATYPE_U16; 744 case ARES_SVCB_PARAM_IPV4HINT: 745 return ARES_OPT_DATATYPE_INADDR4_LIST; 746 case ARES_SVCB_PARAM_IPV6HINT: 747 return ARES_OPT_DATATYPE_INADDR6_LIST; 748 } 749 return ARES_OPT_DATATYPE_BIN; 750} 751 752ares_dns_opt_datatype_t ares_dns_opt_get_datatype(ares_dns_rr_key_t key, 753 unsigned short opt) 754{ 755 switch (key) { 756 case ARES_RR_OPT_OPTIONS: 757 return ares_dns_opt_get_type_opt(opt); 758 case ARES_RR_SVCB_PARAMS: 759 case ARES_RR_HTTPS_PARAMS: 760 return ares_dns_opt_get_type_svcb(opt); 761 default: 762 break; 763 } 764 return ARES_OPT_DATATYPE_BIN; 765} 766 767static const char *ares_dns_opt_get_name_opt(unsigned short opt) 768{ 769 ares_opt_param_t param = (ares_opt_param_t)opt; 770 switch (param) { 771 case ARES_OPT_PARAM_LLQ: 772 return "LLQ"; 773 case ARES_OPT_PARAM_UL: 774 return "UL"; 775 case ARES_OPT_PARAM_NSID: 776 return "NSID"; 777 case ARES_OPT_PARAM_DAU: 778 return "DAU"; 779 case ARES_OPT_PARAM_DHU: 780 return "DHU"; 781 case ARES_OPT_PARAM_N3U: 782 return "N3U"; 783 case ARES_OPT_PARAM_EDNS_CLIENT_SUBNET: 784 return "edns-client-subnet"; 785 case ARES_OPT_PARAM_EDNS_EXPIRE: 786 return "edns-expire"; 787 case ARES_OPT_PARAM_COOKIE: 788 return "COOKIE"; 789 case ARES_OPT_PARAM_EDNS_TCP_KEEPALIVE: 790 return "edns-tcp-keepalive"; 791 case ARES_OPT_PARAM_PADDING: 792 return "Padding"; 793 case ARES_OPT_PARAM_CHAIN: 794 return "CHAIN"; 795 case ARES_OPT_PARAM_EDNS_KEY_TAG: 796 return "edns-key-tag"; 797 case ARES_OPT_PARAM_EXTENDED_DNS_ERROR: 798 return "extended-dns-error"; 799 } 800 return NULL; 801} 802 803static const char *ares_dns_opt_get_name_svcb(unsigned short opt) 804{ 805 ares_svcb_param_t param = (ares_svcb_param_t)opt; 806 switch (param) { 807 case ARES_SVCB_PARAM_NO_DEFAULT_ALPN: 808 return "no-default-alpn"; 809 case ARES_SVCB_PARAM_ECH: 810 return "ech"; 811 case ARES_SVCB_PARAM_MANDATORY: 812 return "mandatory"; 813 case ARES_SVCB_PARAM_ALPN: 814 return "alpn"; 815 case ARES_SVCB_PARAM_PORT: 816 return "port"; 817 case ARES_SVCB_PARAM_IPV4HINT: 818 return "ipv4hint"; 819 case ARES_SVCB_PARAM_IPV6HINT: 820 return "ipv6hint"; 821 } 822 return NULL; 823} 824 825const char *ares_dns_opt_get_name(ares_dns_rr_key_t key, unsigned short opt) 826{ 827 switch (key) { 828 case ARES_RR_OPT_OPTIONS: 829 return ares_dns_opt_get_name_opt(opt); 830 case ARES_RR_SVCB_PARAMS: 831 case ARES_RR_HTTPS_PARAMS: 832 return ares_dns_opt_get_name_svcb(opt); 833 default: 834 break; 835 } 836 return NULL; 837} 838 839const char *ares_dns_rcode_tostr(ares_dns_rcode_t rcode) 840{ 841 switch (rcode) { 842 case ARES_RCODE_NOERROR: 843 return "NOERROR"; 844 case ARES_RCODE_FORMERR: 845 return "FORMERR"; 846 case ARES_RCODE_SERVFAIL: 847 return "SERVFAIL"; 848 case ARES_RCODE_NXDOMAIN: 849 return "NXDOMAIN"; 850 case ARES_RCODE_NOTIMP: 851 return "NOTIMP"; 852 case ARES_RCODE_REFUSED: 853 return "REFUSED"; 854 case ARES_RCODE_YXDOMAIN: 855 return "YXDOMAIN"; 856 case ARES_RCODE_YXRRSET: 857 return "YXRRSET"; 858 case ARES_RCODE_NXRRSET: 859 return "NXRRSET"; 860 case ARES_RCODE_NOTAUTH: 861 return "NOTAUTH"; 862 case ARES_RCODE_NOTZONE: 863 return "NOTZONE"; 864 case ARES_RCODE_DSOTYPEI: 865 return "DSOTYPEI"; 866 case ARES_RCODE_BADSIG: 867 return "BADSIG"; 868 case ARES_RCODE_BADKEY: 869 return "BADKEY"; 870 case ARES_RCODE_BADTIME: 871 return "BADTIME"; 872 case ARES_RCODE_BADMODE: 873 return "BADMODE"; 874 case ARES_RCODE_BADNAME: 875 return "BADNAME"; 876 case ARES_RCODE_BADALG: 877 return "BADALG"; 878 case ARES_RCODE_BADTRUNC: 879 return "BADTRUNC"; 880 case ARES_RCODE_BADCOOKIE: 881 return "BADCOOKIE"; 882 } 883 884 return "UNKNOWN"; 885} 886