dig.c revision 960c8888f620585d068e63ac9b9d1c59182bffc2
a7038d1a0513c8e804937ebc95fc9cb3a46c04f5Mark Andrews * Copyright (C) 2000 Internet Software Consortium.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Permission to use, copy, modify, and distribute this software for any
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * purpose with or without fee is hereby granted, provided that the above
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * copyright notice and this permission notice appear in all copies.
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
15a44745412679c30a6d022733925af70a38b715David Lawrence * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
15a44745412679c30a6d022733925af70a38b715David Lawrence * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
15a44745412679c30a6d022733925af70a38b715David Lawrence * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15a44745412679c30a6d022733925af70a38b715David Lawrence * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15a44745412679c30a6d022733925af70a38b715David Lawrence * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
15a44745412679c30a6d022733925af70a38b715David Lawrence * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
471e0563c7965c556c759775882cd3448dae78eaMark Andrews/* $Id: dig.c,v 1.43 2000/06/07 00:13:54 mws Exp $ */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrenceextern ISC_LIST(dig_searchlist_t) search_list;
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrewsextern isc_boolean_t have_ipv6, show_details, specified_source,
9ac7076ebad044afb15e9e2687e3696868778538Mark Andrewsextern unsigned int timeout;
0b056755b2f423ba5f6adac8f7851d78f7d11437David Lawrenceisc_boolean_t short_form = ISC_FALSE, printcmd = ISC_TRUE;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence trace = ISC_FALSE, ns_search_only = ISC_FALSE,
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence comments = ISC_TRUE, section_question = ISC_TRUE,
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence section_answer = ISC_TRUE, section_authority = ISC_TRUE,
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence section_additional = ISC_TRUE, recurse = ISC_TRUE,
0b056755b2f423ba5f6adac8f7851d78f7d11437David Lawrence defname = ISC_TRUE, aaonly = ISC_FALSE, tcpmode = ISC_FALSE;
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencestatic const char *opcodetext[] = {
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafssonstatic const char *rcodetext[] = {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence "RESERVED11",
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence "RESERVED12",
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence "RESERVED13",
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence "RESERVED14",
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence "RESERVED15",
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence"Usage: dig [@global-server] [domain] [q-type] [q-class] {q-opt}\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" {global-d-opt} host [@local-server] {local-d-opt}\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" [ host [@local-server] {local-d-opt} [...]]\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence"Where: domain are in the Domain Name System\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" q-class is one of (in,chaos,...) [default: in]\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" q-type is one of (a,any,mx,ns,soa,hinfo,axfr,txt,...) [default:a]\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" (Use ixfr=version for type ixfr)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" q-opt is one of:\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" -x dot-notation (shortcut for in-addr lookups)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" -f filename (batch mode)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" -p port (specify port number)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" -t type (specify query type)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" -c class (specify query class)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" -y name:key (specify named base64 tsig key)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" d-opt is of the form +keyword[=value], where keyword is:\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]vc (TCP mode)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]tcp (TCP mode, alternate syntax)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +time=### (Set query timeout) [5]\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +tries=### (Set number of UDP attempts) [3]\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +domain=### (Set default domainname)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +bufsize=### (Set EDNS0 Max UDP packet size)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]search (Set whether to use searchlist)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]defname (Set whether to use default domaon)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]recursive (Recursive mode)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]aaonly (Set AA flag in query)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]details (Show details of all requests)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +twiddle (Intentionally form bad requests)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +ndots=### (Set NDOTS value)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]comments (Control display of comment lines)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]question (Control display of question)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]answer (Control display of answer)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]authority (Control display of authority)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]additional (Control display of additional)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]short (Disable everything except short\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" form of answer)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +qr (Print question before sending)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" Additional d-opts subject to removal before release:\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]nssearch (Search all authorative nameservers)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]identify (ID responders in short answers)\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" Available but not yet completed:\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence" +[no]trace (Trace delegation down from root)\n"
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson" global d-opts and servers (before host name) affect all queries.\n"
76c8294c81fb48b1da6e1fc5b83322a4cedb8e58Andreas Gustafsson" local d-opts and servers (after host name) affect only that lookup.\n"
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrencereceived(int bytes, int frmsize, char *frm, dig_query_t *query) {
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews diff = isc_time_microdiff(&now, &query->time_sent);
bddfe77128b0f16af263ff149db40f0d885f43d0Mark Andrews printf(";; Query time: %ld msec\n", (long int)diff/1000);
23cb957a81a51a9656917ea98d0ae56b7abdcaccMark Andrews "be validated");
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews } else if (query->lookup->identify && !short_form) {
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews diff = isc_time_microdiff(&now, &query->time_sent);
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrews printf(";; Received %u bytes from %.*s in %d ms\n",
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrewstrying(int frmsize, char *frm, dig_lookup_t *lookup) {
2002be4f65776451676df6ee21a2e28f52bcad6dMark Andrewssay_message(dns_rdata_t *rdata, dig_query_t *query, isc_buffer_t *buf) {
ffe74cc719aa0f10c38fbc1f2f3ea7db0960cb8fMark Andrews if (query->lookup->trace || query->lookup->ns_search_only) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews result = dns_rdatatype_totext(rdata->type, buf);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews diff = isc_time_microdiff(&now, &query->time_sent);
8d3e74b1683f714a484bbcf73249e8ee470e36d7Mark Andrews snprintf (store, 19, " in %d ms.", (int)diff/1000);
613991eef6bb79b9703382aff26cddd0281da915Bob Halleyshort_answer(dns_message_t *msg, dns_messagetextflag_t flags,
5d83b561ad7eb84885a8ec63dee4c51b335f067aBrian Wellington char t[4096];
87ecd67dae468cf5c9bae213c6fa321449b2ebc2Andreas Gustafsson result = dns_message_firstname(msg, DNS_SECTION_ANSWER);
54c26ab21c61c6d6b1e484bb88dc3ac263845d17Mark Andrews dns_message_currentname(msg, DNS_SECTION_ANSWER, &name);
21825a8d005ccc2dfaf12889bf9eef3413555277Brian Wellington rdataset = ISC_LIST_NEXT(rdataset, link)) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson result = dns_message_nextname(msg, DNS_SECTION_ANSWER);
94a537e6ab3069f8d34e12e5ea722250be2b89c8Michael Graffprintmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson debug ("printmessage(%s)",headers?"headers":"noheaders");
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson * Exitcode 9 means we timed out, but if we're printing a message,
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson * we much have recovered. Go ahead and reset it to code 0, and
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson * call this a success.
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson result = isc_buffer_allocate(mctx, &buf, OUTPUTBUF);
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson check_result (result, "isc_buffer_allocate");
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson if (query->lookup->comments && !short_form) {
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson printf(";; ->>HEADER<<- opcode: %s, status: %s, "
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson opcodetext[msg->opcode], rcodetext[msg->rcode],
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) {
5d2026ea7b5ae43bbd69d98b747f75ba3290bef1Mark Andrews "AUTHORITY: %u, ADDITIONAL: %u\n",
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrews "dns_message_pseudosectiontotext");
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (query->lookup->section_question && headers) {
389c749a5ee18f1c0d6278ae49f2aae5d5f0d2dcMark Andrews check_result(result, "dns_message_sectiontotext");
29c818c7d40fc8898b062903ec703851328a4deaMark Andrews check_result(result, "dns_message_sectiontotext");
cabaeca9ae5b98c80586b91e89cf552e17a75a9bBrian Wellington result = short_answer(msg, flags, buf, query);
29c818c7d40fc8898b062903ec703851328a4deaMark Andrews check_result(result, "dns_message_sectiontotext");
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews check_result(result, "dns_message_sectiontotext");
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* Only print the signature on the first record */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews "dns_message_pseudosectiontotext");
d981ca645597116d227a48bf37cc5edc061c854dBob Halley "dns_message_pseudosectiontotext");
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews if (headers && query->lookup->comments && !short_form)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews printf ("%.*s",(int)isc_buffer_usedlength(buf),
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews while (i < argc) {
19d365e4448f1782611280b020987988b7ac3210Mark Andrews * Reorder an argument list so that server names all come at the end.
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * This is a bit of a hack, to allow batch-mode processing to properly
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * handle the server options.
f1cae4bcb7ee3060d893f5ab3ba55c1820bf3e4aBrian Wellington * We're not using isc_commandline_parse() here since the command line
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * syntax of dig is quite a bit different from that which can be described
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * that routine. There is a portability issue here.
6bebabb376b93e7d12f53a253b197a3fc0e0b001Andreas Gustafssonparse_args(isc_boolean_t is_batchfile, int argc, char **argv) {
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews * The semantics for parsing the args is a bit complex; if
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews * we don't have a host yet, make the arg apply globally,
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * otherwise make it apply to the latest host. This is
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * a bit different than the previous versions, but should
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence * form a consistent user interface.
d981ca645597116d227a48bf37cc5edc061c854dBob Halley sizeof(struct dig_server));
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff strncpy(srv->servername, &rv[0][1], MXNAME-1);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff } else if (strncmp(rv[0], "+domain=", 8) == 0) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* Global option always */
7c0378745269fe49a05904935afc42b85528f53aDavid Lawrence /* Global option always */
7e4cda9965e2edf2ec43c57967eec8eff7061ab0Andreas Gustafsson } else if (strncmp(rv[0], "+nodefn", 7) == 0) {
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington /* Global option always */
942d1a339b1fe617f7d17d66cb5fccce798d15aeBrian Wellington } else if (strncmp(rv[0], "+tries=", 7) == 0) {
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington } else if (strncmp(rv[0], "+buf=", 5) == 0) {
f16495732753175e4a9fc144323a12fdcc29b561Brian Wellington } else if (strncmp(rv[0], "+bufsize=", 9) == 0) {
7e4cda9965e2edf2ec43c57967eec8eff7061ab0Andreas Gustafsson } else if (strncmp(rv[0], "+ndots=", 7) == 0) {
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington /* Global option always */
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington } else if (strncmp(rv[0], "+rec", 4) == 0) {
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington } else if (strncmp(rv[0], "+norec", 6) == 0) {
93ed317bb43658ed48ee7439f7a36bb9bcf80c94Brian Wellington } else if (strncmp(rv[0], "+aa", 3) == 0) {
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington } else if (strncmp(rv[0], "+noaa", 5) == 0) {
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington } else if (strncmp(rv[0], "+tr", 3) == 0) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff } else if (strncmp(rv[0], "+nodet", 6) == 0) {
8abddcd3f24476b945419659e7cb73bcb970886bDavid Lawrence } else if (strncmp(rv[0], "+nocom", 6) == 0) {
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington } else if (strncmp(rv[0], "+que", 4) == 0) {
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson } else if (strncmp(rv[0], "+aut", 4) == 0) {
0c8649cea98afc061dd2938fd315df53b8fc35caAndreas Gustafsson } else if (strncmp(rv[0], "+all", 4) == 0) {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews } else if (strncmp(rv[0], "+twiddle", 6) == 0) {
9916239908343b3eb17f0578de4c3cd6a313d85fMark Andrews *XXXMWS Only works for ipv4 now.
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley * Can't use inet_pton here, since we allow
0513f89e68f82f9ec54e7af9c979a7c43babbe31Bob Halley * partial addresses.
471e0563c7965c556c759775882cd3448dae78eaMark Andrews n = sscanf(rv[1], "%d.%d.%d.%d", &adrs[0], &adrs[1],
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence sizeof(struct dig_lookup));
242bba8991b030b7764f0bdca3922d75c34ea51eAndreas Gustafsson for (i = n - 1; i >= 0; i--) {
242bba8991b030b7764f0bdca3922d75c34ea51eAndreas Gustafsson strncat(lookup->textname, batchline, MXNAME);
d56fa53141ef99613a998796b0858d6840db19f3Brian Wellington strncat(lookup->textname, "in-addr.arpa.", MXNAME);
242bba8991b030b7764f0bdca3922d75c34ea51eAndreas Gustafsson debug("Looking up %s", lookup->textname);
242bba8991b030b7764f0bdca3922d75c34ea51eAndreas Gustafsson lookup->trace = ISC_TF(trace || ns_search_only);
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson lookup->section_authority = section_authority;
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson lookup->section_additional = section_additional;
242bba8991b030b7764f0bdca3922d75c34ea51eAndreas Gustafsson ISC_LIST_APPEND(lookup_list, lookup, link);
3ddd92da6651bc72aa79a04195ad389d86fd1a66Andreas Gustafsson sizeof(struct dig_lookup));
fa460c223a69449eaac67ddb6abafe74f5e1ff02Michael Graff lookup->trace = ISC_TF(trace || ns_search_only);
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington lookup->section_question = section_question;
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington lookup->section_additional = section_additional;
ebfcb6cf66283096ebda1503b6cc042ce86b6bedBrian Wellington bargv[bargc] = strtok(batchline, " \t\r\n");
fa460c223a69449eaac67ddb6abafe74f5e1ff02Michael Graff while ((bargv[bargc] != NULL) && (bargc < 14 )) {
fa460c223a69449eaac67ddb6abafe74f5e1ff02Michael Graff * This silliness (instead of ``bargv[0] = "dig";'')
a98551ef592e9be6008e0141ceeb32efd586c5efMark Andrews * dances around the const string issue. If in
fa460c223a69449eaac67ddb6abafe74f5e1ff02Michael Graff * the future the 2nd argument to strncpy() is made
fa460c223a69449eaac67ddb6abafe74f5e1ff02Michael Graff * longer than three characters, don't forget to resize
fa460c223a69449eaac67ddb6abafe74f5e1ff02Michael Graff * bargv0 to accommodate it.
fa460c223a69449eaac67ddb6abafe74f5e1ff02Michael Graff lookup = isc_mem_allocate(mctx, sizeof(struct dig_lookup));
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson lookup->trace = ISC_TF(trace || ns_search_only);
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson lookup->section_question = section_question;
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson lookup->section_authority = section_authority;
d3a86da2e8f09e2c3f55721aae537b9cacc7e537Andreas Gustafsson lookup->section_additional = section_additional;
9be230cfca126bea6b666f506a230ffcdfba60dbMark Andrews for (i = 0 ; i<p; i++);