1 /*- 2 * (c) Magerya Vitaly 3 * 4 * Copying and distribution of this file, with or without modification, 5 * are permitted in any medium without royalty provided the copyright 6 * notice and this notice are preserved. This file is offered as-is, 7 * without any warranty. 8 */ 9 10 #include <netinet/in.h> 11 12 #include <limits.h> 13 #include <netdb.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <unistd.h> 17 18 #include <ldns/ldns.h> 19 20 /* General utilities. 21 */ 22 23 static char *progname; 24 25 #define countof(array) (sizeof(array)/sizeof(*(array))) 26 27 static void 28 die(int code, const char *fmt, ...) { 29 va_list args; 30 31 va_start(args, fmt); 32 fprintf(stderr, "%s: ", progname); 33 vfprintf(stderr, fmt, args); 34 fprintf(stderr, "\n"); 35 va_end(args); 36 exit(code); 37 } 38 39 static int 40 ndots(const char *name) { 41 int n; 42 43 for (n = 0; (name = strchr(name, '.')); n++, name++); 44 return n; 45 } 46 47 /* General LDNS-specific utilities. 48 */ 49 50 static ldns_status 51 ldns_resolver_new_default(ldns_resolver **res) { 52 if (ldns_resolver_new_frm_file(res, NULL) == LDNS_STATUS_OK || 53 (*res = ldns_resolver_new()) != NULL) 54 return LDNS_STATUS_OK; 55 return LDNS_STATUS_MEM_ERR; 56 } 57 58 static ldns_status 59 ldns_resolver_push_default_servers(ldns_resolver *res) { 60 ldns_status status; 61 ldns_rdf *addr; 62 63 if ((status = ldns_str2rdf_a(&addr, "127.0.0.1")) != LDNS_STATUS_OK || 64 (status = ldns_resolver_push_nameserver(res, addr)) != LDNS_STATUS_OK) 65 return ldns_rdf_deep_free(addr), status; 66 ldns_rdf_deep_free(addr); 67 if ((status = ldns_str2rdf_aaaa(&addr, "::1")) != LDNS_STATUS_OK || 68 (status = ldns_resolver_push_nameserver(res, addr)) != LDNS_STATUS_OK) 69 return ldns_rdf_deep_free(addr), status; 70 ldns_rdf_deep_free(addr); 71 return LDNS_STATUS_OK; 72 } 73 74 static ldns_rdf * 75 ldns_rdf_new_addr_frm_str(const char *str) { 76 ldns_rdf *addr; 77 78 if ((addr = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, str)) == NULL) 79 addr = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, str); 80 return addr; 81 } 82 83 static void 84 ldns_resolver_remove_nameservers(ldns_resolver *res) { 85 while (ldns_resolver_nameserver_count(res) > 0) 86 ldns_rdf_deep_free(ldns_resolver_pop_nameserver(res)); 87 } 88 89 static ldns_rdf * 90 ldns_rdf_reverse_a(ldns_rdf *addr, const char *base) { 91 char *buf; 92 int i, len; 93 94 len = strlen(base); 95 buf = alloca(LDNS_IP4ADDRLEN*4 + len + 1); 96 for (len = i = 0; i < LDNS_IP4ADDRLEN; i++) 97 len += sprintf(&buf[len], "%d.", 98 (int)ldns_rdf_data(addr)[LDNS_IP4ADDRLEN - i - 1]); 99 sprintf(&buf[len], "%s", base); 100 return ldns_dname_new_frm_str(buf); 101 } 102 103 static ldns_rdf * 104 ldns_rdf_reverse_aaaa(ldns_rdf *addr, const char *base) { 105 char *buf; 106 int i, len; 107 108 len = strlen(base); 109 buf = alloca(LDNS_IP6ADDRLEN*4 + len + 1); 110 for (i = 0; i < LDNS_IP6ADDRLEN; i++) { 111 uint8_t byte = ldns_rdf_data(addr)[LDNS_IP6ADDRLEN - i - 1]; 112 sprintf(&buf[i*4], "%x.%x.", byte & 0x0F, byte >> 4); 113 } 114 sprintf(&buf[LDNS_IP6ADDRLEN*4], "%s", base); 115 return ldns_dname_new_frm_str(buf); 116 } 117 118 static ldns_status 119 ldns_pkt_push_rr_soa(ldns_pkt *pkt, ldns_pkt_section sec, 120 const ldns_rdf *name, ldns_rr_class c, uint32_t serial) { 121 ldns_rdf *rdf; 122 ldns_rr *rr; 123 uint32_t n; 124 125 if ((rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_SOA)) == NULL) 126 return LDNS_STATUS_MEM_ERR; 127 ldns_rr_set_class(rr, c); 128 ldns_rr_set_owner(rr, ldns_rdf_clone(name)); 129 ldns_rr_set_ttl(rr, 0); 130 131 n = 0; 132 if ((rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, 1, &n)) == NULL) 133 goto memerr; 134 ldns_rr_set_rdf(rr, rdf, 0); 135 ldns_rr_set_rdf(rr, ldns_rdf_clone(rdf), 1); 136 137 n = htonl(serial); 138 if ((rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_INT32, 4, &n)) == NULL) 139 goto memerr; 140 ldns_rr_set_rdf(rr, rdf, 2); 141 142 n = 0; 143 if ((rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_PERIOD, 4, &n)) == NULL) 144 goto memerr; 145 ldns_rr_set_rdf(rr, rdf, 3); 146 ldns_rr_set_rdf(rr, ldns_rdf_clone(rdf), 4); 147 ldns_rr_set_rdf(rr, ldns_rdf_clone(rdf), 5); 148 ldns_rr_set_rdf(rr, ldns_rdf_clone(rdf), 6); 149 150 if (ldns_rr_rdf(rr, 1) == NULL || ldns_rr_rdf(rr, 4) == NULL || 151 ldns_rr_rdf(rr, 5) == NULL || ldns_rr_rdf(rr, 6) == NULL || 152 !ldns_pkt_push_rr(pkt, sec, rr)) 153 goto memerr; 154 return LDNS_STATUS_OK; 155 156 memerr: 157 ldns_rr_free(rr); 158 return LDNS_STATUS_MEM_ERR; 159 } 160 161 static ldns_status 162 ldns_resolver_send_to(ldns_pkt **answer, ldns_resolver *res, 163 const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, 164 uint16_t flags, uint32_t ixfr_serial, int nameserver) { 165 ldns_status status; 166 ldns_pkt *qpkt; 167 168 int nscnt = ldns_resolver_nameserver_count(res); 169 ldns_rdf **ns = ldns_resolver_nameservers(res); 170 size_t *rtt = ldns_resolver_rtt(res); 171 172 ldns_resolver_set_nameservers(res, &ns[nameserver]); 173 ldns_resolver_set_rtt(res, &rtt[nameserver]); 174 ldns_resolver_set_nameserver_count(res, 1); 175 176 status = ldns_resolver_prepare_query_pkt(&qpkt, res, name, t, c, flags); 177 if (status == LDNS_STATUS_OK && t == LDNS_RR_TYPE_IXFR) 178 status = ldns_pkt_push_rr_soa(qpkt, 179 LDNS_SECTION_AUTHORITY, name, c, ixfr_serial); 180 if (status == LDNS_STATUS_OK) 181 status = ldns_resolver_send_pkt(answer, res, qpkt); 182 ldns_pkt_free(qpkt); 183 184 ldns_resolver_set_nameservers(res, ns); 185 ldns_resolver_set_rtt(res, rtt); 186 ldns_resolver_set_nameserver_count(res, nscnt); 187 return status; 188 } 189 190 static void 191 ldns_pkt_filter_answer(ldns_pkt *pkt, ldns_rr_type type) { 192 int i, j, cnt; 193 ldns_rr_list *rrlist; 194 ldns_rr *rr; 195 ldns_rr_type rrtype; 196 197 rrlist = ldns_pkt_answer(pkt); 198 cnt = ldns_rr_list_rr_count(rrlist); 199 for (i = j = 0; i < cnt; i++) { 200 rr = ldns_rr_list_rr(rrlist, i); 201 rrtype = ldns_rr_get_type(rr); 202 if (type == LDNS_RR_TYPE_ANY || 203 type == rrtype || 204 (type == LDNS_RR_TYPE_AXFR && 205 (rrtype == LDNS_RR_TYPE_A || 206 rrtype == LDNS_RR_TYPE_AAAA || 207 rrtype == LDNS_RR_TYPE_NS || 208 rrtype == LDNS_RR_TYPE_PTR))) 209 ldns_rr_list_set_rr(rrlist, rr, j++); 210 } 211 ldns_rr_list_set_rr_count(rrlist, j); 212 } 213 214 /* Packet content printing. 215 */ 216 217 static struct { 218 ldns_rr_type type; 219 const char *text; 220 } rr_types[] = { 221 {LDNS_RR_TYPE_A, "has address"}, 222 {LDNS_RR_TYPE_NS, "name server"}, 223 {LDNS_RR_TYPE_CNAME, "is an alias for"}, 224 {LDNS_RR_TYPE_WKS, "has well known services"}, 225 {LDNS_RR_TYPE_PTR, "domain name pointer"}, 226 {LDNS_RR_TYPE_HINFO, "host information"}, 227 {LDNS_RR_TYPE_MX, "mail is handled by"}, 228 {LDNS_RR_TYPE_TXT, "descriptive text"}, 229 {LDNS_RR_TYPE_X25, "x25 address"}, 230 {LDNS_RR_TYPE_ISDN, "ISDN address"}, 231 {LDNS_RR_TYPE_SIG, "has signature"}, 232 {LDNS_RR_TYPE_KEY, "has key"}, 233 {LDNS_RR_TYPE_AAAA, "has IPv6 address"}, 234 {LDNS_RR_TYPE_LOC, "location"}, 235 }; 236 237 static void 238 print_opcode(ldns_pkt_opcode opcode) { 239 ldns_lookup_table *lt = ldns_lookup_by_id(ldns_opcodes, opcode); 240 241 if (lt && lt->name) 242 printf("%s", lt->name); 243 else 244 printf("RESERVED%d", opcode); 245 } 246 247 static void 248 print_rcode(uint8_t rcode) { 249 ldns_lookup_table *lt = ldns_lookup_by_id(ldns_rcodes, rcode); 250 251 if (lt && lt->name) 252 printf("%s", lt->name); 253 else 254 printf("RESERVED%d", rcode); 255 } 256 257 static int 258 print_rr_type(ldns_rr_type type) { 259 char *str; 260 int n; 261 262 str = ldns_rr_type2str(type); 263 n = printf("%s", str); 264 free(str); 265 return n; 266 } 267 268 static int 269 print_rr_class(ldns_rr_class cls) { 270 char *str; 271 int n; 272 273 str = ldns_rr_class2str(cls); 274 n = printf("%s", str); 275 free(str); 276 return n; 277 } 278 279 static int 280 print_rdf(ldns_rdf *rdf) { 281 char *str; 282 int n; 283 284 str = ldns_rdf2str(rdf); 285 n = printf("%s", str); 286 free(str); 287 return n; 288 } 289 290 static int 291 print_rdf_nodot(ldns_rdf *rdf) { 292 char *str; 293 int len, n; 294 295 str = ldns_rdf2str(rdf); 296 len = strlen(str); 297 n = printf("%.*s", str[len-1] == '.' ? len-1 : len, str); 298 free(str); 299 return n; 300 } 301 302 static int 303 print_padding(int fromcol, int tocol) { 304 int col = fromcol, nextcol = fromcol + 8 - fromcol%8; 305 306 if (fromcol + 1 > tocol) tocol = fromcol + 1; 307 for (; nextcol <= tocol; col = nextcol, nextcol += 8) 308 printf("\t"); 309 for (; col < tocol; col++) 310 printf(" "); 311 return col - fromcol; 312 } 313 314 static void 315 print_rr_verbose(ldns_rr *rr) { 316 bool isq = ldns_rr_is_question(rr); 317 int rdcnt = ldns_rr_rd_count(rr); 318 int i, n; 319 320 /* bind9-host does not count the initial ';' here */ 321 n = isq ? printf(";") : 0; 322 n = print_rdf(ldns_rr_owner(rr)); 323 if (!isq) { 324 n += print_padding(n, 24); 325 n += printf("%d", ldns_rr_ttl(rr)); 326 } 327 n += print_padding(n, 32); 328 n += print_rr_class(ldns_rr_get_class(rr)); 329 n += print_padding(n, 40); 330 n += print_rr_type(ldns_rr_get_type(rr)); 331 for (i = 0; i < rdcnt; i++) { 332 if (i == 0) print_padding(n, 48); 333 else printf(" "); 334 print_rdf(ldns_rr_rdf(rr, i)); 335 } 336 printf("\n"); 337 } 338 339 static void 340 print_pkt_section_verbose(const char *name, ldns_rr_list *rrlist) { 341 int i, cnt = ldns_rr_list_rr_count(rrlist); 342 343 if (cnt == 0) 344 return; 345 printf(";; %s SECTION:\n", name); 346 for (i = 0; i < cnt; i++) 347 print_rr_verbose(ldns_rr_list_rr(rrlist, i)); 348 printf("\n"); 349 } 350 351 static void 352 print_pkt_verbose(ldns_pkt *pkt) { 353 int got_flags = 0; 354 355 printf(";; ->>HEADER<<- opcode: "); 356 print_opcode(ldns_pkt_get_opcode(pkt)); 357 printf(", status: "); 358 print_rcode(ldns_pkt_get_rcode(pkt)); 359 printf(", id: %u\n", ldns_pkt_id(pkt)); 360 printf(";; flags:"); 361 if (ldns_pkt_qr(pkt)) printf(" qr"), got_flags = 1; 362 if (ldns_pkt_aa(pkt)) printf(" aa"), got_flags = 1; 363 if (ldns_pkt_tc(pkt)) printf(" tc"), got_flags = 1; 364 if (ldns_pkt_rd(pkt)) printf(" rd"), got_flags = 1; 365 if (ldns_pkt_ra(pkt)) printf(" ra"), got_flags = 1; 366 if (ldns_pkt_ad(pkt)) printf(" ad"), got_flags = 1; 367 if (ldns_pkt_cd(pkt)) printf(" cd"), got_flags = 1; 368 if (!got_flags) printf(" "); 369 printf("; QUERY: %u, ANSWER: %u, AUTHORITY: %u, ADDITIONAL: %u\n", 370 ldns_pkt_qdcount(pkt), ldns_pkt_ancount(pkt), 371 ldns_pkt_nscount(pkt), ldns_pkt_arcount(pkt)); 372 if (ldns_pkt_edns(pkt)) 373 printf(";; EDNS: version: %u, udp=%u\n", 374 ldns_pkt_edns_version(pkt), ldns_pkt_edns_udp_size(pkt)); 375 printf("\n"); 376 print_pkt_section_verbose("QUESTION", ldns_pkt_question(pkt)); 377 print_pkt_section_verbose("ANSWER", ldns_pkt_answer(pkt)); 378 print_pkt_section_verbose("AUTHORITY", ldns_pkt_authority(pkt)); 379 print_pkt_section_verbose("ADDITIONAL", ldns_pkt_additional(pkt)); 380 } 381 382 static void 383 print_rr_short(ldns_rr *rr) { 384 ldns_rr_type type = ldns_rr_get_type(rr); 385 size_t i, rdcnt = ldns_rr_rd_count(rr); 386 387 print_rdf_nodot(ldns_rr_owner(rr)); 388 printf(" "); 389 for (i = 0; i < countof(rr_types); i++) { 390 if (rr_types[i].type == type) { 391 printf("%s", rr_types[i].text); 392 goto found; 393 } 394 } 395 396 printf("has "); 397 print_rr_type(type); 398 printf(" record"); 399 400 found: 401 for (i = 0; i < rdcnt; i++) { 402 printf(" "); 403 print_rdf(ldns_rr_rdf(rr, i)); 404 } 405 printf("\n"); 406 } 407 408 static void 409 print_pkt_short(ldns_pkt *pkt, bool print_rr_server) { 410 ldns_rr_list *rrlist = ldns_pkt_answer(pkt); 411 size_t i; 412 413 for (i = 0; i < ldns_rr_list_rr_count(rrlist); i++) { 414 if (print_rr_server) { 415 printf("Nameserver "); 416 print_rdf(ldns_pkt_answerfrom(pkt)); 417 printf(":\n\t"); 418 } 419 print_rr_short(ldns_rr_list_rr(rrlist, i)); 420 } 421 } 422 423 static void 424 print_received_line(ldns_resolver *res, ldns_pkt *pkt) { 425 char *from = ldns_rdf2str(ldns_pkt_answerfrom(pkt)); 426 427 printf("Received %zu bytes from %s#%d in %d ms\n", 428 ldns_pkt_size(pkt), from, ldns_resolver_port(res), 429 ldns_pkt_querytime(pkt)); 430 free(from); 431 } 432 433 /* Main program. 434 * 435 * Note that no memory is freed below this line by intention. 436 */ 437 438 #define DEFAULT_TCP_TIMEOUT 10 439 #define DEFAULT_UDP_TIMEOUT 5 440 441 enum operation_mode { M_AXFR, M_DEFAULT_Q, M_SINGLE_Q, M_SOA }; 442 443 static enum operation_mode o_mode = M_DEFAULT_Q; 444 static bool o_ignore_servfail = true; 445 static bool o_ip6_int = false; 446 static bool o_print_pkt_server = false; 447 static bool o_print_rr_server = false; 448 static bool o_recursive = true; 449 static bool o_tcp = false; 450 static bool o_verbose = false; 451 static char *o_name = NULL; 452 static char *o_server = NULL; 453 static int o_ipversion = LDNS_RESOLV_INETANY; 454 static int o_ndots = 1; 455 static int o_retries = 1; 456 static ldns_rr_class o_rrclass = LDNS_RR_CLASS_IN; 457 static ldns_rr_type o_rrtype = LDNS_RR_TYPE_A; 458 static time_t o_timeout = 0; 459 static uint32_t o_ixfr_serial = 0; 460 461 static void 462 usage(void) { 463 fputs( 464 "Usage: host [-aCdilrsTvw46] [-c class] [-N ndots] [-R number]\n" 465 " [-t type] [-W wait] name [server]\n" 466 "\t-a same as -v -t ANY\n" 467 "\t-C query SOA records from all authoritative name servers\n" 468 "\t-c use this query class (IN, CH, HS, etc)\n" 469 "\t-d produce verbose output, same as -v\n" 470 "\t-i use IP6.INT for IPv6 reverse lookups\n" 471 "\t-l list records in a zone via AXFR\n" 472 "\t-N consider names with at least this many dots as absolute\n" 473 "\t-R retry UDP queries this many times\n" 474 "\t-r disable recursive query\n" 475 "\t-s do not ignore SERVFAIL responses\n" 476 "\t-T send query via TCP\n" 477 "\t-t use this query type (A, AAAA, MX, etc)\n" 478 "\t-v produce verbose output\n" 479 "\t-w wait forever for a server reply\n" 480 "\t-W wait this many seconds for a reply\n" 481 "\t-4 use IPv4 only\n" 482 "\t-6 use IPv6 only\n", 483 stderr); 484 exit(1); 485 } 486 487 static void 488 parse_args(int argc, char *argv[]) { 489 int ch; 490 491 progname = argv[0]; 492 while ((ch = getopt(argc, argv, "aCdilrsTvw46c:N:R:t:W:")) != -1) { 493 switch (ch) { 494 case 'a': 495 if (o_mode != M_AXFR) 496 o_mode = M_SINGLE_Q; 497 o_rrtype = LDNS_RR_TYPE_ANY; 498 o_verbose = true; 499 break; 500 case 'C': 501 o_mode = M_SOA; 502 o_print_rr_server = true; 503 o_rrclass = LDNS_RR_CLASS_IN; 504 o_rrtype = LDNS_RR_TYPE_NS; 505 break; 506 case 'c': 507 /* bind9-host sets o_mode to M_SINGLE_Q here */ 508 o_rrclass = ldns_get_rr_class_by_name(optarg); 509 if (o_rrclass <= 0) 510 die(2, "invalid class: %s\n", optarg); 511 break; 512 case 'd': o_verbose = true; break; 513 case 'i': o_ip6_int = true; break; 514 case 'l': 515 o_mode = M_AXFR; 516 o_rrtype = LDNS_RR_TYPE_AXFR; 517 o_tcp = true; 518 break; 519 case 'N': 520 o_ndots = atoi(optarg); 521 if (o_ndots < 0) o_ndots = 0; 522 break; 523 case 'n': 524 /* bind9-host accepts and ignores this option */ 525 break; 526 case 'r': o_recursive = 0; break; 527 case 'R': 528 o_retries = atoi(optarg); 529 if (o_retries <= 0) o_retries = 1; 530 if (o_retries > 255) o_retries = 255; 531 break; 532 case 's': o_ignore_servfail = false; break; 533 case 'T': o_tcp = true; break; 534 case 't': 535 if (o_mode != M_AXFR) 536 o_mode = M_SINGLE_Q; 537 if (strncasecmp(optarg, "ixfr=", 5) == 0) { 538 o_rrtype = LDNS_RR_TYPE_IXFR; 539 o_ixfr_serial = atol(optarg + 5); 540 } else { 541 o_rrtype = ldns_get_rr_type_by_name(optarg); 542 if (o_rrtype <= 0) 543 die(2, "invalid type: %s\n", optarg); 544 } 545 if (o_rrtype == LDNS_RR_TYPE_AXFR || o_rrtype == LDNS_RR_TYPE_IXFR) 546 o_tcp = true; 547 if (o_rrtype == LDNS_RR_TYPE_AXFR) { 548 o_mode = M_AXFR; 549 o_rrtype = LDNS_RR_TYPE_ANY; 550 o_verbose = true; 551 } 552 break; 553 case 'v': o_verbose = true; break; 554 case 'w': 555 o_timeout = (time_t)INT_MAX; 556 break; 557 case 'W': 558 o_timeout = atol(optarg); 559 if (o_timeout <= 0) o_timeout = 1; 560 break; 561 case '4': o_ipversion = LDNS_RESOLV_INET; break; 562 case '6': o_ipversion = LDNS_RESOLV_INET6; break; 563 default: 564 usage(); 565 } 566 } 567 argc -= optind; 568 argv += optind; 569 /* bind9-host ignores arguments after the 2-nd one */ 570 if (argc < 1) 571 usage(); 572 o_name = argv[0]; 573 if (argc > 1) { 574 o_server = argv[1]; 575 o_print_pkt_server = true; 576 } 577 } 578 579 static ldns_rdf* 580 safe_str2rdf_dname(const char *name) { 581 ldns_rdf *dname; 582 ldns_status status; 583 584 if ((status = ldns_str2rdf_dname(&dname, name)) != LDNS_STATUS_OK) { 585 die(1, "'%s' is not a legal name (%s)", 586 name, ldns_get_errorstr_by_id(status)); 587 } 588 return dname; 589 } 590 591 static ldns_rdf* 592 safe_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2) { 593 ldns_rdf *result = ldns_dname_cat_clone(rd1, rd2); 594 595 if (!result) 596 die(1, "not enought memory for a domain name"); 597 /* Why doesn't ldns_dname_cat_clone check this condition? */ 598 if (ldns_rdf_size(result) > LDNS_MAX_DOMAINLEN) 599 die(1, "'%s' is not a legal name (%s)\n", ldns_rdf2str(result), 600 ldns_get_errorstr_by_id(LDNS_STATUS_DOMAINNAME_OVERFLOW)); 601 return result; 602 } 603 604 static bool 605 query(ldns_resolver *res, ldns_rdf *domain, ldns_pkt **pkt) { 606 ldns_status status; 607 ldns_pkt_rcode rcode; 608 int i, cnt; 609 610 if (o_verbose) { 611 printf("Trying \""); 612 print_rdf_nodot(domain); 613 printf("\"\n"); 614 } 615 for (cnt = ldns_resolver_nameserver_count(res), i = 0; i < cnt; i++) { 616 status = ldns_resolver_send_to(pkt, res, domain, o_rrtype, 617 o_rrclass, o_recursive ? LDNS_RD : 0, o_ixfr_serial, i); 618 if (status != LDNS_STATUS_OK) { 619 *pkt = NULL; 620 continue; 621 } 622 if (ldns_pkt_tc(*pkt) && !ldns_resolver_usevc(res)) { 623 if (o_verbose) 624 printf(";; Truncated, retrying in TCP mode.\n"); 625 ldns_resolver_set_usevc(res, true); 626 status = ldns_resolver_send_to(pkt, res, domain, o_rrtype, 627 o_rrclass, o_recursive ? LDNS_RD : 0, o_ixfr_serial, i); 628 ldns_resolver_set_usevc(res, false); 629 if (status != LDNS_STATUS_OK) 630 continue; 631 } 632 rcode = ldns_pkt_get_rcode(*pkt); 633 if (o_ignore_servfail && rcode == LDNS_RCODE_SERVFAIL && cnt > 1) 634 continue; 635 return rcode == LDNS_RCODE_NOERROR; 636 } 637 if (*pkt == NULL) { 638 printf(";; connection timed out; no servers could be reached\n"); 639 exit(1); 640 } 641 return false; 642 } 643 644 static ldns_rdf * 645 search(ldns_resolver *res, ldns_rdf *domain, ldns_pkt **pkt, bool absolute) { 646 ldns_rdf *dname, **searchlist; 647 int i, n; 648 649 if (absolute && query(res, domain, pkt)) 650 return domain; 651 652 if ((dname = ldns_resolver_domain(res)) != NULL) { 653 dname = safe_dname_cat_clone(domain, dname); 654 if (query(res, dname, pkt)) 655 return dname; 656 } 657 658 searchlist = ldns_resolver_searchlist(res); 659 n = ldns_resolver_searchlist_count(res); 660 for (i = 0; i < n; i++) { 661 dname = safe_dname_cat_clone(domain, searchlist[i]); 662 if (query(res, dname, pkt)) 663 return dname; 664 } 665 666 if (!absolute && query(res, domain, pkt)) 667 return domain; 668 669 return NULL; 670 } 671 672 static void 673 report(ldns_resolver *res, ldns_rdf *domain, ldns_pkt *pkt) { 674 ldns_pkt_rcode rcode; 675 676 if (o_print_pkt_server) { 677 printf("Using domain server:\nName: %s\nAddress: ", o_server); 678 print_rdf(ldns_pkt_answerfrom(pkt)); 679 printf("#%d\nAliases: \n\n", ldns_resolver_port(res)); 680 o_print_pkt_server = false; 681 } 682 rcode = ldns_pkt_get_rcode(pkt); 683 if (rcode != LDNS_RCODE_NOERROR) { 684 printf("Host "); 685 print_rdf_nodot(domain); 686 printf(" not found: %d(", rcode); 687 print_rcode(rcode); 688 printf(")\n"); 689 } else { 690 if (o_verbose) { 691 print_pkt_verbose(pkt); 692 } else { 693 print_pkt_short(pkt, o_print_rr_server); 694 if (o_mode != M_DEFAULT_Q && 695 ldns_rr_list_rr_count(ldns_pkt_answer(pkt)) == 0) { 696 print_rdf_nodot(domain); 697 printf(" has no "); 698 print_rr_type(o_rrtype); 699 printf(" record\n"); 700 } 701 } 702 } 703 if (o_verbose) 704 print_received_line(res, pkt); 705 } 706 707 static bool 708 doquery(ldns_resolver *res, ldns_rdf *domain) { 709 ldns_pkt *pkt; 710 bool q; 711 712 q = query(res, domain, &pkt); 713 report(res, domain, pkt); 714 return q; 715 } 716 717 static bool 718 doquery_filtered(ldns_resolver *res, ldns_rdf *domain) { 719 ldns_pkt *pkt; 720 bool q; 721 722 q = query(res, domain, &pkt); 723 ldns_pkt_filter_answer(pkt, o_rrtype); 724 report(res, domain, pkt); 725 return q; 726 } 727 728 static bool 729 dosearch(ldns_resolver *res, ldns_rdf *domain, bool absolute) { 730 ldns_pkt *pkt; 731 ldns_rdf *dname; 732 733 dname = search(res, domain, &pkt, absolute); 734 report(res, dname != NULL ? dname : domain, pkt); 735 return o_mode != M_DEFAULT_Q ? (dname != NULL) : 736 (dname != NULL) && 737 (o_rrtype = LDNS_RR_TYPE_AAAA, doquery_filtered(res, dname)) && 738 (o_rrtype = LDNS_RR_TYPE_MX, doquery_filtered(res, dname)); 739 } 740 741 static bool 742 doaxfr(ldns_resolver *res, ldns_rdf *domain, bool absolute) { 743 ldns_pkt *pkt; 744 ldns_rdf *dname; 745 ldns_rr_type rrtype; 746 747 rrtype = o_rrtype; 748 o_rrtype = LDNS_RR_TYPE_AXFR; 749 dname = search(res, domain, &pkt, absolute); 750 ldns_pkt_filter_answer(pkt, rrtype); 751 report(res, dname != NULL ? dname : domain, pkt); 752 return dname != NULL; 753 } 754 755 static bool 756 dosoa(ldns_resolver *res, ldns_rdf *domain, bool absolute) { 757 ldns_rr_list *answer, **nsaddrs; 758 ldns_rdf *dname, *addr; 759 ldns_pkt *pkt; 760 ldns_rr *rr; 761 size_t i, j, n, cnt; 762 763 if ((dname = search(res, domain, &pkt, absolute)) == NULL) 764 return false; 765 766 answer = ldns_pkt_answer(pkt); 767 cnt = ldns_rr_list_rr_count(answer); 768 nsaddrs = alloca(cnt*sizeof(*nsaddrs)); 769 for (n = 0, i = 0; i < cnt; i++) 770 if ((addr = ldns_rr_ns_nsdname(ldns_rr_list_rr(answer, i))) != NULL) 771 nsaddrs[n++] = ldns_get_rr_list_addr_by_name(res, 772 addr, LDNS_RR_CLASS_IN, 0); 773 774 o_print_pkt_server = false; 775 o_recursive = false; 776 o_rrtype = LDNS_RR_TYPE_SOA; 777 for (i = 0; i < n; i++) { 778 cnt = ldns_rr_list_rr_count(nsaddrs[i]); 779 for (j = 0; j < cnt; j++) { 780 ldns_resolver_remove_nameservers(res); 781 rr = ldns_rr_list_rr(nsaddrs[i], j); 782 if ((ldns_resolver_ip6(res) == LDNS_RESOLV_INET && 783 ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) || 784 (ldns_resolver_ip6(res) == LDNS_RESOLV_INET6 && 785 ldns_rr_get_type(rr) == LDNS_RR_TYPE_A)) 786 continue; 787 if (ldns_resolver_push_nameserver_rr(res, rr) == LDNS_STATUS_OK) 788 /* bind9-host queries for domain, not dname here */ 789 doquery(res, dname); 790 } 791 } 792 return 0; 793 } 794 795 static void 796 resolver_set_nameserver_hostname(ldns_resolver *res, const char *server) { 797 struct addrinfo hints, *ailist, *ai; 798 ldns_status status; 799 ldns_rdf *rdf; 800 int err; 801 802 memset(&hints, 0, sizeof hints); 803 switch (ldns_resolver_ip6(res)) { 804 case LDNS_RESOLV_INET: hints.ai_family = PF_INET; break; 805 case LDNS_RESOLV_INET6: hints.ai_family = PF_INET6; break; 806 default: hints.ai_family = PF_UNSPEC; break; 807 } 808 hints.ai_socktype = SOCK_STREAM; 809 do err = getaddrinfo(server, NULL, &hints, &ailist); 810 while (err == EAI_AGAIN); 811 if (err != 0) 812 die(1, "couldn't get address for '%s': %s", server, gai_strerror(err)); 813 for (ai = ailist; ai != NULL; ai = ai->ai_next) { 814 if ((rdf = ldns_sockaddr_storage2rdf((void*)ai->ai_addr, NULL)) == NULL) 815 die(1, "couldn't allocate an rdf: %s", 816 ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR)); 817 status = ldns_resolver_push_nameserver(res, rdf); 818 if (status != LDNS_STATUS_OK) 819 die(1, "couldn't push a nameserver address: %s", 820 ldns_get_errorstr_by_id(status)); 821 } 822 } 823 824 static void 825 resolver_set_nameserver_str(ldns_resolver *res, const char *server) { 826 ldns_rdf *addr; 827 828 ldns_resolver_remove_nameservers(res); 829 addr = ldns_rdf_new_addr_frm_str(server); 830 if (addr) { 831 if (ldns_resolver_push_nameserver(res, addr) != LDNS_STATUS_OK) 832 die(1, "couldn't push a nameserver address"); 833 } else 834 resolver_set_nameserver_hostname(res, server); 835 } 836 837 int 838 main(int argc, char *argv[]) { 839 ldns_rdf *addr, *dname; 840 ldns_resolver *res; 841 ldns_status status; 842 struct timeval restimeout; 843 844 parse_args(argc, argv); 845 846 status = ldns_resolver_new_default(&res); 847 if (status != LDNS_STATUS_OK) 848 die(1, "error creating resolver: %s", ldns_get_errorstr_by_id(status)); 849 if (ldns_resolver_nameserver_count(res) == 0) 850 ldns_resolver_push_default_servers(res); 851 852 ldns_resolver_set_usevc(res, o_tcp); 853 restimeout.tv_sec = o_timeout > 0 ? o_timeout : 854 o_tcp ? DEFAULT_TCP_TIMEOUT : DEFAULT_UDP_TIMEOUT; 855 restimeout.tv_usec = 0; 856 ldns_resolver_set_timeout(res, restimeout); 857 ldns_resolver_set_retry(res, o_retries+1); 858 ldns_resolver_set_ip6(res, o_ipversion); 859 ldns_resolver_set_defnames(res, false); 860 ldns_resolver_set_fallback(res, false); 861 862 if (o_server) 863 resolver_set_nameserver_str(res, o_server); 864 865 if (ldns_str2rdf_a(&addr, o_name) == LDNS_STATUS_OK) { 866 dname = ldns_rdf_reverse_a(addr, "in-addr.arpa"); 867 if (dname == NULL) 868 die(1, "can't reverse '%s': %s", o_name, 869 ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR)); 870 o_mode = M_SINGLE_Q; 871 o_rrtype = LDNS_RR_TYPE_PTR; 872 return !doquery(res, dname); 873 } else if (ldns_str2rdf_aaaa(&addr, o_name) == LDNS_STATUS_OK) { 874 dname = ldns_rdf_reverse_aaaa(addr, o_ip6_int ? "ip6.int" : "ip6.arpa"); 875 if (dname == NULL) 876 die(1, "can't reverse '%s': %s", o_name, 877 ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR)); 878 o_mode = M_SINGLE_Q; 879 o_rrtype = LDNS_RR_TYPE_PTR; 880 return !doquery(res, dname); 881 } 882 return !(o_mode == M_SOA ? dosoa : o_mode == M_AXFR ? doaxfr : dosearch) 883 (res, safe_str2rdf_dname(o_name), ndots(o_name) >= o_ndots); 884 } 885