📄 dig.c
字号:
/* * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* $Id: dig.c,v 1.157.2.13.2.20 2004/06/23 04:19:40 marka Exp $ */#include <config.h>#include <stdlib.h>#include <time.h>#include <ctype.h>#include <isc/app.h>#include <isc/netaddr.h>#include <isc/parseint.h>#include <isc/print.h>#include <isc/string.h>#include <isc/util.h>#include <isc/task.h>#include <dns/byaddr.h>#include <dns/fixedname.h>#include <dns/masterdump.h>#include <dns/message.h>#include <dns/name.h>#include <dns/rdata.h>#include <dns/rdataset.h>#include <dns/rdatatype.h>#include <dns/rdataclass.h>#include <dns/result.h>#include <dig/dig.h>extern ISC_LIST(dig_lookup_t) lookup_list;extern dig_serverlist_t server_list;extern ISC_LIST(dig_searchlist_t) search_list;#define ADD_STRING(b, s) { \ if (strlen(s) >= isc_buffer_availablelength(b)) \ return (ISC_R_NOSPACE); \ else \ isc_buffer_putstr(b, s); \}extern isc_boolean_t have_ipv4, have_ipv6, specified_source, usesearch, qr;extern in_port_t port;extern unsigned int timeout;extern isc_mem_t *mctx;extern dns_messageid_t id;extern int sendcount;extern int ndots;extern int lookup_counter;extern int exitcode;extern isc_sockaddr_t bind_address;extern char keynametext[MXNAME];extern char keyfile[MXNAME];extern char keysecret[MXNAME];#ifdef DIG_SIGCHASEextern char trustedkey[MXNAME];#endifextern dns_tsigkey_t *key;extern isc_boolean_t validated;extern isc_taskmgr_t *taskmgr;extern isc_task_t *global_task;extern isc_boolean_t free_now;dig_lookup_t *default_lookup = NULL;extern isc_boolean_t debugging, memdebugging;static char *batchname = NULL;static FILE *batchfp = NULL;static char *argv0;static char domainopt[DNS_NAME_MAXTEXT];static isc_boolean_t short_form = ISC_FALSE, printcmd = ISC_TRUE, ip6_int = ISC_FALSE, plusquest = ISC_FALSE, pluscomm = ISC_FALSE, multiline = ISC_FALSE, nottl = ISC_FALSE, noclass = ISC_FALSE;static const char *opcodetext[] = { "QUERY", "IQUERY", "STATUS", "RESERVED3", "NOTIFY", "UPDATE", "RESERVED6", "RESERVED7", "RESERVED8", "RESERVED9", "RESERVED10", "RESERVED11", "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15"};static const char *rcodetext[] = { "NOERROR", "FORMERR", "SERVFAIL", "NXDOMAIN", "NOTIMP", "REFUSED", "YXDOMAIN", "YXRRSET", "NXRRSET", "NOTAUTH", "NOTZONE", "RESERVED11", "RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15", "BADVERS"};extern char *progname;static voidprint_usage(FILE *fp) { fputs("Usage: dig [@global-server] [domain] [q-type] [q-class] {q-opt}\n"" {global-d-opt} host [@local-server] {local-d-opt}\n"" [ host [@local-server] {local-d-opt} [...]]\n", fp);}static voidusage(void) { print_usage(stderr); fputs("\nUse \"dig -h\" (or \"dig -h | more\") " "for complete list of options\n", stderr); exit(1);}static voidversion(void) { fputs("DiG " VERSION "\n", stderr);}static voidhelp(void) { print_usage(stdout); fputs("Where: domain is in the Domain Name System\n"" q-class is one of (in,hs,ch,...) [default: in]\n"" q-type is one of (a,any,mx,ns,soa,hinfo,axfr,txt,...) [default:a]\n"" (Use ixfr=version for type ixfr)\n"" q-opt is one of:\n"" -x dot-notation (shortcut for in-addr lookups)\n"" -i (IP6.INT reverse IPv6 lookups)\n"" -f filename (batch mode)\n"" -b address[#port] (bind to source address/port)\n"" -p port (specify port number)\n"" -t type (specify query type)\n"" -c class (specify query class)\n"" -k keyfile (specify tsig key file)\n"" -y name:key (specify named base64 tsig key)\n"" -4 (use IPv4 query transport only)\n"" -6 (use IPv6 query transport only)\n"" d-opt is of the form +keyword[=value], where keyword is:\n"" +[no]vc (TCP mode)\n"" +[no]tcp (TCP mode, alternate syntax)\n"" +time=### (Set query timeout) [5]\n"" +tries=### (Set number of UDP attempts) [3]\n"" +retry=### (Set number of UDP retries) [2]\n"" +domain=### (Set default domainname)\n"" +bufsize=### (Set EDNS0 Max UDP packet size)\n"" +ndots=### (Set NDOTS value)\n"" +[no]search (Set whether to use searchlist)\n"" +[no]defname (Ditto)\n"" +[no]recurse (Recursive mode)\n"" +[no]ignore (Don't revert to TCP for TC responses.)""\n"" +[no]fail (Don't try next server on SERVFAIL)\n"" +[no]besteffort (Try to parse even illegal messages)\n"" +[no]aaonly (Set AA flag in query (+[no]aaflag))\n"" +[no]adflag (Set AD flag in query)\n"" +[no]cdflag (Set CD flag in query)\n"" +[no]cl (Control display of class in records)\n"" +[no]cmd (Control display of command line)\n"" +[no]comments (Control display of comment lines)\n"" +[no]question (Control display of question)\n"" +[no]answer (Control display of answer)\n"" +[no]authority (Control display of authority)\n"" +[no]additional (Control display of additional)\n"" +[no]stats (Control display of statistics)\n"" +[no]short (Disable everything except short\n"" form of answer)\n"" +[no]ttlid (Control display of ttls in records)\n"" +[no]all (Set or clear all display flags)\n"" +[no]qr (Print question before sending)\n"" +[no]nssearch (Search all authoritative nameservers)\n"" +[no]identify (ID responders in short answers)\n"" +[no]trace (Trace delegation down from root)\n"" +[no]dnssec (Request DNSSEC records)\n"#ifdef DIG_SIGCHASE" +[no]sigchase (Chase DNSSEC signatures)\n"" +trusted-key=#### (Trusted Key when chasing DNSSEC sigs)\n"#if DIG_SIGCHASE_TD" +[no]topdown (Do DNSSEC validation top down mode)\n"#endif#endif" +[no]multiline (Print records in an expanded format)\n"" global d-opts and servers (before host name) affect all queries.\n"" local d-opts and servers (after host name) affect only that lookup.\n"" -h (print help and exit)\n"" -v (print version and exit)\n", stdout);}/* * Callback from dighost.c to print the received message. */voidreceived(int bytes, isc_sockaddr_t *from, dig_query_t *query) { isc_uint64_t diff; isc_time_t now; time_t tnow; char fromtext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(from, fromtext, sizeof(fromtext)); TIME_NOW(&now); if (query->lookup->stats && !short_form) { diff = isc_time_microdiff(&now, &query->time_sent); printf(";; Query time: %ld msec\n", (long int)diff/1000); printf(";; SERVER: %s(%s)\n", fromtext, query->servname); time(&tnow); printf(";; WHEN: %s", ctime(&tnow)); if (query->lookup->doing_xfr) { printf(";; XFR size: %u records (messages %u)\n", query->rr_count, query->msg_count); } else { printf(";; MSG SIZE rcvd: %d\n", bytes); } if (key != NULL) { if (!validated) puts(";; WARNING -- Some TSIG could not " "be validated"); } if ((key == NULL) && (keysecret[0] != 0)) { puts(";; WARNING -- TSIG key was not used."); } puts(""); } else if (query->lookup->identify && !short_form) { diff = isc_time_microdiff(&now, &query->time_sent); printf(";; Received %u bytes from %s(%s) in %d ms\n\n", bytes, fromtext, query->servname, (int)diff/1000); }}/* * Callback from dighost.c to print that it is trying a server. * Not used in dig. * XXX print_trying */voidtrying(char *frm, dig_lookup_t *lookup) { UNUSED(frm); UNUSED(lookup);}/* * Internal print routine used to print short form replies. */static isc_result_tsay_message(dns_rdata_t *rdata, dig_query_t *query, isc_buffer_t *buf) { isc_result_t result; isc_uint64_t diff; isc_time_t now; char store[sizeof("12345678901234567890")]; if (query->lookup->trace || query->lookup->ns_search_only) { result = dns_rdatatype_totext(rdata->type, buf); if (result != ISC_R_SUCCESS) return (result); ADD_STRING(buf, " "); } result = dns_rdata_totext(rdata, NULL, buf); check_result(result, "dns_rdata_totext"); if (query->lookup->identify) { TIME_NOW(&now); diff = isc_time_microdiff(&now, &query->time_sent); ADD_STRING(buf, " from server "); ADD_STRING(buf, query->servname); snprintf(store, 19, " in %d ms.", (int)diff/1000); ADD_STRING(buf, store); } ADD_STRING(buf, "\n"); return (ISC_R_SUCCESS);}/* * short_form message print handler. Calls above say_message() */static isc_result_tshort_answer(dns_message_t *msg, dns_messagetextflag_t flags, isc_buffer_t *buf, dig_query_t *query){ dns_name_t *name; dns_rdataset_t *rdataset; isc_buffer_t target; isc_result_t result, loopresult; dns_name_t empty_name; char t[4096]; dns_rdata_t rdata = DNS_RDATA_INIT; UNUSED(flags); dns_name_init(&empty_name, NULL); result = dns_message_firstname(msg, DNS_SECTION_ANSWER); if (result == ISC_R_NOMORE) return (ISC_R_SUCCESS); else if (result != ISC_R_SUCCESS) return (result); for (;;) { name = NULL; dns_message_currentname(msg, DNS_SECTION_ANSWER, &name); isc_buffer_init(&target, t, sizeof(t)); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { loopresult = dns_rdataset_first(rdataset); while (loopresult == ISC_R_SUCCESS) { dns_rdataset_current(rdataset, &rdata); result = say_message(&rdata, query, buf); check_result(result, "say_message"); loopresult = dns_rdataset_next(rdataset); dns_rdata_reset(&rdata); } } result = dns_message_nextname(msg, DNS_SECTION_ANSWER); if (result == ISC_R_NOMORE) break; else if (result != ISC_R_SUCCESS) return (result); } return (ISC_R_SUCCESS);}#ifdef DIG_SIGCHASEisc_result_tprintrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset, isc_buffer_t *target){ isc_result_t result; dns_master_style_t *style = NULL; unsigned int styleflags = 0; if (rdataset == NULL || owner_name == NULL || target == NULL) return(ISC_FALSE); styleflags |= DNS_STYLEFLAG_REL_OWNER; if (nottl) styleflags |= DNS_STYLEFLAG_NO_TTL; if (noclass) styleflags |= DNS_STYLEFLAG_NO_CLASS; if (multiline) { styleflags |= DNS_STYLEFLAG_OMIT_OWNER; styleflags |= DNS_STYLEFLAG_OMIT_CLASS; styleflags |= DNS_STYLEFLAG_REL_DATA; styleflags |= DNS_STYLEFLAG_OMIT_TTL; styleflags |= DNS_STYLEFLAG_TTL; styleflags |= DNS_STYLEFLAG_MULTILINE; styleflags |= DNS_STYLEFLAG_COMMENT; } if (multiline || (nottl && noclass)) result = dns_master_stylecreate(&style, styleflags, 24, 24, 24, 32, 80, 8, mctx); else if (nottl || noclass) result = dns_master_stylecreate(&style, styleflags, 24, 24, 32, 40, 80, 8, mctx); else result = dns_master_stylecreate(&style, styleflags, 24, 32, 40, 48, 80, 8, mctx); check_result(result, "dns_master_stylecreate"); result = dns_master_rdatasettotext(owner_name, rdataset, style, target); if (style != NULL) dns_master_styledestroy(&style, mctx); return(result);}#endif/* * Callback from dighost.c to print the reply from a server */isc_result_tprintmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) { isc_result_t result; dns_messagetextflag_t flags; isc_buffer_t *buf = NULL; unsigned int len = OUTPUTBUF; dns_master_style_t *style = NULL; unsigned int styleflags = 0; styleflags |= DNS_STYLEFLAG_REL_OWNER; if (nottl) styleflags |= DNS_STYLEFLAG_NO_TTL; if (noclass) styleflags |= DNS_STYLEFLAG_NO_CLASS; if (multiline) { styleflags |= DNS_STYLEFLAG_OMIT_OWNER; styleflags |= DNS_STYLEFLAG_OMIT_CLASS; styleflags |= DNS_STYLEFLAG_REL_DATA; styleflags |= DNS_STYLEFLAG_OMIT_TTL; styleflags |= DNS_STYLEFLAG_TTL; styleflags |= DNS_STYLEFLAG_MULTILINE; styleflags |= DNS_STYLEFLAG_COMMENT; } if (multiline || (nottl && noclass)) result = dns_master_stylecreate(&style, styleflags, 24, 24, 24, 32, 80, 8, mctx); else if (nottl || noclass) result = dns_master_stylecreate(&style, styleflags, 24, 24, 32, 40, 80, 8, mctx); else result = dns_master_stylecreate(&style, styleflags, 24, 32, 40, 48, 80, 8, mctx); check_result(result, "dns_master_stylecreate"); if (query->lookup->cmdline[0] != 0) { if (!short_form) fputs(query->lookup->cmdline, stdout); query->lookup->cmdline[0]=0; } debug("printmessage(%s %s %s)", headers ? "headers" : "noheaders", query->lookup->comments ? "comments" : "nocomments", short_form ? "short_form" : "long_form"); flags = 0; if (!headers) { flags |= DNS_MESSAGETEXTFLAG_NOHEADERS; flags |= DNS_MESSAGETEXTFLAG_NOCOMMENTS; } if (!query->lookup->comments) flags |= DNS_MESSAGETEXTFLAG_NOCOMMENTS; result = ISC_R_SUCCESS; result = isc_buffer_allocate(mctx, &buf, len); check_result(result, "isc_buffer_allocate"); if (query->lookup->comments && !short_form) { if (query->lookup->cmdline[0] != 0) printf("; %s\n", query->lookup->cmdline); if (msg == query->lookup->sendmsg) printf(";; Sending:\n"); else printf(";; Got answer:\n"); if (headers) { printf(";; ->>HEADER<<- opcode: %s, status: %s, " "id: %u\n", opcodetext[msg->opcode], rcodetext[msg->rcode], msg->id); printf(";; flags:"); if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) printf(" qr"); if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0) printf(" aa"); if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) printf(" tc"); if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0) printf(" rd"); if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0) printf(" ra"); if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0) printf(" ad"); if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0) printf(" cd"); printf("; QUERY: %u, ANSWER: %u, " "AUTHORITY: %u, ADDITIONAL: %u\n", msg->counts[DNS_SECTION_QUESTION], msg->counts[DNS_SECTION_ANSWER], msg->counts[DNS_SECTION_AUTHORITY], msg->counts[DNS_SECTION_ADDITIONAL]); } }repopulate_buffer: if (query->lookup->comments && headers && !short_form) { result = dns_message_pseudosectiontotext(msg, DNS_PSEUDOSECTION_OPT, style, flags, buf); if (result == ISC_R_NOSPACE) {buftoosmall: len += OUTPUTBUF; isc_buffer_free(&buf); result = isc_buffer_allocate(mctx, &buf, len); if (result == ISC_R_SUCCESS) goto repopulate_buffer; else goto cleanup; } check_result(result, "dns_message_pseudosectiontotext"); } if (query->lookup->section_question && headers) { if (!short_form) { result = dns_message_sectiontotext(msg, DNS_SECTION_QUESTION, style, flags, buf); if (result == ISC_R_NOSPACE) goto buftoosmall; check_result(result, "dns_message_sectiontotext"); } } if (query->lookup->section_answer) { if (!short_form) { result = dns_message_sectiontotext(msg, DNS_SECTION_ANSWER, style, flags, buf); if (result == ISC_R_NOSPACE) goto buftoosmall; check_result(result, "dns_message_sectiontotext"); } else { result = short_answer(msg, flags, buf, query); if (result == ISC_R_NOSPACE) goto buftoosmall; check_result(result, "short_answer"); } } if (query->lookup->section_authority) { if (!short_form) { result = dns_message_sectiontotext(msg, DNS_SECTION_AUTHORITY, style, flags, buf); if (result == ISC_R_NOSPACE) goto buftoosmall; check_result(result, "dns_message_sectiontotext");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -