📄 dighost.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: dighost.c,v 1.221.2.19.2.14 2004/06/30 23:57:52 marka Exp $ *//* * Notice to programmers: Do not use this code as an example of how to * use the ISC library to perform DNS lookups. Dig and Host both operate * on the request level, since they allow fine-tuning of output and are * intended as debugging tools. As a result, they perform many of the * functions which could be better handled using the dns_resolver * functions in most applications. */#include <config.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <limits.h>#include <dns/byaddr.h>#ifdef DIG_SIGCHASE#include <dns/dnssec.h>#include <dns/ds.h>#include <dns/nsec.h>#include <isc/file.h>#include <isc/random.h>#include <ctype.h>#endif#include <dns/fixedname.h>#include <dns/message.h>#include <dns/name.h>#include <dns/rdata.h>#include <dns/rdataclass.h>#include <dns/rdatalist.h>#include <dns/rdataset.h>#include <dns/rdatastruct.h>#include <dns/rdatatype.h>#include <dns/result.h>#include <dns/tsig.h>#include <dst/dst.h>#include <isc/app.h>#include <isc/base64.h>#include <isc/entropy.h>#include <isc/lang.h>#include <isc/netaddr.h>#ifdef DIG_SIGCHASE#include <isc/netdb.h>#endif#include <isc/print.h>#include <isc/random.h>#include <isc/result.h>#include <isc/string.h>#include <isc/task.h>#include <isc/timer.h>#include <isc/types.h>#include <isc/util.h>#include <lwres/lwres.h>#include <lwres/net.h>#include <bind9/getaddresses.h>#include <dig/dig.h>#if ! defined(NS_INADDRSZ)#define NS_INADDRSZ 4#endif#if ! defined(NS_IN6ADDRSZ)#define NS_IN6ADDRSZ 16#endifstatic lwres_context_t *lwctx = NULL;static lwres_conf_t *lwconf;ISC_LIST(dig_lookup_t) lookup_list;dig_serverlist_t server_list;ISC_LIST(dig_searchlist_t) search_list;isc_boolean_t have_ipv4 = ISC_FALSE, have_ipv6 = ISC_FALSE, specified_source = ISC_FALSE, free_now = ISC_FALSE, cancel_now = ISC_FALSE, usesearch = ISC_FALSE, qr = ISC_FALSE, is_dst_up = ISC_FALSE;in_port_t port = 53;unsigned int timeout = 0;isc_mem_t *mctx = NULL;isc_taskmgr_t *taskmgr = NULL;isc_task_t *global_task = NULL;isc_timermgr_t *timermgr = NULL;isc_socketmgr_t *socketmgr = NULL;isc_sockaddr_t bind_address;isc_sockaddr_t bind_any;int sendcount = 0;int recvcount = 0;int sockcount = 0;int ndots = -1;int tries = 3;int lookup_counter = 0;/* * Exit Codes: * 0 Everything went well, including things like NXDOMAIN * 1 Usage error * 7 Got too many RR's or Names * 8 Couldn't open batch file * 9 No reply from server * 10 Internal error */int exitcode = 0;int fatalexit = 0;char keynametext[MXNAME];char keyfile[MXNAME] = "";char keysecret[MXNAME] = "";isc_buffer_t *namebuf = NULL;dns_tsigkey_t *key = NULL;isc_boolean_t validated = ISC_TRUE;isc_entropy_t *entp = NULL;isc_mempool_t *commctx = NULL;isc_boolean_t debugging = ISC_FALSE;isc_boolean_t memdebugging = ISC_FALSE;char *progname = NULL;isc_mutex_t lookup_lock;dig_lookup_t *current_lookup = NULL;#ifdef DIG_SIGCHASEisc_result_t get_trusted_key(isc_mem_t *mctx);dns_rdataset_t * sigchase_scanname(dns_rdatatype_t type, dns_rdatatype_t covers, isc_boolean_t *lookedup, dns_name_t *rdata_name);dns_rdataset_t * chase_scanname_section(dns_message_t *msg, dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, int section);isc_result_t advanced_rrsearch(dns_rdataset_t **rdataset, dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, isc_boolean_t *lookedup);isc_result_t sigchase_verify_sig_key(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t* dnsseckey, dns_rdataset_t *sigrdataset, isc_mem_t *mctx);isc_result_t sigchase_verify_sig(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdataset_t *keyrdataset, dns_rdataset_t *sigrdataset, isc_mem_t *mctx);isc_result_t sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset, dns_rdataset_t *dsrdataset, isc_mem_t *mctx);void sigchase(dns_message_t *msg);void print_rdata(dns_rdata_t *rdata, isc_mem_t *mctx);void print_rdataset(dns_name_t *name, dns_rdataset_t *rdataset, isc_mem_t *mctx);void dup_name(dns_name_t *source, dns_name_t* target, isc_mem_t *mctx);void dump_database(void);void dump_database_section(dns_message_t *msg, int section);dns_rdataset_t * search_type(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers);isc_result_t contains_trusted_key(dns_name_t *name, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, isc_mem_t *mctx);void print_type(dns_rdatatype_t type);isc_result_t prove_nx_domain(dns_message_t * msg, dns_name_t * name, dns_name_t * rdata_name, dns_rdataset_t ** rdataset, dns_rdataset_t ** sigrdataset);isc_result_t prove_nx_type(dns_message_t * msg, dns_name_t *name, dns_rdataset_t *nsec, dns_rdataclass_t class, dns_rdatatype_t type, dns_name_t * rdata_name, dns_rdataset_t ** rdataset, dns_rdataset_t ** sigrdataset);isc_result_t prove_nx(dns_message_t * msg, dns_name_t * name, dns_rdataclass_t class, dns_rdatatype_t type, dns_name_t * rdata_name, dns_rdataset_t ** rdataset, dns_rdataset_t ** sigrdataset);static void nameFromString(const char *str, dns_name_t *p_ret);int inf_name(dns_name_t * name1, dns_name_t * name2);isc_result_t opentmpkey(isc_mem_t *mctx, const char *file, char **tempp, FILE **fp);isc_result_t removetmpkey(isc_mem_t *mctx, const char *file);void clean_trustedkey(void );void insert_trustedkey(dst_key_t * key);#if DIG_SIGCHASE_BUisc_result_t getneededrr(dns_message_t *msg);void sigchase_bottom_up(dns_message_t *msg);void sigchase_bu(dns_message_t *msg);#endif#if DIG_SIGCHASE_TDisc_result_t initialization(dns_name_t *name);isc_result_t prepare_lookup(dns_name_t *name);isc_result_t grandfather_pb_test(dns_name_t * zone_name, dns_rdataset_t *sigrdataset);isc_result_t child_of_zone(dns_name_t *name, dns_name_t *zone_name, dns_name_t *child_name);void sigchase_td(dns_message_t *msg);#endifchar trustedkey[MXNAME] = "";dns_rdataset_t * chase_rdataset = NULL;dns_rdataset_t * chase_sigrdataset = NULL;dns_rdataset_t * chase_dsrdataset = NULL;dns_rdataset_t * chase_sigdsrdataset = NULL;dns_rdataset_t * chase_keyrdataset = NULL;dns_rdataset_t * chase_sigkeyrdataset = NULL;dns_rdataset_t * chase_nsrdataset = NULL;dns_name_t chase_name; /* the query name */#if DIG_SIGCHASE_TD/* * the current name is the parent name when we follow delegation */dns_name_t chase_current_name; /* * the child name is used for delegation (NS DS responses in AUTHORITY section) */dns_name_t chase_authority_name;#endif#if DIG_SIGCHASE_BUdns_name_t chase_signame;#endifisc_boolean_t chase_siglookedup = ISC_FALSE;isc_boolean_t chase_keylookedup = ISC_FALSE;isc_boolean_t chase_sigkeylookedup = ISC_FALSE;isc_boolean_t chase_dslookedup = ISC_FALSE;isc_boolean_t chase_sigdslookedup = ISC_FALSE;#if DIG_SIGCHASE_TDisc_boolean_t chase_nslookedup = ISC_FALSE;isc_boolean_t chase_lookedup = ISC_FALSE;isc_boolean_t delegation_follow = ISC_FALSE;isc_boolean_t grandfather_pb = ISC_FALSE;isc_boolean_t have_response = ISC_FALSE;isc_boolean_t have_delegation_ns = ISC_FALSE;dns_message_t * error_message = NULL;#endifisc_boolean_t dsvalidating = ISC_FALSE;isc_boolean_t chase_name_dup = ISC_FALSE;ISC_LIST(dig_message_t) chase_message_list;ISC_LIST(dig_message_t) chase_message_list2;#define MAX_TRUSTED_KEY 5typedef struct struct_trusted_key_list { dst_key_t * key[MAX_TRUSTED_KEY]; int nb_tk;} struct_tk_list;struct_tk_list tk_list = { {NULL, NULL, NULL, NULL, NULL}, 0};#endif/* * Apply and clear locks at the event level in global task. * Can I get rid of these using shutdown events? XXX */#define LOCK_LOOKUP {\ debug("lock_lookup %s:%d", __FILE__, __LINE__);\ check_result(isc_mutex_lock((&lookup_lock)), "isc_mutex_lock");\ debug("success");\}#define UNLOCK_LOOKUP {\ debug("unlock_lookup %s:%d", __FILE__, __LINE__);\ check_result(isc_mutex_unlock((&lookup_lock)),\ "isc_mutex_unlock");\}static voidcancel_lookup(dig_lookup_t *lookup);static voidrecv_done(isc_task_t *task, isc_event_t *event);static voidconnect_timeout(isc_task_t *task, isc_event_t *event);static voidlaunch_next_query(dig_query_t *query, isc_boolean_t include_question);static void *mem_alloc(void *arg, size_t size) { return (isc_mem_get(arg, size));}static voidmem_free(void *arg, void *mem, size_t size) { isc_mem_put(arg, mem, size);}char *next_token(char **stringp, const char *delim) { char *res; do { res = strsep(stringp, delim); if (res == NULL) break; } while (*res == '\0'); return (res);}static intcount_dots(char *string) { char *s; int i = 0; s = string; while (*s != '\0') { if (*s == '.') i++; s++; } return (i);}static voidhex_dump(isc_buffer_t *b) { unsigned int len; isc_region_t r; isc_buffer_usedregion(b, &r); printf("%d bytes\n", r.length); for (len = 0; len < r.length; len++) { printf("%02x ", r.base[len]); if (len % 16 == 15) printf("\n"); } if (len % 16 != 0) printf("\n");}/* * Append 'len' bytes of 'text' at '*p', failing with * ISC_R_NOSPACE if that would advance p past 'end'. */static isc_result_tappend(const char *text, int len, char **p, char *end) { if (len > end - *p) return (ISC_R_NOSPACE); memcpy(*p, text, len); *p += len; return (ISC_R_SUCCESS);}static isc_result_treverse_octets(const char *in, char **p, char *end) { char *dot = strchr(in, '.'); int len; if (dot != NULL) { isc_result_t result; result = reverse_octets(dot + 1, p, end); if (result != ISC_R_SUCCESS) return (result); result = append(".", 1, p, end); if (result != ISC_R_SUCCESS) return (result); len = dot - in; } else { len = strlen(in); } return (append(in, len, p, end));}isc_result_tget_reverse(char *reverse, size_t len, char *value, isc_boolean_t ip6_int, isc_boolean_t strict){ int r; isc_result_t result; isc_netaddr_t addr; addr.family = AF_INET6; r = inet_pton(AF_INET6, value, &addr.type.in6); if (r > 0) { /* This is a valid IPv6 address. */ dns_fixedname_t fname; dns_name_t *name; unsigned int options = 0; if (ip6_int) options |= DNS_BYADDROPT_IPV6INT; dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); result = dns_byaddr_createptrname2(&addr, options, name); if (result != ISC_R_SUCCESS) return (result); dns_name_format(name, reverse, len); return (ISC_R_SUCCESS); } else { /* * Not a valid IPv6 address. Assume IPv4. * If 'strict' is not set, construct the * in-addr.arpa name by blindly reversing * octets whether or not they look like integers, * so that this can be used for RFC2317 names * and such. */ 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -