host.c

来自「非常好的dns解析软件」· C语言 代码 · 共 834 行 · 第 1/2 页

C
834
字号
/* * Copyright (C) 2004-2006  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: host.c,v 1.94.18.14 2006/05/23 04:40:42 marka Exp $ *//*! \file */#include <config.h>#include <limits.h>#include <isc/app.h>#include <isc/commandline.h>#include <isc/netaddr.h>#include <isc/print.h>#include <isc/string.h>#include <isc/util.h>#include <isc/task.h>#include <isc/stdlib.h>#include <dns/byaddr.h>#include <dns/fixedname.h>#include <dns/message.h>#include <dns/name.h>#include <dns/rdata.h>#include <dns/rdataclass.h>#include <dns/rdataset.h>#include <dns/rdatatype.h>#include <dns/rdatastruct.h>#include <dig/dig.h>static isc_boolean_t short_form = ISC_TRUE, listed_server = ISC_FALSE;static isc_boolean_t default_lookups = ISC_TRUE;static int seen_error = -1;static isc_boolean_t list_addresses = ISC_TRUE;static dns_rdatatype_t list_type = dns_rdatatype_a;static isc_boolean_t printed_server = 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"};struct rtype {	unsigned int type;	const char *text;};struct rtype rtypes[] = {	{ 1, 	"has address" },	{ 2, 	"name server" },	{ 5, 	"is an alias for" },	{ 11,	"has well known services" },	{ 12,	"domain name pointer" },	{ 13,	"host information" },	{ 15,	"mail is handled by" },	{ 16,	"descriptive text" },	{ 19,	"x25 address" },	{ 20,	"ISDN address" },	{ 24,	"has signature" },	{ 25,	"has key" },	{ 28,	"has IPv6 address" },	{ 29,	"location" },	{ 0, NULL }};static voidshow_usage(void) {	fputs("Usage: host [-aCdlriTwv] [-c class] [-N ndots] [-t type] [-W time]\n""            [-R number] [-m flag] hostname [server]\n""       -a is equivalent to -v -t ANY\n""       -c specifies query class for non-IN data\n""       -C compares SOA records on authoritative nameservers\n""       -d is equivalent to -v\n""       -l lists all hosts in a domain, using AXFR\n""       -i IP6.INT reverse lookups\n""       -N changes the number of dots allowed before root lookup is done\n""       -r disables recursive processing\n""       -R specifies number of retries for UDP packets\n""       -s a SERVFAIL response should stop query\n""       -t specifies the query type\n""       -T enables TCP/IP mode\n""       -v enables verbose output\n""       -w specifies to wait forever for a reply\n""       -W specifies how long to wait for a reply\n""       -4 use IPv4 query transport only\n""       -6 use IPv6 query transport only\n""       -m set memory debugging flag (trace|record|usage)\n", stderr);	exit(1);}voiddighost_shutdown(void) {	isc_app_shutdown();}voidreceived(int bytes, isc_sockaddr_t *from, dig_query_t *query) {	isc_time_t now;	int diff;	if (!short_form) {		char fromtext[ISC_SOCKADDR_FORMATSIZE];		isc_sockaddr_format(from, fromtext, sizeof(fromtext));		TIME_NOW(&now);		diff = (int) isc_time_microdiff(&now, &query->time_sent);		printf("Received %u bytes from %s in %d ms\n",		       bytes, fromtext, diff/1000);	}}voidtrying(char *frm, dig_lookup_t *lookup) {	UNUSED(lookup);	if (!short_form)		printf("Trying \"%s\"\n", frm);}static voidsay_message(dns_name_t *name, const char *msg, dns_rdata_t *rdata,	    dig_query_t *query){	isc_buffer_t *b = NULL;	char namestr[DNS_NAME_FORMATSIZE];	isc_region_t r;	isc_result_t result;	unsigned int bufsize = BUFSIZ;	dns_name_format(name, namestr, sizeof(namestr)); retry:	result = isc_buffer_allocate(mctx, &b, bufsize);	check_result(result, "isc_buffer_allocate");	result = dns_rdata_totext(rdata, NULL, b);	if (result == ISC_R_NOSPACE) {		isc_buffer_free(&b);		bufsize *= 2;		goto retry;	}	check_result(result, "dns_rdata_totext");	isc_buffer_usedregion(b, &r);	if (query->lookup->identify_previous_line) {		printf("Nameserver %s:\n\t",			query->servname);	}	printf("%s %s %.*s", namestr,	       msg, (int)r.length, (char *)r.base);	if (query->lookup->identify) {		printf(" on server %s", query->servname);	}	printf("\n");	isc_buffer_free(&b);}#ifdef DIG_SIGCHASE/* Just for compatibility : not use in host program */isc_result_tprintrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset,	      isc_buffer_t *target){  UNUSED(owner_name);  UNUSED(rdataset);  UNUSED(target);  return(ISC_FALSE);}#endifstatic isc_result_tprintsection(dns_message_t *msg, dns_section_t sectionid,	     const char *section_name, isc_boolean_t headers,	     dig_query_t *query){	dns_name_t *name, *print_name;	dns_rdataset_t *rdataset;	dns_rdata_t rdata = DNS_RDATA_INIT;	isc_buffer_t target;	isc_result_t result, loopresult;	isc_region_t r;	dns_name_t empty_name;	char t[4096];	isc_boolean_t first;	isc_boolean_t no_rdata;	if (sectionid == DNS_SECTION_QUESTION)		no_rdata = ISC_TRUE;	else		no_rdata = ISC_FALSE;	if (headers)		printf(";; %s SECTION:\n", section_name);	dns_name_init(&empty_name, NULL);	result = dns_message_firstname(msg, sectionid);	if (result == ISC_R_NOMORE)		return (ISC_R_SUCCESS);	else if (result != ISC_R_SUCCESS)		return (result);	for (;;) {		name = NULL;		dns_message_currentname(msg, sectionid, &name);		isc_buffer_init(&target, t, sizeof(t));		first = ISC_TRUE;		print_name = name;		for (rdataset = ISC_LIST_HEAD(name->list);		     rdataset != NULL;		     rdataset = ISC_LIST_NEXT(rdataset, link)) {			if (query->lookup->rdtype == dns_rdatatype_axfr &&			    !((!list_addresses &&			       (list_type == dns_rdatatype_any ||			        rdataset->type == list_type)) ||			      (list_addresses &&			       (rdataset->type == dns_rdatatype_a ||			        rdataset->type == dns_rdatatype_aaaa ||				rdataset->type == dns_rdatatype_ns ||				rdataset->type == dns_rdatatype_ptr))))				continue;			if (!short_form) {				result = dns_rdataset_totext(rdataset,							     print_name,							     ISC_FALSE,							     no_rdata,							     &target);				if (result != ISC_R_SUCCESS)					return (result);#ifdef USEINITALWS				if (first) {					print_name = &empty_name;					first = ISC_FALSE;				}#else				UNUSED(first); /* Shut up compiler. */#endif			} else {				loopresult = dns_rdataset_first(rdataset);				while (loopresult == ISC_R_SUCCESS) {					struct rtype *t;					const char *rtt;					char typebuf[DNS_RDATATYPE_FORMATSIZE];					char typebuf2[DNS_RDATATYPE_FORMATSIZE						     + 20];					dns_rdataset_current(rdataset, &rdata);					for (t = rtypes; t->text != NULL; t++) {						if (t->type == rdata.type) {							rtt = t->text;							goto found;						}					}					dns_rdatatype_format(rdata.type,							     typebuf,							     sizeof(typebuf));					snprintf(typebuf2, sizeof(typebuf2),						 "has %s record", typebuf);					rtt = typebuf2;				found:					say_message(print_name, rtt,						    &rdata, query);					dns_rdata_reset(&rdata);					loopresult =						dns_rdataset_next(rdataset);				}			}		}		if (!short_form) {			isc_buffer_usedregion(&target, &r);			if (no_rdata)				printf(";%.*s", (int)r.length,				       (char *)r.base);			else				printf("%.*s", (int)r.length, (char *)r.base);		}		result = dns_message_nextname(msg, sectionid);		if (result == ISC_R_NOMORE)			break;		else if (result != ISC_R_SUCCESS)			return (result);	}	return (ISC_R_SUCCESS);}static isc_result_tprintrdata(dns_message_t *msg, dns_rdataset_t *rdataset, dns_name_t *owner,	   const char *set_name, isc_boolean_t headers){	isc_buffer_t target;	isc_result_t result;	isc_region_t r;	char t[4096];	UNUSED(msg);	if (headers)		printf(";; %s SECTION:\n", set_name);	isc_buffer_init(&target, t, sizeof(t));	result = dns_rdataset_totext(rdataset, owner, ISC_FALSE, ISC_FALSE,				     &target);	if (result != ISC_R_SUCCESS)		return (result);	isc_buffer_usedregion(&target, &r);	printf("%.*s", (int)r.length, (char *)r.base);	return (ISC_R_SUCCESS);}static voidchase_cnamechain(dns_message_t *msg, dns_name_t *qname) {	isc_result_t result;	dns_rdataset_t *rdataset;	dns_rdata_cname_t cname;	dns_rdata_t rdata = DNS_RDATA_INIT;	unsigned int i = msg->counts[DNS_SECTION_ANSWER]; 	while (i-- > 0) {		rdataset = NULL;		result = dns_message_findname(msg, DNS_SECTION_ANSWER, qname,					      dns_rdatatype_cname, 0, NULL,					      &rdataset);		if (result != ISC_R_SUCCESS)			return;		result = dns_rdataset_first(rdataset);		check_result(result, "dns_rdataset_first");		dns_rdata_reset(&rdata);		dns_rdataset_current(rdataset, &rdata);		result = dns_rdata_tostruct(&rdata, &cname, NULL);		check_result(result, "dns_rdata_tostruct");		dns_name_copy(&cname.cname, qname, NULL);		dns_rdata_freestruct(&cname);	}}isc_result_tprintmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) {	isc_boolean_t did_flag = ISC_FALSE;	dns_rdataset_t *opt, *tsig = NULL;	dns_name_t *tsigname;	isc_result_t result = ISC_R_SUCCESS;	int force_error;	UNUSED(headers);	/*	 * We get called multiple times.	 * Preserve any existing error status.	 */	force_error = (seen_error == 1) ? 1 : 0;	seen_error = 1;	if (listed_server && !printed_server) {		char sockstr[ISC_SOCKADDR_FORMATSIZE];		printf("Using domain server:\n");		printf("Name: %s\n", query->userarg);		isc_sockaddr_format(&query->sockaddr, sockstr,				    sizeof(sockstr));		printf("Address: %s\n", sockstr);		printf("Aliases: \n\n");		printed_server = ISC_TRUE;	}	if (msg->rcode != 0) {		char namestr[DNS_NAME_FORMATSIZE];		dns_name_format(query->lookup->name, namestr, sizeof(namestr));		printf("Host %s not found: %d(%s)\n", namestr,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?