diff --git a/doc/tshark.pod b/doc/tshark.pod index ec4f743070..22ef5d7b6c 100644 --- a/doc/tshark.pod +++ b/doc/tshark.pod @@ -433,7 +433,7 @@ Print the version and options and exits. =item -H Einput hosts fileE Read a list of entries from a "hosts" file, which will then be written -to a capture file. Implies B<-W n>. +to a capture file. Implies B<-W n>. Can be called multiple times. The "hosts" file format is documented at L. diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c index 76c0ea4ec9..4d36231c08 100644 --- a/epan/addr_resolv.c +++ b/epan/addr_resolv.c @@ -277,6 +277,7 @@ static gboolean new_resolved_objects = FALSE; static struct addrinfo *addrinfo_list = NULL; /* IPv4 and IPv6 */ static struct addrinfo *addrinfo_list_last = NULL; +static GPtrArray* extra_hosts_files = NULL; static hashether_t *add_eth_name(const guint8 *addr, const gchar *name); static void add_serv_port_cb(const guint32 port); @@ -2009,7 +2010,7 @@ ipxnet_addr_lookup(const gchar *name, gboolean *success) } /* ipxnet_addr_lookup */ -gboolean +static gboolean read_hosts_file (const char *hostspath) { FILE *hf; @@ -2075,6 +2076,36 @@ read_hosts_file (const char *hostspath) return TRUE; } /* read_hosts_file */ +gboolean +add_hosts_file (const char *hosts_file) +{ + FILE *hf; + gboolean found = FALSE; + guint i; + + if (!hosts_file) + return FALSE; + + if ((hf = ws_fopen(hosts_file, "r")) == NULL) + return FALSE; + + if (!extra_hosts_files) + extra_hosts_files = g_ptr_array_new(); + + for (i = 0; i < extra_hosts_files->len; i++) { + if (strcmp(hosts_file, (const char *) g_ptr_array_index(extra_hosts_files, i)) == 0) + found = TRUE; + } + + if (!found) { + g_ptr_array_add(extra_hosts_files, g_strdup(hosts_file)); + if (addrinfo_list) { + return read_hosts_file (hosts_file); + } + } + return TRUE; +} + gboolean add_ip_name_from_string (const char *addr, const char *name) { @@ -2425,6 +2456,7 @@ void host_name_lookup_init(void) { char *hostspath; struct addrinfo *ai; + guint i; #ifdef HAVE_GNU_ADNS #ifdef _WIN32 @@ -2522,6 +2554,12 @@ host_name_lookup_init(void) { #endif /* HAVE_GNU_ADNS */ #endif /* HAVE_C_ARES */ + if(extra_hosts_files && !gbl_resolv_flags.load_hosts_file_from_profile_only){ + for (i = 0; i < extra_hosts_files->len; i++) { + read_hosts_file((const char *) g_ptr_array_index(extra_hosts_files, i)); + } + } + subnet_name_lookup_init(); } diff --git a/epan/addr_resolv.h b/epan/addr_resolv.h index 11657c0448..0f51d104f9 100644 --- a/epan/addr_resolv.h +++ b/epan/addr_resolv.h @@ -214,8 +214,16 @@ extern void add_ipv4_name(const guint addr, const gchar *name); /* adds a hostname/IPv6 in the hash table */ extern void add_ipv6_name(const struct e_in6_addr *addr, const gchar *name); -/* read a "hosts" file and add its entries to the IPv4 & IPv6 hash tables */ -extern gboolean read_hosts_file (const char *hostspath); +/** Add an additional "hosts" file for IPv4 and IPv6 name resolution. + * + * The file can be added before host_name_lookup_init() is called and + * will be re-read each time host_name_lookup_init() is called. + * + * @param hostspath Absolute path to the hosts file. + * + * @return TRUE if the hosts file can be read. + */ +extern gboolean add_hosts_file (const char *hosts_file); /* adds a hostname in the hash table */ extern gboolean add_ip_name_from_string (const char *addr, const char *name); diff --git a/epan/libwireshark.def b/epan/libwireshark.def index d2be0ef463..d300b01c83 100644 --- a/epan/libwireshark.def +++ b/epan/libwireshark.def @@ -11,6 +11,7 @@ EXPORTS abs_time_secs_to_str abs_time_to_str +add_hosts_file add_new_data_source add_ip_name_from_string add_ipv4_name @@ -905,7 +906,6 @@ range_copy range_empty range_foreach ranges_are_equal -read_hosts_file read_keytab_file read_keytab_file_from_preferences read_prefs diff --git a/tshark.c b/tshark.c index 951fcb7804..b25badcf5a 100644 --- a/tshark.c +++ b/tshark.c @@ -889,7 +889,6 @@ main(int argc, char *argv[]) volatile int out_file_type = WTAP_FILE_PCAP; #endif volatile gboolean out_file_name_res = FALSE; - gchar *hosts_file = NULL; gchar *volatile cf_name = NULL; gchar *rfilter = NULL; #ifdef HAVE_PCAP_OPEN_DEAD @@ -1277,7 +1276,11 @@ main(int argc, char *argv[]) } break; case 'H': /* Read address to name mappings from a hosts file */ - hosts_file = optarg; + if (! add_hosts_file(optarg)) + { + cmdarg_err("Can't read host entries from \"%s\"", optarg); + return 1; + } out_file_name_res = TRUE; break; @@ -1842,16 +1845,6 @@ main(int argc, char *argv[]) g_assert_not_reached(); } - /* Read in the hosts file after cf_open() (which calls init_dissection() - * which resets the name database). - */ - if (hosts_file) { - if (! read_hosts_file(hosts_file)) { - cmdarg_err("Can't read host entries from \"%s\"", hosts_file); - return 1; - } - } - /* Process the packets in the file */ TRY { #ifdef HAVE_LIBPCAP