diff options
author | Anders Broman <anders.broman@ericsson.com> | 2013-08-18 19:02:48 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2013-08-18 19:02:48 +0000 |
commit | ccb96fd73a17b294afe9f0511f708239fd787939 (patch) | |
tree | 0c489ddbc5b6579f92fbf410a13604aa68f8c1e1 /epan/addr_resolv.c | |
parent | 2cbe77751607fc3541333c83b59b84ba9af4d893 (diff) | |
download | wireshark-ccb96fd73a17b294afe9f0511f708239fd787939.tar.gz wireshark-ccb96fd73a17b294afe9f0511f708239fd787939.tar.bz2 wireshark-ccb96fd73a17b294afe9f0511f708239fd787939.zip |
Use g_hastable() for IPv6 name reslution.
svn path=/trunk/; revision=51415
Diffstat (limited to 'epan/addr_resolv.c')
-rw-r--r-- | epan/addr_resolv.c | 141 |
1 files changed, 80 insertions, 61 deletions
diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c index 2c1f44b8ad..b7382aa752 100644 --- a/epan/addr_resolv.c +++ b/epan/addr_resolv.c @@ -141,8 +141,6 @@ #define HASHETHSIZE 2048 #define HASHHOSTSIZE 2048 #define HASHIPXNETSIZE 256 -#define HASHMANUFSIZE 256 -#define HASHPORTSIZE 256 #define SUBNETLENGTHSIZE 32 /*1-32 inc.*/ /* g_int64_hash() and g_int64_equal() first appear in GLib 2.22, make a local copy here */ @@ -219,11 +217,8 @@ typedef struct sub_net_hashipv4 { gchar name[MAXNAMELEN]; } sub_net_hashipv4_t; -/* hash table used for IPv6 lookup */ - -#define HASH_IPV6_ADDRESS(addr) \ - ((((addr).bytes[14] << 8)|((addr).bytes[15])) & (HASHHOSTSIZE - 1)) +#if 0 typedef struct hashipv6 { struct e_in6_addr addr; gboolean is_dummy_entry; /* name is IPv6 address in colon format */ @@ -232,7 +227,7 @@ typedef struct hashipv6 { gchar ip6[MAX_IP6_STR_LEN]; /* XX */ gchar name[MAXNAMELEN]; } hashipv6_t; - +#endif /* Array of entries of subnets of different lengths */ typedef struct { gsize mask_length; /*1-32*/ @@ -240,10 +235,6 @@ typedef struct { sub_net_hashipv4_t** subnet_addresses; /* Hash table of subnet addresses */ } subnet_length_entry_t; -/* hash table used for TCP/UDP/SCTP port lookup */ - -#define HASH_PORT(port) ((port) & (HASHPORTSIZE - 1)) - #if 0 typedef struct serv_port { @@ -295,9 +286,8 @@ typedef struct _ipxnet char name[MAXNAMELEN]; } ipxnet_t; -static hashipv6_t *ipv6_table[HASHHOSTSIZE]; - static GHashTable *ipv4_hash_table = NULL; +static GHashTable *ipv6_hash_table = NULL; static gchar *cb_service; static port_type cb_proto = PT_NONE; @@ -322,6 +312,42 @@ 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); + +/* http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx#existing + * One-at-a-Time hash + */ +static guint32 +ipv6_oat_hash(gconstpointer key) +{ + int len = 16; + const unsigned char *p = (const unsigned char *)key; + guint32 h = 0; + int i; + + for ( i = 0; i < len; i++ ) { + h += p[i]; + h += ( h << 10 ); + h ^= ( h >> 6 ); + } + + h += ( h << 3 ); + h ^= ( h >> 11 ); + h += ( h << 15 ); + + return h; +} + +static gboolean +ipv6_equal(gconstpointer v1, gconstpointer v2) +{ + + if( memcmp(v1, v2, sizeof (struct e_in6_addr)) == 0 ) { + return TRUE; + } + + return FALSE; +} + /* * Flag controlling what names to resolve. */ @@ -956,9 +982,8 @@ try_resolv: static hashipv6_t * new_ipv6(const struct e_in6_addr *addr) { - hashipv6_t *tp = se_new(hashipv6_t); + hashipv6_t *tp = g_new(hashipv6_t,1); tp->addr = *addr; - tp->next = NULL; tp->resolve = FALSE; tp->is_dummy_entry = FALSE; ip6_to_str_buf(addr, tp->ip6); @@ -969,7 +994,6 @@ new_ipv6(const struct e_in6_addr *addr) static hashipv6_t * host_lookup6(const struct e_in6_addr *addr, gboolean *found) { - int hash_idx; hashipv6_t * volatile tp; #ifdef INET6 #ifdef HAVE_C_ARES @@ -980,30 +1004,25 @@ host_lookup6(const struct e_in6_addr *addr, gboolean *found) *found = TRUE; - hash_idx = HASH_IPV6_ADDRESS(*addr); - - tp = ipv6_table[hash_idx]; + tp = (hashipv6_t *)g_hash_table_lookup(ipv6_hash_table, addr); + if(tp == NULL){ + struct e_in6_addr *addr_key; - if( tp == NULL ) { - tp = ipv6_table[hash_idx] = new_ipv6(addr); - } else { - while(1) { - if( memcmp(&tp->addr, addr, sizeof (struct e_in6_addr)) == 0 ) { - if (tp->is_dummy_entry && !tp->resolve) - break; - if (tp->is_dummy_entry) - *found = FALSE; - return tp; - } - if (tp->next == NULL) { - tp->next = new_ipv6(addr); - tp = tp->next; - break; - } - tp = tp->next; + addr_key = g_new(struct e_in6_addr,1); + tp = new_ipv6(addr); + memcpy(addr_key, addr, 16); + g_hash_table_insert(ipv6_hash_table, addr_key, tp); + }else{ + if (tp->is_dummy_entry && !tp->resolve){ + goto try_resolv; } + if (tp->is_dummy_entry){ + *found = FALSE; + } + return tp; } +try_resolv: if (gbl_resolv_flags.network_name && gbl_resolv_flags.use_external_net_name_resolver) { tp->resolve = TRUE; @@ -2731,7 +2750,6 @@ add_ipv4_name(const guint addr, const gchar *name) void add_ipv6_name(const struct e_in6_addr *addrp, const gchar *name) { - int hash_idx; hashipv6_t *tp; struct addrinfo *ai; struct sockaddr_in6 *sa6; @@ -2743,31 +2761,21 @@ add_ipv6_name(const struct e_in6_addr *addrp, const gchar *name) if (name[0] == '\0') return; - hash_idx = HASH_IPV6_ADDRESS(*addrp); - - tp = ipv6_table[hash_idx]; + tp = (hashipv6_t *)g_hash_table_lookup(ipv6_hash_table, addrp); + if(tp){ + g_strlcpy(tp->name, name, MAXNAMELEN); + tp->resolve = TRUE; + }else{ + struct e_in6_addr *addr_key; - if( tp == NULL ) { - tp = ipv6_table[hash_idx] = new_ipv6(addrp); - } else { - while(1) { - if (memcmp(&tp->addr, addrp, sizeof (struct e_in6_addr)) == 0) { - /* address already known */ - if (!tp->is_dummy_entry) { - return; - } else { - /* replace this dummy entry with the new one */ - break; - } - } - if (tp->next == NULL) { - tp->next = new_ipv6(addrp); - tp = tp->next; - break; - } - tp = tp->next; - } + addr_key = g_new(struct e_in6_addr,1); + tp = new_ipv6(addrp); + memcpy(addr_key, addrp, 16); + g_strlcpy(tp->name, name, MAXNAMELEN); + tp->resolve = TRUE; + g_hash_table_insert(ipv6_hash_table, addr_key, tp); } + g_strlcpy(tp->name, name, MAXNAMELEN); tp->resolve = TRUE; new_resolved_objects = TRUE; @@ -2810,6 +2818,9 @@ host_name_lookup_init(void) g_assert(ipv4_hash_table == NULL); ipv4_hash_table = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); + g_assert(ipv6_hash_table == NULL); + ipv6_hash_table = g_hash_table_new_full(ipv6_oat_hash, ipv6_equal, g_free, g_free); + if (!addrinfo_list) { ai = se_new0(struct addrinfo); addrinfo_list = addrinfo_list_last = ai; @@ -2914,7 +2925,10 @@ host_name_lookup_cleanup(void) g_hash_table_destroy(ipv4_hash_table); ipv4_hash_table = NULL; } - memset(ipv6_table, 0, sizeof(ipv6_table)); + if(ipv6_hash_table){ + g_hash_table_destroy(ipv6_hash_table); + ipv6_hash_table = NULL; + } memset(subnet_length_entries, 0, sizeof(subnet_length_entries)); @@ -3471,6 +3485,11 @@ get_ipv4_hash_table(void) return ipv4_hash_table; } +GHashTable * +get_ipv6_hash_table(void) +{ + return ipv6_hash_table; +} /* Initialize all the address resolution subsystems in this file */ void addr_resolv_init(void) |