00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021 #include <stdlib.h>
00022 #include <limits.h>
00023
00024 #ifdef HAVE_LOCALE_H
00025 #include <locale.h>
00026 #endif
00027
00028 #ifdef WITH_IDN
00029 #include <idn/result.h>
00030 #include <idn/log.h>
00031 #include <idn/resconf.h>
00032 #include <idn/api.h>
00033 #endif
00034
00035 #include <isc/app.h>
00036 #include <isc/commandline.h>
00037 #include <isc/netaddr.h>
00038 #include <isc/print.h>
00039 #include <isc/string.h>
00040 #include <isc/util.h>
00041 #include <isc/task.h>
00042 #include <isc/stdlib.h>
00043
00044 #include <dns/byaddr.h>
00045 #include <dns/fixedname.h>
00046 #include <dns/message.h>
00047 #include <dns/name.h>
00048 #include <dns/rdata.h>
00049 #include <dns/rdataclass.h>
00050 #include <dns/rdataset.h>
00051 #include <dns/rdatatype.h>
00052 #include <dns/rdatastruct.h>
00053
00054 #include <dig/dig.h>
00055
00056 static isc_boolean_t short_form = ISC_TRUE, listed_server = ISC_FALSE;
00057 static isc_boolean_t default_lookups = ISC_TRUE;
00058 static int seen_error = -1;
00059 static isc_boolean_t list_addresses = ISC_TRUE;
00060 static dns_rdatatype_t list_type = dns_rdatatype_a;
00061 static isc_boolean_t printed_server = ISC_FALSE;
00062
00063 static const char *opcodetext[] = {
00064 "QUERY",
00065 "IQUERY",
00066 "STATUS",
00067 "RESERVED3",
00068 "NOTIFY",
00069 "UPDATE",
00070 "RESERVED6",
00071 "RESERVED7",
00072 "RESERVED8",
00073 "RESERVED9",
00074 "RESERVED10",
00075 "RESERVED11",
00076 "RESERVED12",
00077 "RESERVED13",
00078 "RESERVED14",
00079 "RESERVED15"
00080 };
00081
00082 static const char *rcodetext[] = {
00083 "NOERROR",
00084 "FORMERR",
00085 "SERVFAIL",
00086 "NXDOMAIN",
00087 "NOTIMP",
00088 "REFUSED",
00089 "YXDOMAIN",
00090 "YXRRSET",
00091 "NXRRSET",
00092 "NOTAUTH",
00093 "NOTZONE",
00094 "RESERVED11",
00095 "RESERVED12",
00096 "RESERVED13",
00097 "RESERVED14",
00098 "RESERVED15",
00099 "BADVERS"
00100 };
00101
00102 struct rtype {
00103 unsigned int type;
00104 const char *text;
00105 };
00106
00107 struct rtype rtypes[] = {
00108 { 1, "has address" },
00109 { 2, "name server" },
00110 { 5, "is an alias for" },
00111 { 11, "has well known services" },
00112 { 12, "domain name pointer" },
00113 { 13, "host information" },
00114 { 15, "mail is handled by" },
00115 { 16, "descriptive text" },
00116 { 19, "x25 address" },
00117 { 20, "ISDN address" },
00118 { 24, "has signature" },
00119 { 25, "has key" },
00120 { 28, "has IPv6 address" },
00121 { 29, "location" },
00122 { 0, NULL }
00123 };
00124
00125 static char *
00126 rcode_totext(dns_rcode_t rcode)
00127 {
00128 static char buf[sizeof("?65535")];
00129 union {
00130 const char *consttext;
00131 char *deconsttext;
00132 } totext;
00133
00134 if (rcode >= (sizeof(rcodetext)/sizeof(rcodetext[0]))) {
00135 snprintf(buf, sizeof(buf), "?%u", rcode);
00136 totext.deconsttext = buf;
00137 } else
00138 totext.consttext = rcodetext[rcode];
00139 return totext.deconsttext;
00140 }
00141
00142 ISC_PLATFORM_NORETURN_PRE static void
00143 show_usage(void) ISC_PLATFORM_NORETURN_POST;
00144
00145 static void
00146 show_usage(void) {
00147 fputs(
00148 "Usage: host [-aCdlriTwv] [-c class] [-N ndots] [-t type] [-W time]\n"
00149 " [-R number] [-m flag] hostname [server]\n"
00150 " -a is equivalent to -v -t ANY\n"
00151 " -c specifies query class for non-IN data\n"
00152 " -C compares SOA records on authoritative nameservers\n"
00153 " -d is equivalent to -v\n"
00154 " -l lists all hosts in a domain, using AXFR\n"
00155 " -i IP6.INT reverse lookups\n"
00156 " -N changes the number of dots allowed before root lookup is done\n"
00157 " -r disables recursive processing\n"
00158 " -R specifies number of retries for UDP packets\n"
00159 " -s a SERVFAIL response should stop query\n"
00160 " -t specifies the query type\n"
00161 " -T enables TCP/IP mode\n"
00162 " -v enables verbose output\n"
00163 " -w specifies to wait forever for a reply\n"
00164 " -W specifies how long to wait for a reply\n"
00165 " -4 use IPv4 query transport only\n"
00166 " -6 use IPv6 query transport only\n"
00167 " -m set memory debugging flag (trace|record|usage)\n"
00168 " -V print version number and exit\n", stderr);
00169 exit(1);
00170 }
00171
00172 void
00173 dighost_shutdown(void) {
00174 isc_app_shutdown();
00175 }
00176
00177 void
00178 received(int bytes, isc_sockaddr_t *from, dig_query_t *query) {
00179 isc_time_t now;
00180 int diff;
00181
00182 if (!short_form) {
00183 char fromtext[ISC_SOCKADDR_FORMATSIZE];
00184 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
00185 TIME_NOW(&now);
00186 diff = (int) isc_time_microdiff(&now, &query->time_sent);
00187 printf("Received %u bytes from %s in %d ms\n",
00188 bytes, fromtext, diff/1000);
00189 }
00190 }
00191
00192 void
00193 trying(char *frm, dig_lookup_t *lookup) {
00194 UNUSED(lookup);
00195
00196 if (!short_form)
00197 printf("Trying \"%s\"\n", frm);
00198 }
00199
00200 static void
00201 say_message(dns_name_t *name, const char *msg, dns_rdata_t *rdata,
00202 dig_query_t *query)
00203 {
00204 isc_buffer_t *b = NULL;
00205 char namestr[DNS_NAME_FORMATSIZE];
00206 isc_region_t r;
00207 isc_result_t result;
00208 unsigned int bufsize = BUFSIZ;
00209
00210 dns_name_format(name, namestr, sizeof(namestr));
00211 retry:
00212 result = isc_buffer_allocate(mctx, &b, bufsize);
00213 check_result(result, "isc_buffer_allocate");
00214 result = dns_rdata_totext(rdata, NULL, b);
00215 if (result == ISC_R_NOSPACE) {
00216 isc_buffer_free(&b);
00217 bufsize *= 2;
00218 goto retry;
00219 }
00220 check_result(result, "dns_rdata_totext");
00221 isc_buffer_usedregion(b, &r);
00222 if (query->lookup->identify_previous_line) {
00223 printf("Nameserver %s:\n\t",
00224 query->servname);
00225 }
00226 printf("%s %s %.*s", namestr,
00227 msg, (int)r.length, (char *)r.base);
00228 if (query->lookup->identify) {
00229 printf(" on server %s", query->servname);
00230 }
00231 printf("\n");
00232 isc_buffer_free(&b);
00233 }
00234 #ifdef DIG_SIGCHASE
00235
00236 isc_result_t
00237 printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset,
00238 isc_buffer_t *target)
00239 {
00240 UNUSED(owner_name);
00241 UNUSED(rdataset);
00242 UNUSED(target);
00243 return(ISC_FALSE);
00244 }
00245 #endif
00246 static isc_result_t
00247 printsection(dns_message_t *msg, dns_section_t sectionid,
00248 const char *section_name, isc_boolean_t headers,
00249 dig_query_t *query)
00250 {
00251 dns_name_t *name, *print_name;
00252 dns_rdataset_t *rdataset;
00253 dns_rdata_t rdata = DNS_RDATA_INIT;
00254 isc_buffer_t target;
00255 isc_result_t result, loopresult;
00256 isc_region_t r;
00257 dns_name_t empty_name;
00258 char tbuf[4096];
00259 isc_boolean_t first;
00260 isc_boolean_t no_rdata;
00261
00262 if (sectionid == DNS_SECTION_QUESTION)
00263 no_rdata = ISC_TRUE;
00264 else
00265 no_rdata = ISC_FALSE;
00266
00267 if (headers)
00268 printf(";; %s SECTION:\n", section_name);
00269
00270 dns_name_init(&empty_name, NULL);
00271
00272 result = dns_message_firstname(msg, sectionid);
00273 if (result == ISC_R_NOMORE)
00274 return (ISC_R_SUCCESS);
00275 else if (result != ISC_R_SUCCESS)
00276 return (result);
00277
00278 for (;;) {
00279 name = NULL;
00280 dns_message_currentname(msg, sectionid, &name);
00281
00282 isc_buffer_init(&target, tbuf, sizeof(tbuf));
00283 first = ISC_TRUE;
00284 print_name = name;
00285
00286 for (rdataset = ISC_LIST_HEAD(name->list);
00287 rdataset != NULL;
00288 rdataset = ISC_LIST_NEXT(rdataset, link)) {
00289 if (query->lookup->rdtype == dns_rdatatype_axfr &&
00290 !((!list_addresses &&
00291 (list_type == dns_rdatatype_any ||
00292 rdataset->type == list_type)) ||
00293 (list_addresses &&
00294 (rdataset->type == dns_rdatatype_a ||
00295 rdataset->type == dns_rdatatype_aaaa ||
00296 rdataset->type == dns_rdatatype_ns ||
00297 rdataset->type == dns_rdatatype_ptr))))
00298 continue;
00299 if (!short_form) {
00300 result = dns_rdataset_totext(rdataset,
00301 print_name,
00302 ISC_FALSE,
00303 no_rdata,
00304 &target);
00305 if (result != ISC_R_SUCCESS)
00306 return (result);
00307 #ifdef USEINITALWS
00308 if (first) {
00309 print_name = &empty_name;
00310 first = ISC_FALSE;
00311 }
00312 #else
00313 UNUSED(first);
00314 #endif
00315 } else {
00316 loopresult = dns_rdataset_first(rdataset);
00317 while (loopresult == ISC_R_SUCCESS) {
00318 struct rtype *t;
00319 const char *rtt;
00320 char typebuf[DNS_RDATATYPE_FORMATSIZE];
00321 char typebuf2[DNS_RDATATYPE_FORMATSIZE
00322 + 20];
00323 dns_rdataset_current(rdataset, &rdata);
00324
00325 for (t = rtypes; t->text != NULL; t++) {
00326 if (t->type == rdata.type) {
00327 rtt = t->text;
00328 goto found;
00329 }
00330 }
00331
00332 dns_rdatatype_format(rdata.type,
00333 typebuf,
00334 sizeof(typebuf));
00335 snprintf(typebuf2, sizeof(typebuf2),
00336 "has %s record", typebuf);
00337 rtt = typebuf2;
00338 found:
00339 say_message(print_name, rtt,
00340 &rdata, query);
00341 dns_rdata_reset(&rdata);
00342 loopresult =
00343 dns_rdataset_next(rdataset);
00344 }
00345 }
00346 }
00347 if (!short_form) {
00348 isc_buffer_usedregion(&target, &r);
00349 if (no_rdata)
00350 printf(";%.*s", (int)r.length,
00351 (char *)r.base);
00352 else
00353 printf("%.*s", (int)r.length, (char *)r.base);
00354 }
00355
00356 result = dns_message_nextname(msg, sectionid);
00357 if (result == ISC_R_NOMORE)
00358 break;
00359 else if (result != ISC_R_SUCCESS)
00360 return (result);
00361 }
00362
00363 return (ISC_R_SUCCESS);
00364 }
00365
00366 static isc_result_t
00367 printrdata(dns_message_t *msg, dns_rdataset_t *rdataset, dns_name_t *owner,
00368 const char *set_name, isc_boolean_t headers)
00369 {
00370 isc_buffer_t target;
00371 isc_result_t result;
00372 isc_region_t r;
00373 char tbuf[4096];
00374
00375 UNUSED(msg);
00376 if (headers)
00377 printf(";; %s SECTION:\n", set_name);
00378
00379 isc_buffer_init(&target, tbuf, sizeof(tbuf));
00380
00381 result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE,
00382 &target);
00383 if (result != ISC_R_SUCCESS)
00384 return (result);
00385 isc_buffer_usedregion(&target, &r);
00386 printf("%.*s", (int)r.length, (char *)r.base);
00387
00388 return (ISC_R_SUCCESS);
00389 }
00390
00391 static void
00392 chase_cnamechain(dns_message_t *msg, dns_name_t *qname) {
00393 isc_result_t result;
00394 dns_rdataset_t *rdataset;
00395 dns_rdata_cname_t cname;
00396 dns_rdata_t rdata = DNS_RDATA_INIT;
00397 unsigned int i = msg->counts[DNS_SECTION_ANSWER];
00398
00399 while (i-- > 0) {
00400 rdataset = NULL;
00401 result = dns_message_findname(msg, DNS_SECTION_ANSWER, qname,
00402 dns_rdatatype_cname, 0, NULL,
00403 &rdataset);
00404 if (result != ISC_R_SUCCESS)
00405 return;
00406 result = dns_rdataset_first(rdataset);
00407 check_result(result, "dns_rdataset_first");
00408 dns_rdata_reset(&rdata);
00409 dns_rdataset_current(rdataset, &rdata);
00410 result = dns_rdata_tostruct(&rdata, &cname, NULL);
00411 check_result(result, "dns_rdata_tostruct");
00412 dns_name_copy(&cname.cname, qname, NULL);
00413 dns_rdata_freestruct(&cname);
00414 }
00415 }
00416
00417 isc_result_t
00418 printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) {
00419 isc_boolean_t did_flag = ISC_FALSE;
00420 dns_rdataset_t *opt, *tsig = NULL;
00421 dns_name_t *tsigname;
00422 isc_result_t result = ISC_R_SUCCESS;
00423 int force_error;
00424
00425 UNUSED(headers);
00426
00427
00428
00429
00430
00431 force_error = (seen_error == 1) ? 1 : 0;
00432 seen_error = 1;
00433 if (listed_server && !printed_server) {
00434 char sockstr[ISC_SOCKADDR_FORMATSIZE];
00435
00436 printf("Using domain server:\n");
00437 printf("Name: %s\n", query->userarg);
00438 isc_sockaddr_format(&query->sockaddr, sockstr,
00439 sizeof(sockstr));
00440 printf("Address: %s\n", sockstr);
00441 printf("Aliases: \n\n");
00442 printed_server = ISC_TRUE;
00443 }
00444
00445 if (msg->rcode != 0) {
00446 char namestr[DNS_NAME_FORMATSIZE];
00447 dns_name_format(query->lookup->name, namestr, sizeof(namestr));
00448
00449 if (query->lookup->identify_previous_line)
00450 printf("Nameserver %s:\n\t%s not found: %d(%s)\n",
00451 query->servname,
00452 (msg->rcode != dns_rcode_nxdomain) ? namestr :
00453 query->lookup->textname, msg->rcode,
00454 rcode_totext(msg->rcode));
00455 else
00456 printf("Host %s not found: %d(%s)\n",
00457 (msg->rcode != dns_rcode_nxdomain) ? namestr :
00458 query->lookup->textname, msg->rcode,
00459 rcode_totext(msg->rcode));
00460 return (ISC_R_SUCCESS);
00461 }
00462
00463 if (default_lookups && query->lookup->rdtype == dns_rdatatype_a) {
00464 char namestr[DNS_NAME_FORMATSIZE];
00465 dig_lookup_t *lookup;
00466 dns_fixedname_t fixed;
00467 dns_name_t *name;
00468
00469
00470 dns_fixedname_init(&fixed);
00471 name = dns_fixedname_name(&fixed);
00472 dns_name_copy(query->lookup->name, name, NULL);
00473 chase_cnamechain(msg, name);
00474 dns_name_format(name, namestr, sizeof(namestr));
00475 lookup = clone_lookup(query->lookup, ISC_FALSE);
00476 if (lookup != NULL) {
00477 strncpy(lookup->textname, namestr,
00478 sizeof(lookup->textname));
00479 lookup->textname[sizeof(lookup->textname)-1] = 0;
00480 lookup->rdtype = dns_rdatatype_aaaa;
00481 lookup->rdtypeset = ISC_TRUE;
00482 lookup->origin = NULL;
00483 lookup->retries = tries;
00484 ISC_LIST_APPEND(lookup_list, lookup, link);
00485 }
00486 lookup = clone_lookup(query->lookup, ISC_FALSE);
00487 if (lookup != NULL) {
00488 strncpy(lookup->textname, namestr,
00489 sizeof(lookup->textname));
00490 lookup->textname[sizeof(lookup->textname)-1] = 0;
00491 lookup->rdtype = dns_rdatatype_mx;
00492 lookup->rdtypeset = ISC_TRUE;
00493 lookup->origin = NULL;
00494 lookup->retries = tries;
00495 ISC_LIST_APPEND(lookup_list, lookup, link);
00496 }
00497 }
00498
00499 if (!short_form) {
00500 printf(";; ->>HEADER<<- opcode: %s, status: %s, id: %u\n",
00501 opcodetext[msg->opcode], rcode_totext(msg->rcode),
00502 msg->id);
00503 printf(";; flags: ");
00504 if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) {
00505 printf("qr");
00506 did_flag = ISC_TRUE;
00507 }
00508 if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) {
00509 printf("%saa", did_flag ? " " : "");
00510 did_flag = ISC_TRUE;
00511 }
00512 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
00513 printf("%stc", did_flag ? " " : "");
00514 did_flag = ISC_TRUE;
00515 }
00516 if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) {
00517 printf("%srd", did_flag ? " " : "");
00518 did_flag = ISC_TRUE;
00519 }
00520 if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) {
00521 printf("%sra", did_flag ? " " : "");
00522 did_flag = ISC_TRUE;
00523 }
00524 if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) {
00525 printf("%sad", did_flag ? " " : "");
00526 did_flag = ISC_TRUE;
00527 }
00528 if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) {
00529 printf("%scd", did_flag ? " " : "");
00530 did_flag = ISC_TRUE;
00531 POST(did_flag);
00532 }
00533 printf("; QUERY: %u, ANSWER: %u, "
00534 "AUTHORITY: %u, ADDITIONAL: %u\n",
00535 msg->counts[DNS_SECTION_QUESTION],
00536 msg->counts[DNS_SECTION_ANSWER],
00537 msg->counts[DNS_SECTION_AUTHORITY],
00538 msg->counts[DNS_SECTION_ADDITIONAL]);
00539 opt = dns_message_getopt(msg);
00540 if (opt != NULL)
00541 printf(";; EDNS: version: %u, udp=%u\n",
00542 (unsigned int)((opt->ttl & 0x00ff0000) >> 16),
00543 (unsigned int)opt->rdclass);
00544 tsigname = NULL;
00545 tsig = dns_message_gettsig(msg, &tsigname);
00546 if (tsig != NULL)
00547 printf(";; PSEUDOSECTIONS: TSIG\n");
00548 }
00549 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_QUESTION]) &&
00550 !short_form) {
00551 printf("\n");
00552 result = printsection(msg, DNS_SECTION_QUESTION, "QUESTION",
00553 ISC_TRUE, query);
00554 if (result != ISC_R_SUCCESS)
00555 return (result);
00556 }
00557 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) {
00558 if (!short_form)
00559 printf("\n");
00560 result = printsection(msg, DNS_SECTION_ANSWER, "ANSWER",
00561 ISC_TF(!short_form), query);
00562 if (result != ISC_R_SUCCESS)
00563 return (result);
00564 }
00565
00566 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_AUTHORITY]) &&
00567 !short_form) {
00568 printf("\n");
00569 result = printsection(msg, DNS_SECTION_AUTHORITY, "AUTHORITY",
00570 ISC_TRUE, query);
00571 if (result != ISC_R_SUCCESS)
00572 return (result);
00573 }
00574 if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ADDITIONAL]) &&
00575 !short_form) {
00576 printf("\n");
00577 result = printsection(msg, DNS_SECTION_ADDITIONAL,
00578 "ADDITIONAL", ISC_TRUE, query);
00579 if (result != ISC_R_SUCCESS)
00580 return (result);
00581 }
00582 if ((tsig != NULL) && !short_form) {
00583 printf("\n");
00584 result = printrdata(msg, tsig, tsigname,
00585 "PSEUDOSECTION TSIG", ISC_TRUE);
00586 if (result != ISC_R_SUCCESS)
00587 return (result);
00588 }
00589 if (!short_form)
00590 printf("\n");
00591
00592 if (short_form && !default_lookups &&
00593 ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) {
00594 char namestr[DNS_NAME_FORMATSIZE];
00595 char typestr[DNS_RDATATYPE_FORMATSIZE];
00596 dns_name_format(query->lookup->name, namestr, sizeof(namestr));
00597 dns_rdatatype_format(query->lookup->rdtype, typestr,
00598 sizeof(typestr));
00599 printf("%s has no %s record\n", namestr, typestr);
00600 }
00601 seen_error = force_error;
00602 return (result);
00603 }
00604
00605 static const char * optstring = "46ac:dilnm:rst:vVwCDN:R:TW:";
00606
00607
00608 static void
00609 version(void) {
00610 fputs("host " VERSION "\n", stderr);
00611 }
00612
00613 static void
00614 pre_parse_args(int argc, char **argv) {
00615 int c;
00616
00617 while ((c = isc_commandline_parse(argc, argv, optstring)) != -1) {
00618 switch (c) {
00619 case 'm':
00620 memdebugging = ISC_TRUE;
00621 if (strcasecmp("trace", isc_commandline_argument) == 0)
00622 isc_mem_debugging |= ISC_MEM_DEBUGTRACE;
00623 else if (!strcasecmp("record",
00624 isc_commandline_argument) == 0)
00625 isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
00626 else if (strcasecmp("usage",
00627 isc_commandline_argument) == 0)
00628 isc_mem_debugging |= ISC_MEM_DEBUGUSAGE;
00629 break;
00630
00631 case '4': break;
00632 case '6': break;
00633 case 'a': break;
00634 case 'c': break;
00635 case 'd': break;
00636 case 'i': break;
00637 case 'l': break;
00638 case 'n': break;
00639 case 'r': break;
00640 case 's': break;
00641 case 't': break;
00642 case 'v': break;
00643 case 'V':
00644 version();
00645 exit(0);
00646 break;
00647 case 'w': break;
00648 case 'C': break;
00649 case 'D':
00650 if (debugging)
00651 debugtiming = ISC_TRUE;
00652 debugging = ISC_TRUE;
00653 break;
00654 case 'N': break;
00655 case 'R': break;
00656 case 'T': break;
00657 case 'W': break;
00658 default:
00659 show_usage();
00660 }
00661 }
00662 isc_commandline_reset = ISC_TRUE;
00663 isc_commandline_index = 1;
00664 }
00665
00666 static void
00667 parse_args(isc_boolean_t is_batchfile, int argc, char **argv) {
00668 char hostname[MXNAME];
00669 dig_lookup_t *lookup;
00670 int c;
00671 char store[MXNAME];
00672 isc_textregion_t tr;
00673 isc_result_t result = ISC_R_SUCCESS;
00674 dns_rdatatype_t rdtype;
00675 dns_rdataclass_t rdclass;
00676 isc_uint32_t serial = 0;
00677
00678 UNUSED(is_batchfile);
00679
00680 lookup = make_empty_lookup();
00681
00682 lookup->servfail_stops = ISC_FALSE;
00683 lookup->comments = ISC_FALSE;
00684 short_form = !verbose;
00685
00686 while ((c = isc_commandline_parse(argc, argv, optstring)) != -1) {
00687 switch (c) {
00688 case 'l':
00689 lookup->tcp_mode = ISC_TRUE;
00690 lookup->rdtype = dns_rdatatype_axfr;
00691 lookup->rdtypeset = ISC_TRUE;
00692 fatalexit = 3;
00693 break;
00694 case 'v':
00695 case 'd':
00696 short_form = ISC_FALSE;
00697 break;
00698 case 'r':
00699 lookup->recurse = ISC_FALSE;
00700 break;
00701 case 't':
00702 if (strncasecmp(isc_commandline_argument,
00703 "ixfr=", 5) == 0) {
00704 rdtype = dns_rdatatype_ixfr;
00705
00706 serial = strtoul(isc_commandline_argument + 5,
00707 NULL, 10);
00708 result = ISC_R_SUCCESS;
00709 } else {
00710 tr.base = isc_commandline_argument;
00711 tr.length = strlen(isc_commandline_argument);
00712 result = dns_rdatatype_fromtext(&rdtype,
00713 (isc_textregion_t *)&tr);
00714 }
00715
00716 if (result != ISC_R_SUCCESS) {
00717 fatalexit = 2;
00718 fatal("invalid type: %s\n",
00719 isc_commandline_argument);
00720 }
00721 if (!lookup->rdtypeset ||
00722 lookup->rdtype != dns_rdatatype_axfr)
00723 lookup->rdtype = rdtype;
00724 lookup->rdtypeset = ISC_TRUE;
00725 #ifdef WITH_IDN
00726 idnoptions = 0;
00727 #endif
00728 if (rdtype == dns_rdatatype_axfr) {
00729
00730 list_type = dns_rdatatype_any;
00731 short_form = ISC_FALSE;
00732 lookup->tcp_mode = ISC_TRUE;
00733 } else if (rdtype == dns_rdatatype_ixfr) {
00734 lookup->ixfr_serial = serial;
00735 lookup->tcp_mode = ISC_TRUE;
00736 list_type = rdtype;
00737 #ifdef WITH_IDN
00738 } else if (rdtype == dns_rdatatype_a ||
00739 rdtype == dns_rdatatype_aaaa ||
00740 rdtype == dns_rdatatype_mx) {
00741 idnoptions = IDN_ASCCHECK;
00742 list_type = rdtype;
00743 #endif
00744 } else
00745 list_type = rdtype;
00746 list_addresses = ISC_FALSE;
00747 default_lookups = ISC_FALSE;
00748 break;
00749 case 'c':
00750 tr.base = isc_commandline_argument;
00751 tr.length = strlen(isc_commandline_argument);
00752 result = dns_rdataclass_fromtext(&rdclass,
00753 (isc_textregion_t *)&tr);
00754
00755 if (result != ISC_R_SUCCESS) {
00756 fatalexit = 2;
00757 fatal("invalid class: %s\n",
00758 isc_commandline_argument);
00759 } else {
00760 lookup->rdclass = rdclass;
00761 lookup->rdclassset = ISC_TRUE;
00762 }
00763 default_lookups = ISC_FALSE;
00764 break;
00765 case 'a':
00766 if (!lookup->rdtypeset ||
00767 lookup->rdtype != dns_rdatatype_axfr)
00768 lookup->rdtype = dns_rdatatype_any;
00769 #ifdef WITH_IDN
00770 idnoptions = 0;
00771 #endif
00772 list_type = dns_rdatatype_any;
00773 list_addresses = ISC_FALSE;
00774 lookup->rdtypeset = ISC_TRUE;
00775 short_form = ISC_FALSE;
00776 default_lookups = ISC_FALSE;
00777 break;
00778 case 'i':
00779 lookup->ip6_int = ISC_TRUE;
00780 break;
00781 case 'n':
00782
00783 break;
00784 case 'm':
00785
00786 break;
00787 case 'w':
00788
00789
00790
00791
00792 timeout = INT_MAX;
00793 break;
00794 case 'W':
00795 timeout = atoi(isc_commandline_argument);
00796 if (timeout < 1)
00797 timeout = 1;
00798 break;
00799 case 'R':
00800 tries = atoi(isc_commandline_argument) + 1;
00801 if (tries < 2)
00802 tries = 2;
00803 break;
00804 case 'T':
00805 lookup->tcp_mode = ISC_TRUE;
00806 break;
00807 case 'C':
00808 debug("showing all SOAs");
00809 lookup->rdtype = dns_rdatatype_ns;
00810 lookup->rdtypeset = ISC_TRUE;
00811 lookup->rdclass = dns_rdataclass_in;
00812 lookup->rdclassset = ISC_TRUE;
00813 lookup->ns_search_only = ISC_TRUE;
00814 lookup->trace_root = ISC_TRUE;
00815 lookup->identify_previous_line = ISC_TRUE;
00816 default_lookups = ISC_FALSE;
00817 break;
00818 case 'N':
00819 debug("setting NDOTS to %s",
00820 isc_commandline_argument);
00821 ndots = atoi(isc_commandline_argument);
00822 break;
00823 case 'D':
00824
00825 break;
00826 case '4':
00827 if (have_ipv4) {
00828 isc_net_disableipv6();
00829 have_ipv6 = ISC_FALSE;
00830 } else
00831 fatal("can't find IPv4 networking");
00832 break;
00833 case '6':
00834 if (have_ipv6) {
00835 isc_net_disableipv4();
00836 have_ipv4 = ISC_FALSE;
00837 } else
00838 fatal("can't find IPv6 networking");
00839 break;
00840 case 's':
00841 lookup->servfail_stops = ISC_TRUE;
00842 break;
00843 }
00844 }
00845
00846 lookup->retries = tries;
00847
00848 if (isc_commandline_index >= argc)
00849 show_usage();
00850
00851 strlcpy(hostname, argv[isc_commandline_index], sizeof(hostname));
00852
00853 if (argc > isc_commandline_index + 1) {
00854 set_nameserver(argv[isc_commandline_index+1]);
00855 debug("server is %s", argv[isc_commandline_index+1]);
00856 listed_server = ISC_TRUE;
00857 } else
00858 check_ra = ISC_TRUE;
00859
00860 lookup->pending = ISC_FALSE;
00861 if (get_reverse(store, sizeof(store), hostname,
00862 lookup->ip6_int, ISC_TRUE) == ISC_R_SUCCESS) {
00863 strncpy(lookup->textname, store, sizeof(lookup->textname));
00864 lookup->textname[sizeof(lookup->textname)-1] = 0;
00865 lookup->rdtype = dns_rdatatype_ptr;
00866 lookup->rdtypeset = ISC_TRUE;
00867 default_lookups = ISC_FALSE;
00868 } else {
00869 strncpy(lookup->textname, hostname, sizeof(lookup->textname));
00870 lookup->textname[sizeof(lookup->textname)-1]=0;
00871 usesearch = ISC_TRUE;
00872 }
00873 lookup->new_search = ISC_TRUE;
00874 ISC_LIST_APPEND(lookup_list, lookup, link);
00875 }
00876
00877 int
00878 main(int argc, char **argv) {
00879 isc_result_t result;
00880
00881 tries = 2;
00882
00883 ISC_LIST_INIT(lookup_list);
00884 ISC_LIST_INIT(server_list);
00885 ISC_LIST_INIT(search_list);
00886
00887 fatalexit = 1;
00888 #ifdef WITH_IDN
00889 idnoptions = IDN_ASCCHECK;
00890 #endif
00891
00892 debug("main()");
00893 progname = argv[0];
00894 pre_parse_args(argc, argv);
00895 result = isc_app_start();
00896 check_result(result, "isc_app_start");
00897 setup_libs();
00898 setup_system();
00899 parse_args(ISC_FALSE, argc, argv);
00900 if (keyfile[0] != 0)
00901 setup_file_key();
00902 else if (keysecret[0] != 0)
00903 setup_text_key();
00904 result = isc_app_onrun(mctx, global_task, onrun_callback, NULL);
00905 check_result(result, "isc_app_onrun");
00906 isc_app_run();
00907 cancel_all();
00908 destroy_libs();
00909 isc_app_finish();
00910 return ((seen_error == 0) ? 0 : 1);
00911 }