host.c revision 143731
1/* 2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 2000-2003 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id: host.c,v 1.76.2.5.2.10 2004/09/06 01:33:05 marka Exp $ */ 19 20#include <config.h> 21#include <limits.h> 22 23#include <isc/app.h> 24#include <isc/commandline.h> 25#include <isc/netaddr.h> 26#include <isc/print.h> 27#include <isc/string.h> 28#include <isc/util.h> 29#include <isc/task.h> 30#include <isc/stdlib.h> 31 32#include <dns/byaddr.h> 33#include <dns/fixedname.h> 34#include <dns/message.h> 35#include <dns/name.h> 36#include <dns/rdata.h> 37#include <dns/rdataclass.h> 38#include <dns/rdataset.h> 39#include <dns/rdatatype.h> 40 41#include <dig/dig.h> 42 43extern ISC_LIST(dig_lookup_t) lookup_list; 44extern dig_serverlist_t server_list; 45extern ISC_LIST(dig_searchlist_t) search_list; 46 47extern isc_boolean_t have_ipv4, have_ipv6; 48extern isc_boolean_t usesearch; 49extern isc_boolean_t debugging; 50extern unsigned int timeout; 51extern isc_mem_t *mctx; 52extern int ndots; 53extern int tries; 54extern char *progname; 55extern isc_task_t *global_task; 56extern int fatalexit; 57 58static isc_boolean_t short_form = ISC_TRUE, listed_server = ISC_FALSE; 59static isc_boolean_t default_lookups = ISC_TRUE; 60static int seen_error = -1; 61static isc_boolean_t list_addresses = ISC_TRUE; 62static dns_rdatatype_t list_type = dns_rdatatype_a; 63 64static const char *opcodetext[] = { 65 "QUERY", 66 "IQUERY", 67 "STATUS", 68 "RESERVED3", 69 "NOTIFY", 70 "UPDATE", 71 "RESERVED6", 72 "RESERVED7", 73 "RESERVED8", 74 "RESERVED9", 75 "RESERVED10", 76 "RESERVED11", 77 "RESERVED12", 78 "RESERVED13", 79 "RESERVED14", 80 "RESERVED15" 81}; 82 83static const char *rcodetext[] = { 84 "NOERROR", 85 "FORMERR", 86 "SERVFAIL", 87 "NXDOMAIN", 88 "NOTIMP", 89 "REFUSED", 90 "YXDOMAIN", 91 "YXRRSET", 92 "NXRRSET", 93 "NOTAUTH", 94 "NOTZONE", 95 "RESERVED11", 96 "RESERVED12", 97 "RESERVED13", 98 "RESERVED14", 99 "RESERVED15", 100 "BADVERS" 101}; 102 103struct rtype { 104 unsigned int type; 105 const char *text; 106}; 107 108struct rtype rtypes[] = { 109 { 1, "has address" }, 110 { 2, "name server" }, 111 { 5, "is an alias for" }, 112 { 11, "has well known services" }, 113 { 12, "domain name pointer" }, 114 { 13, "host information" }, 115 { 15, "mail is handled by" }, 116 { 16, "descriptive text" }, 117 { 19, "x25 address" }, 118 { 20, "ISDN address" }, 119 { 24, "has signature" }, 120 { 25, "has key" }, 121 { 28, "has IPv6 address" }, 122 { 29, "location" }, 123 { 0, NULL } 124}; 125 126static void 127show_usage(void) { 128 fputs( 129"Usage: host [-aCdlriTwv] [-c class] [-N ndots] [-t type] [-W time]\n" 130" [-R number] hostname [server]\n" 131" -a is equivalent to -v -t *\n" 132" -c specifies query class for non-IN data\n" 133" -C compares SOA records on authoritative nameservers\n" 134" -d is equivalent to -v\n" 135" -l lists all hosts in a domain, using AXFR\n" 136" -i IP6.INT reverse lookups\n" 137" -N changes the number of dots allowed before root lookup is done\n" 138" -r disables recursive processing\n" 139" -R specifies number of retries for UDP packets\n" 140" -t specifies the query type\n" 141" -T enables TCP/IP mode\n" 142" -v enables verbose output\n" 143" -w specifies to wait forever for a reply\n" 144" -W specifies how long to wait for a reply\n" 145" -4 use IPv4 query transport only\n" 146" -6 use IPv6 query transport only\n", stderr); 147 exit(1); 148} 149 150void 151dighost_shutdown(void) { 152 isc_app_shutdown(); 153} 154 155void 156received(int bytes, isc_sockaddr_t *from, dig_query_t *query) { 157 isc_time_t now; 158 int diff; 159 160 if (!short_form) { 161 char fromtext[ISC_SOCKADDR_FORMATSIZE]; 162 isc_sockaddr_format(from, fromtext, sizeof(fromtext)); 163 TIME_NOW(&now); 164 diff = (int) isc_time_microdiff(&now, &query->time_sent); 165 printf("Received %u bytes from %s in %d ms\n", 166 bytes, fromtext, diff/1000); 167 } 168} 169 170void 171trying(char *frm, dig_lookup_t *lookup) { 172 UNUSED(lookup); 173 174 if (!short_form) 175 printf("Trying \"%s\"\n", frm); 176} 177 178static void 179say_message(dns_name_t *name, const char *msg, dns_rdata_t *rdata, 180 dig_query_t *query) 181{ 182 isc_buffer_t *b = NULL; 183 char namestr[DNS_NAME_FORMATSIZE]; 184 isc_region_t r; 185 isc_result_t result; 186 unsigned int bufsize = BUFSIZ; 187 188 dns_name_format(name, namestr, sizeof(namestr)); 189 retry: 190 result = isc_buffer_allocate(mctx, &b, bufsize); 191 check_result(result, "isc_buffer_allocate"); 192 result = dns_rdata_totext(rdata, NULL, b); 193 if (result == ISC_R_NOSPACE) { 194 isc_buffer_free(&b); 195 bufsize *= 2; 196 goto retry; 197 } 198 check_result(result, "dns_rdata_totext"); 199 isc_buffer_usedregion(b, &r); 200 if (query->lookup->identify_previous_line) { 201 printf("Nameserver %s:\n\t", 202 query->servname); 203 } 204 printf("%s %s %.*s", namestr, 205 msg, (int)r.length, (char *)r.base); 206 if (query->lookup->identify) { 207 printf(" on server %s", query->servname); 208 } 209 printf("\n"); 210 isc_buffer_free(&b); 211} 212#ifdef DIG_SIGCHASE 213/* Just for compatibility : not use in host program */ 214isc_result_t 215printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset, 216 isc_buffer_t *target) 217{ 218 UNUSED(owner_name); 219 UNUSED(rdataset); 220 UNUSED(target); 221 return(ISC_FALSE); 222} 223#endif 224static isc_result_t 225printsection(dns_message_t *msg, dns_section_t sectionid, 226 const char *section_name, isc_boolean_t headers, 227 dig_query_t *query) 228{ 229 dns_name_t *name, *print_name; 230 dns_rdataset_t *rdataset; 231 dns_rdata_t rdata = DNS_RDATA_INIT; 232 isc_buffer_t target; 233 isc_result_t result, loopresult; 234 isc_region_t r; 235 dns_name_t empty_name; 236 char t[4096]; 237 isc_boolean_t first; 238 isc_boolean_t no_rdata; 239 240 if (sectionid == DNS_SECTION_QUESTION) 241 no_rdata = ISC_TRUE; 242 else 243 no_rdata = ISC_FALSE; 244 245 if (headers) 246 printf(";; %s SECTION:\n", section_name); 247 248 dns_name_init(&empty_name, NULL); 249 250 result = dns_message_firstname(msg, sectionid); 251 if (result == ISC_R_NOMORE) 252 return (ISC_R_SUCCESS); 253 else if (result != ISC_R_SUCCESS) 254 return (result); 255 256 for (;;) { 257 name = NULL; 258 dns_message_currentname(msg, sectionid, &name); 259 260 isc_buffer_init(&target, t, sizeof(t)); 261 first = ISC_TRUE; 262 print_name = name; 263 264 for (rdataset = ISC_LIST_HEAD(name->list); 265 rdataset != NULL; 266 rdataset = ISC_LIST_NEXT(rdataset, link)) { 267 if (query->lookup->rdtype == dns_rdatatype_axfr && 268 !((!list_addresses && 269 (list_type == dns_rdatatype_any || 270 rdataset->type == list_type)) || 271 (list_addresses && 272 (rdataset->type == dns_rdatatype_a || 273 rdataset->type == dns_rdatatype_aaaa || 274 rdataset->type == dns_rdatatype_ns || 275 rdataset->type == dns_rdatatype_ptr)))) 276 continue; 277 if (!short_form) { 278 result = dns_rdataset_totext(rdataset, 279 print_name, 280 ISC_FALSE, 281 no_rdata, 282 &target); 283 if (result != ISC_R_SUCCESS) 284 return (result); 285#ifdef USEINITALWS 286 if (first) { 287 print_name = &empty_name; 288 first = ISC_FALSE; 289 } 290#else 291 UNUSED(first); /* Shut up compiler. */ 292#endif 293 } else { 294 loopresult = dns_rdataset_first(rdataset); 295 while (loopresult == ISC_R_SUCCESS) { 296 struct rtype *t; 297 const char *rtt; 298 char typebuf[DNS_RDATATYPE_FORMATSIZE]; 299 char typebuf2[DNS_RDATATYPE_FORMATSIZE 300 + 20]; 301 dns_rdataset_current(rdataset, &rdata); 302 303 for (t = rtypes; t->text != NULL; t++) { 304 if (t->type == rdata.type) { 305 rtt = t->text; 306 goto found; 307 } 308 } 309 310 dns_rdatatype_format(rdata.type, 311 typebuf, 312 sizeof(typebuf)); 313 snprintf(typebuf2, sizeof(typebuf2), 314 "has %s record", typebuf); 315 rtt = typebuf2; 316 found: 317 say_message(print_name, rtt, 318 &rdata, query); 319 dns_rdata_reset(&rdata); 320 loopresult = 321 dns_rdataset_next(rdataset); 322 } 323 } 324 } 325 if (!short_form) { 326 isc_buffer_usedregion(&target, &r); 327 if (no_rdata) 328 printf(";%.*s", (int)r.length, 329 (char *)r.base); 330 else 331 printf("%.*s", (int)r.length, (char *)r.base); 332 } 333 334 result = dns_message_nextname(msg, sectionid); 335 if (result == ISC_R_NOMORE) 336 break; 337 else if (result != ISC_R_SUCCESS) 338 return (result); 339 } 340 341 return (ISC_R_SUCCESS); 342} 343 344static isc_result_t 345printrdata(dns_message_t *msg, dns_rdataset_t *rdataset, dns_name_t *owner, 346 const char *set_name, isc_boolean_t headers) 347{ 348 isc_buffer_t target; 349 isc_result_t result; 350 isc_region_t r; 351 char t[4096]; 352 353 UNUSED(msg); 354 if (headers) 355 printf(";; %s SECTION:\n", set_name); 356 357 isc_buffer_init(&target, t, sizeof(t)); 358 359 result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE, 360 &target); 361 if (result != ISC_R_SUCCESS) 362 return (result); 363 isc_buffer_usedregion(&target, &r); 364 printf("%.*s", (int)r.length, (char *)r.base); 365 366 return (ISC_R_SUCCESS); 367} 368 369isc_result_t 370printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) { 371 isc_boolean_t did_flag = ISC_FALSE; 372 dns_rdataset_t *opt, *tsig = NULL; 373 dns_name_t *tsigname; 374 isc_result_t result = ISC_R_SUCCESS; 375 int force_error; 376 377 UNUSED(headers); 378 379 /* 380 * We get called multiple times. 381 * Preserve any existing error status. 382 */ 383 force_error = (seen_error == 1) ? 1 : 0; 384 seen_error = 1; 385 if (listed_server) { 386 char sockstr[ISC_SOCKADDR_FORMATSIZE]; 387 388 printf("Using domain server:\n"); 389 printf("Name: %s\n", query->userarg); 390 isc_sockaddr_format(&query->sockaddr, sockstr, 391 sizeof(sockstr)); 392 printf("Address: %s\n", sockstr); 393 printf("Aliases: \n\n"); 394 } 395 396 if (msg->rcode != 0) { 397 char namestr[DNS_NAME_FORMATSIZE]; 398 dns_name_format(query->lookup->name, namestr, sizeof(namestr)); 399 printf("Host %s not found: %d(%s)\n", namestr, 400 msg->rcode, rcodetext[msg->rcode]); 401 return (ISC_R_SUCCESS); 402 } 403 404 if (default_lookups && query->lookup->rdtype == dns_rdatatype_a) { 405 char namestr[DNS_NAME_FORMATSIZE]; 406 dig_lookup_t *lookup; 407 408 /* Add AAAA and MX lookups. */ 409 410 dns_name_format(query->lookup->name, namestr, sizeof(namestr)); 411 lookup = clone_lookup(query->lookup, ISC_FALSE); 412 if (lookup != NULL) { 413 strncpy(lookup->textname, namestr, 414 sizeof(lookup->textname)); 415 lookup->textname[sizeof(lookup->textname)-1] = 0; 416 lookup->rdtype = dns_rdatatype_aaaa; 417 lookup->rdtypeset = ISC_TRUE; 418 lookup->origin = NULL; 419 lookup->retries = tries; 420 ISC_LIST_APPEND(lookup_list, lookup, link); 421 } 422 lookup = clone_lookup(query->lookup, ISC_FALSE); 423 if (lookup != NULL) { 424 strncpy(lookup->textname, namestr, 425 sizeof(lookup->textname)); 426 lookup->textname[sizeof(lookup->textname)-1] = 0; 427 lookup->rdtype = dns_rdatatype_mx; 428 lookup->rdtypeset = ISC_TRUE; 429 lookup->origin = NULL; 430 lookup->retries = tries; 431 ISC_LIST_APPEND(lookup_list, lookup, link); 432 } 433 } 434 435 if (!short_form) { 436 printf(";; ->>HEADER<<- opcode: %s, status: %s, id: %u\n", 437 opcodetext[msg->opcode], rcodetext[msg->rcode], 438 msg->id); 439 printf(";; flags: "); 440 if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) { 441 printf("qr"); 442 did_flag = ISC_TRUE; 443 } 444 if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) { 445 printf("%saa", did_flag ? " " : ""); 446 did_flag = ISC_TRUE; 447 } 448 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) { 449 printf("%stc", did_flag ? " " : ""); 450 did_flag = ISC_TRUE; 451 } 452 if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) { 453 printf("%srd", did_flag ? " " : ""); 454 did_flag = ISC_TRUE; 455 } 456 if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) { 457 printf("%sra", did_flag ? " " : ""); 458 did_flag = ISC_TRUE; 459 } 460 if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) { 461 printf("%sad", did_flag ? " " : ""); 462 did_flag = ISC_TRUE; 463 } 464 if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) { 465 printf("%scd", did_flag ? " " : ""); 466 did_flag = ISC_TRUE; 467 } 468 printf("; QUERY: %u, ANSWER: %u, " 469 "AUTHORITY: %u, ADDITIONAL: %u\n", 470 msg->counts[DNS_SECTION_QUESTION], 471 msg->counts[DNS_SECTION_ANSWER], 472 msg->counts[DNS_SECTION_AUTHORITY], 473 msg->counts[DNS_SECTION_ADDITIONAL]); 474 opt = dns_message_getopt(msg); 475 if (opt != NULL) 476 printf(";; EDNS: version: %u, udp=%u\n", 477 (unsigned int)((opt->ttl & 0x00ff0000) >> 16), 478 (unsigned int)opt->rdclass); 479 tsigname = NULL; 480 tsig = dns_message_gettsig(msg, &tsigname); 481 if (tsig != NULL) 482 printf(";; PSEUDOSECTIONS: TSIG\n"); 483 } 484 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_QUESTION]) && 485 !short_form) { 486 printf("\n"); 487 result = printsection(msg, DNS_SECTION_QUESTION, "QUESTION", 488 ISC_TRUE, query); 489 if (result != ISC_R_SUCCESS) 490 return (result); 491 } 492 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) { 493 if (!short_form) 494 printf("\n"); 495 result = printsection(msg, DNS_SECTION_ANSWER, "ANSWER", 496 ISC_TF(!short_form), query); 497 if (result != ISC_R_SUCCESS) 498 return (result); 499 } 500 501 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_AUTHORITY]) && 502 !short_form) { 503 printf("\n"); 504 result = printsection(msg, DNS_SECTION_AUTHORITY, "AUTHORITY", 505 ISC_TRUE, query); 506 if (result != ISC_R_SUCCESS) 507 return (result); 508 } 509 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ADDITIONAL]) && 510 !short_form) { 511 printf("\n"); 512 result = printsection(msg, DNS_SECTION_ADDITIONAL, 513 "ADDITIONAL", ISC_TRUE, query); 514 if (result != ISC_R_SUCCESS) 515 return (result); 516 } 517 if ((tsig != NULL) && !short_form) { 518 printf("\n"); 519 result = printrdata(msg, tsig, tsigname, 520 "PSEUDOSECTION TSIG", ISC_TRUE); 521 if (result != ISC_R_SUCCESS) 522 return (result); 523 } 524 if (!short_form) 525 printf("\n"); 526 527 if (short_form && !default_lookups && 528 ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) { 529 char namestr[DNS_NAME_FORMATSIZE]; 530 char typestr[DNS_RDATATYPE_FORMATSIZE]; 531 dns_name_format(query->lookup->name, namestr, sizeof(namestr)); 532 dns_rdatatype_format(query->lookup->rdtype, typestr, 533 sizeof(typestr)); 534 printf("%s has no %s record\n", namestr, typestr); 535 } 536 seen_error = force_error; 537 return (result); 538} 539 540static void 541parse_args(isc_boolean_t is_batchfile, int argc, char **argv) { 542 char hostname[MXNAME]; 543 dig_lookup_t *lookup; 544 int c; 545 char store[MXNAME]; 546 isc_textregion_t tr; 547 isc_result_t result = ISC_R_SUCCESS; 548 dns_rdatatype_t rdtype; 549 dns_rdataclass_t rdclass; 550 isc_uint32_t serial = 0; 551 552 UNUSED(is_batchfile); 553 554 lookup = make_empty_lookup(); 555 556 while ((c = isc_commandline_parse(argc, argv, "lvwrdt:c:aTCN:R:W:Dni46")) 557 != EOF) { 558 switch (c) { 559 case 'l': 560 lookup->tcp_mode = ISC_TRUE; 561 lookup->rdtype = dns_rdatatype_axfr; 562 lookup->rdtypeset = ISC_TRUE; 563 fatalexit = 3; 564 break; 565 case 'v': 566 case 'd': 567 short_form = ISC_FALSE; 568 break; 569 case 'r': 570 lookup->recurse = ISC_FALSE; 571 break; 572 case 't': 573 if (strncasecmp(isc_commandline_argument, 574 "ixfr=", 5) == 0) { 575 rdtype = dns_rdatatype_ixfr; 576 /* XXXMPA add error checking */ 577 serial = strtoul(isc_commandline_argument + 5, 578 NULL, 10); 579 result = ISC_R_SUCCESS; 580 } else { 581 tr.base = isc_commandline_argument; 582 tr.length = strlen(isc_commandline_argument); 583 result = dns_rdatatype_fromtext(&rdtype, 584 (isc_textregion_t *)&tr); 585 } 586 587 if (result != ISC_R_SUCCESS) { 588 fatalexit = 2; 589 fatal("invalid type: %s\n", 590 isc_commandline_argument); 591 } 592 if (!lookup->rdtypeset || 593 lookup->rdtype != dns_rdatatype_axfr) 594 lookup->rdtype = rdtype; 595 lookup->rdtypeset = ISC_TRUE; 596 if (rdtype == dns_rdatatype_axfr) { 597 /* -l -t any -v */ 598 list_type = dns_rdatatype_any; 599 short_form = ISC_FALSE; 600 lookup->tcp_mode = ISC_TRUE; 601 } else if (rdtype == dns_rdatatype_ixfr) { 602 lookup->ixfr_serial = serial; 603 list_type = rdtype; 604 } else 605 list_type = rdtype; 606 list_addresses = ISC_FALSE; 607 break; 608 case 'c': 609 tr.base = isc_commandline_argument; 610 tr.length = strlen(isc_commandline_argument); 611 result = dns_rdataclass_fromtext(&rdclass, 612 (isc_textregion_t *)&tr); 613 614 if (result != ISC_R_SUCCESS) { 615 fatalexit = 2; 616 fatal("invalid class: %s\n", 617 isc_commandline_argument); 618 } else { 619 lookup->rdclass = rdclass; 620 lookup->rdclassset = ISC_TRUE; 621 } 622 default_lookups = ISC_FALSE; 623 break; 624 case 'a': 625 if (!lookup->rdtypeset || 626 lookup->rdtype != dns_rdatatype_axfr) 627 lookup->rdtype = dns_rdatatype_any; 628 list_type = dns_rdatatype_any; 629 list_addresses = ISC_FALSE; 630 lookup->rdtypeset = ISC_TRUE; 631 short_form = ISC_FALSE; 632 default_lookups = ISC_FALSE; 633 break; 634 case 'i': 635 lookup->ip6_int = ISC_TRUE; 636 break; 637 case 'n': 638 /* deprecated */ 639 break; 640 case 'w': 641 /* 642 * The timer routines are coded such that 643 * timeout==MAXINT doesn't enable the timer 644 */ 645 timeout = INT_MAX; 646 break; 647 case 'W': 648 timeout = atoi(isc_commandline_argument); 649 if (timeout < 1) 650 timeout = 1; 651 break; 652 case 'R': 653 tries = atoi(isc_commandline_argument) + 1; 654 if (tries < 2) 655 tries = 2; 656 break; 657 case 'T': 658 lookup->tcp_mode = ISC_TRUE; 659 break; 660 case 'C': 661 debug("showing all SOAs"); 662 lookup->rdtype = dns_rdatatype_ns; 663 lookup->rdtypeset = ISC_TRUE; 664 lookup->rdclass = dns_rdataclass_in; 665 lookup->rdclassset = ISC_TRUE; 666 lookup->ns_search_only = ISC_TRUE; 667 lookup->trace_root = ISC_TRUE; 668 lookup->identify_previous_line = ISC_TRUE; 669 default_lookups = ISC_FALSE; 670 break; 671 case 'N': 672 debug("setting NDOTS to %s", 673 isc_commandline_argument); 674 ndots = atoi(isc_commandline_argument); 675 break; 676 case 'D': 677 debugging = ISC_TRUE; 678 break; 679 case '4': 680 if (have_ipv4) { 681 isc_net_disableipv6(); 682 have_ipv6 = ISC_FALSE; 683 } else 684 fatal("can't find IPv4 networking"); 685 break; 686 case '6': 687 if (have_ipv6) { 688 isc_net_disableipv4(); 689 have_ipv4 = ISC_FALSE; 690 } else 691 fatal("can't find IPv6 networking"); 692 break; 693 } 694 } 695 696 lookup->retries = tries; 697 698 if (isc_commandline_index >= argc) 699 show_usage(); 700 701 strncpy(hostname, argv[isc_commandline_index], sizeof(hostname)); 702 hostname[sizeof(hostname)-1]=0; 703 if (argc > isc_commandline_index + 1) { 704 set_nameserver(argv[isc_commandline_index+1]); 705 debug("server is %s", argv[isc_commandline_index+1]); 706 listed_server = ISC_TRUE; 707 } 708 709 lookup->pending = ISC_FALSE; 710 if (get_reverse(store, sizeof(store), hostname, 711 lookup->ip6_int, ISC_TRUE) == ISC_R_SUCCESS) { 712 strncpy(lookup->textname, store, sizeof(lookup->textname)); 713 lookup->textname[sizeof(lookup->textname)-1] = 0; 714 lookup->rdtype = dns_rdatatype_ptr; 715 lookup->rdtypeset = ISC_TRUE; 716 default_lookups = ISC_FALSE; 717 } else { 718 strncpy(lookup->textname, hostname, sizeof(lookup->textname)); 719 lookup->textname[sizeof(lookup->textname)-1]=0; 720 } 721 lookup->new_search = ISC_TRUE; 722 ISC_LIST_APPEND(lookup_list, lookup, link); 723 724 usesearch = ISC_TRUE; 725} 726 727int 728main(int argc, char **argv) { 729 isc_result_t result; 730 731 tries = 2; 732 733 ISC_LIST_INIT(lookup_list); 734 ISC_LIST_INIT(server_list); 735 ISC_LIST_INIT(search_list); 736 737 fatalexit = 1; 738 739 debug("main()"); 740 progname = argv[0]; 741 result = isc_app_start(); 742 check_result(result, "isc_app_start"); 743 setup_libs(); 744 parse_args(ISC_FALSE, argc, argv); 745 setup_system(); 746 result = isc_app_onrun(mctx, global_task, onrun_callback, NULL); 747 check_result(result, "isc_app_onrun"); 748 isc_app_run(); 749 cancel_all(); 750 destroy_libs(); 751 isc_app_finish(); 752 return ((seen_error == 0) ? 0 : 1); 753} 754 755