dighost.c

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

C
2,368
字号
		 */		char *p = reverse;		char *end = reverse + len;		if (strict && inet_pton(AF_INET, value, &addr.type.in) != 1)			return (DNS_R_BADDOTTEDQUAD);		result = reverse_octets(value, &p, end);		if (result != ISC_R_SUCCESS)			return (result);		/* Append .in-addr.arpa. and a terminating NUL. */		result = append(".in-addr.arpa.", 15, &p, end);		if (result != ISC_R_SUCCESS)			return (result);		return (ISC_R_SUCCESS);	}}voidfatal(const char *format, ...) {	va_list args;	fprintf(stderr, "%s: ", progname);	va_start(args, format);	vfprintf(stderr, format, args);	va_end(args);	fprintf(stderr, "\n");	if (exitcode < 10)		exitcode = 10;	if (fatalexit != 0)		exitcode = fatalexit;	exit(exitcode);}voiddebug(const char *format, ...) {	va_list args;	if (debugging) {		va_start(args, format);		vfprintf(stderr, format, args);		va_end(args);		fprintf(stderr, "\n");	}}voidcheck_result(isc_result_t result, const char *msg) {	if (result != ISC_R_SUCCESS) {		fatal("%s: %s", msg, isc_result_totext(result));	}}/*% * Create a server structure, which is part of the lookup structure. * This is little more than a linked list of servers to query in hopes * of finding the answer the user is looking for */dig_server_t *make_server(const char *servname, const char *userarg) {	dig_server_t *srv;	REQUIRE(servname != NULL);	debug("make_server(%s)", servname);	srv = isc_mem_allocate(mctx, sizeof(struct dig_server));	if (srv == NULL)		fatal("memory allocation failure in %s:%d",		      __FILE__, __LINE__);	strncpy(srv->servername, servname, MXNAME);	strncpy(srv->userarg, userarg, MXNAME);	srv->servername[MXNAME-1] = 0;	srv->userarg[MXNAME-1] = 0;	ISC_LINK_INIT(srv, link);	return (srv);}static intaddr2af(int lwresaddrtype){	int af = 0;	switch (lwresaddrtype) {	case LWRES_ADDRTYPE_V4:		af = AF_INET;		break;	case LWRES_ADDRTYPE_V6:		af = AF_INET6;		break;	}	return (af);}/*% * Create a copy of the server list from the lwres configuration structure. * The dest list must have already had ISC_LIST_INIT applied. */static voidcopy_server_list(lwres_conf_t *confdata, dig_serverlist_t *dest) {	dig_server_t *newsrv;	char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];	int af;	int i;	debug("copy_server_list()");	for (i = 0; i < confdata->nsnext; i++) {		af = addr2af(confdata->nameservers[i].family);		lwres_net_ntop(af, confdata->nameservers[i].address,				   tmp, sizeof(tmp));		newsrv = make_server(tmp, tmp);		ISC_LINK_INIT(newsrv, link);		ISC_LIST_ENQUEUE(*dest, newsrv, link);	}}voidflush_server_list(void) {	dig_server_t *s, *ps;	debug("flush_server_list()");	s = ISC_LIST_HEAD(server_list);	while (s != NULL) {		ps = s;		s = ISC_LIST_NEXT(s, link);		ISC_LIST_DEQUEUE(server_list, ps, link);		isc_mem_free(mctx, ps);	}}voidset_nameserver(char *opt) {	isc_result_t result;	isc_sockaddr_t sockaddrs[DIG_MAX_ADDRESSES];	isc_netaddr_t netaddr;	int count, i;	dig_server_t *srv;	char tmp[ISC_NETADDR_FORMATSIZE];	if (opt == NULL)		return;	result = bind9_getaddresses(opt, 0, sockaddrs,				    DIG_MAX_ADDRESSES, &count); 	if (result != ISC_R_SUCCESS)		fatal("couldn't get address for '%s': %s",		      opt, isc_result_totext(result));	flush_server_list();		for (i = 0; i < count; i++) {		isc_netaddr_fromsockaddr(&netaddr, &sockaddrs[i]);		isc_netaddr_format(&netaddr, tmp, sizeof(tmp));		srv = make_server(tmp, opt);		if (srv == NULL)			fatal("memory allocation failure");		ISC_LIST_APPEND(server_list, srv, link);	}}static isc_result_tadd_nameserver(lwres_conf_t *confdata, const char *addr, int af) {	int i = confdata->nsnext;	if (confdata->nsnext >= LWRES_CONFMAXNAMESERVERS)		return (ISC_R_FAILURE);	switch (af) {	case AF_INET:		confdata->nameservers[i].family = LWRES_ADDRTYPE_V4;		confdata->nameservers[i].length = NS_INADDRSZ;		break;	case AF_INET6:		confdata->nameservers[i].family = LWRES_ADDRTYPE_V6;		confdata->nameservers[i].length = NS_IN6ADDRSZ;		break;	default:		return (ISC_R_FAILURE);	}	if (lwres_net_pton(af, addr, &confdata->nameservers[i].address) == 1) {		confdata->nsnext++;		return (ISC_R_SUCCESS);	}	return (ISC_R_FAILURE);}/*% * Produce a cloned server list.  The dest list must have already had * ISC_LIST_INIT applied. */voidclone_server_list(dig_serverlist_t src, dig_serverlist_t *dest) {	dig_server_t *srv, *newsrv;	debug("clone_server_list()");	srv = ISC_LIST_HEAD(src);	while (srv != NULL) {		newsrv = make_server(srv->servername, srv->userarg);		ISC_LINK_INIT(newsrv, link);		ISC_LIST_ENQUEUE(*dest, newsrv, link);		srv = ISC_LIST_NEXT(srv, link);	}}/*% * Create an empty lookup structure, which holds all the information needed * to get an answer to a user's question.  This structure contains two * linked lists: the server list (servers to query) and the query list * (outstanding queries which have been made to the listed servers). */dig_lookup_t *make_empty_lookup(void) {	dig_lookup_t *looknew;	debug("make_empty_lookup()");	INSIST(!free_now);	looknew = isc_mem_allocate(mctx, sizeof(struct dig_lookup));	if (looknew == NULL)		fatal("memory allocation failure in %s:%d",		       __FILE__, __LINE__);	looknew->pending = ISC_TRUE;	looknew->textname[0] = 0;	looknew->cmdline[0] = 0;	looknew->rdtype = dns_rdatatype_a;	looknew->qrdtype = dns_rdatatype_a;	looknew->rdclass = dns_rdataclass_in;	looknew->rdtypeset = ISC_FALSE;	looknew->rdclassset = ISC_FALSE;	looknew->sendspace = NULL;	looknew->sendmsg = NULL;	looknew->name = NULL;	looknew->oname = NULL;	looknew->timer = NULL;	looknew->xfr_q = NULL;	looknew->current_query = NULL;	looknew->doing_xfr = ISC_FALSE;	looknew->ixfr_serial = ISC_FALSE;	looknew->trace = ISC_FALSE;	looknew->trace_root = ISC_FALSE;	looknew->identify = ISC_FALSE;	looknew->identify_previous_line = ISC_FALSE;	looknew->ignore = ISC_FALSE;	looknew->servfail_stops = ISC_TRUE;	looknew->besteffort = ISC_TRUE;	looknew->dnssec = ISC_FALSE;#ifdef DIG_SIGCHASE	looknew->sigchase = ISC_FALSE;#if DIG_SIGCHASE_TD	looknew->do_topdown = ISC_FALSE;	looknew->trace_root_sigchase = ISC_FALSE;	looknew->rdtype_sigchaseset = ISC_FALSE;	looknew->rdtype_sigchase = dns_rdatatype_any;	looknew->qrdtype_sigchase = dns_rdatatype_any;	looknew->rdclass_sigchase = dns_rdataclass_in;	looknew->rdclass_sigchaseset = ISC_FALSE;#endif#endif	looknew->udpsize = 0;	looknew->edns = -1;	looknew->recurse = ISC_TRUE;	looknew->aaonly = ISC_FALSE;	looknew->adflag = ISC_FALSE;	looknew->cdflag = ISC_FALSE;	looknew->ns_search_only = ISC_FALSE;	looknew->origin = NULL;	looknew->tsigctx = NULL;	looknew->querysig = NULL;	looknew->retries = tries;	looknew->nsfound = 0;	looknew->tcp_mode = ISC_FALSE;	looknew->ip6_int = ISC_FALSE;	looknew->comments = ISC_TRUE;	looknew->stats = ISC_TRUE;	looknew->section_question = ISC_TRUE;	looknew->section_answer = ISC_TRUE;	looknew->section_authority = ISC_TRUE;	looknew->section_additional = ISC_TRUE;	looknew->new_search = ISC_FALSE;	looknew->done_as_is = ISC_FALSE;	looknew->need_search = ISC_FALSE;	ISC_LINK_INIT(looknew, link);	ISC_LIST_INIT(looknew->q);	ISC_LIST_INIT(looknew->my_server_list);	return (looknew);}/*% * Clone a lookup, perhaps copying the server list.  This does not clone * the query list, since it will be regenerated by the setup_lookup() * function, nor does it queue up the new lookup for processing. * Caution: If you don't clone the servers, you MUST clone the server * list seperately from somewhere else, or construct it by hand. */dig_lookup_t *clone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {	dig_lookup_t *looknew;	debug("clone_lookup()");	INSIST(!free_now);	looknew = make_empty_lookup();	INSIST(looknew != NULL);	strncpy(looknew->textname, lookold->textname, MXNAME);#if DIG_SIGCHASE_TD	strncpy(looknew->textnamesigchase, lookold->textnamesigchase, MXNAME);#endif	strncpy(looknew->cmdline, lookold->cmdline, MXNAME);	looknew->textname[MXNAME-1] = 0;	looknew->rdtype = lookold->rdtype;	looknew->qrdtype = lookold->qrdtype;	looknew->rdclass = lookold->rdclass;	looknew->rdtypeset = lookold->rdtypeset;	looknew->rdclassset = lookold->rdclassset;	looknew->doing_xfr = lookold->doing_xfr;	looknew->ixfr_serial = lookold->ixfr_serial;	looknew->trace = lookold->trace;	looknew->trace_root = lookold->trace_root;	looknew->identify = lookold->identify;	looknew->identify_previous_line = lookold->identify_previous_line;	looknew->ignore = lookold->ignore;	looknew->servfail_stops = lookold->servfail_stops;	looknew->besteffort = lookold->besteffort;	looknew->dnssec = lookold->dnssec;#ifdef DIG_SIGCHASE	looknew->sigchase = lookold->sigchase;#if DIG_SIGCHASE_TD	looknew->do_topdown = lookold->do_topdown;	looknew->trace_root_sigchase = lookold->trace_root_sigchase;	looknew->rdtype_sigchaseset = lookold->rdtype_sigchaseset;	looknew->rdtype_sigchase = lookold->rdtype_sigchase;	looknew->qrdtype_sigchase = lookold->qrdtype_sigchase;	looknew->rdclass_sigchase = lookold->rdclass_sigchase;	looknew->rdclass_sigchaseset = lookold->rdclass_sigchaseset;#endif#endif	looknew->udpsize = lookold->udpsize;	looknew->edns = lookold->edns;	looknew->recurse = lookold->recurse;	looknew->aaonly = lookold->aaonly;	looknew->adflag = lookold->adflag;	looknew->cdflag = lookold->cdflag;	looknew->ns_search_only = lookold->ns_search_only;	looknew->tcp_mode = lookold->tcp_mode;	looknew->comments = lookold->comments;	looknew->stats = lookold->stats;	looknew->section_question = lookold->section_question;	looknew->section_answer = lookold->section_answer;	looknew->section_authority = lookold->section_authority;	looknew->section_additional = lookold->section_additional;	looknew->retries = lookold->retries;	looknew->tsigctx = NULL;	looknew->need_search = lookold->need_search;	looknew->done_as_is = lookold->done_as_is;	if (servers)		clone_server_list(lookold->my_server_list,				  &looknew->my_server_list);	return (looknew);}/*% * Requeue a lookup for further processing, perhaps copying the server * list.  The new lookup structure is returned to the caller, and is * queued for processing.  If servers are not cloned in the requeue, they * must be added before allowing the current event to complete, since the * completion of the event may result in the next entry on the lookup * queue getting run. */dig_lookup_t *requeue_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {	dig_lookup_t *looknew;	debug("requeue_lookup()");	lookup_counter++;	if (lookup_counter > LOOKUP_LIMIT)		fatal("too many lookups");	looknew = clone_lookup(lookold, servers);	INSIST(looknew != NULL);	debug("before insertion, init@%p -> %p, new@%p -> %p",	      lookold, lookold->link.next, looknew, looknew->link.next);	ISC_LIST_PREPEND(lookup_list, looknew, link);	debug("after insertion, init -> %p, new = %p, new -> %p",	      lookold, looknew, looknew->link.next);	return (looknew);}static voidsetup_text_key(void) {	isc_result_t result;	dns_name_t keyname;	isc_buffer_t secretbuf;	int secretsize;	unsigned char *secretstore;	debug("setup_text_key()");	result = isc_buffer_allocate(mctx, &namebuf, MXNAME);	check_result(result, "isc_buffer_allocate");	dns_name_init(&keyname, NULL);	check_result(result, "dns_name_init");	isc_buffer_putstr(namebuf, keynametext);	secretsize = strlen(keysecret) * 3 / 4;	secretstore = isc_mem_allocate(mctx, secretsize);	if (secretstore == NULL)		fatal("memory allocation failure in %s:%d",		      __FILE__, __LINE__);	isc_buffer_init(&secretbuf, secretstore, secretsize);	result = isc_base64_decodestring(keysecret, &secretbuf);	if (result != ISC_R_SUCCESS)		goto failure;		secretsize = isc_buffer_usedlength(&secretbuf);	result = dns_name_fromtext(&keyname, namebuf,				   dns_rootname, ISC_FALSE,				   namebuf);	if (result != ISC_R_SUCCESS)		goto failure;	result = dns_tsigkey_create(&keyname, hmacname, secretstore,				    secretsize, ISC_FALSE, NULL, 0, 0, mctx,				    NULL, &key); failure:	if (result != ISC_R_SUCCESS)		printf(";; Couldn't create key %s: %s\n",		       keynametext, isc_result_totext(result));	else		dst_key_setbits(key->key, digestbits);	isc_mem_free(mctx, secretstore);	dns_name_invalidate(&keyname);	isc_buffer_free(&namebuf);}static voidsetup_file_key(void) {	isc_result_t result;	dst_key_t *dstkey = NULL;	debug("setup_file_key()");	result = dst_key_fromnamedfile(keyfile, DST_TYPE_PRIVATE | DST_TYPE_KEY,				       mctx, &dstkey);	if (result != ISC_R_SUCCESS) {		fprintf(stderr, "Couldn't read key from %s: %s\n",			keyfile, isc_result_totext(result));		goto failure;	}	switch (dst_key_alg(dstkey)) {	case DST_ALG_HMACMD5:		hmacname = DNS_TSIG_HMACMD5_NAME;		break;	case DST_ALG_HMACSHA1:		hmacname = DNS_TSIG_HMACSHA1_NAME;		break;	case DST_ALG_HMACSHA224:		hmacname = DNS_TSIG_HMACSHA224_NAME;		break;	case DST_ALG_HMACSHA256:		hmacname = DNS_TSIG_HMACSHA256_NAME;		break;	case DST_ALG_HMACSHA384:		hmacname = DNS_TSIG_HMACSHA384_NAME;		break;	case DST_ALG_HMACSHA512:		hmacname = DNS_TSIG_HMACSHA512_NAME;

⌨️ 快捷键说明

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