Make get_manuf_name return a const string.

Model get_manuf_name after get_ether_name so that a string (either name resolved or colon-separated bytes) is always stored in a hash table.  This will make name resolution of addresses perform a little better because it doesn't have to work about the wmem_allocator.

Change-Id: I80f465ae0845290255a659ab63310ac3cc35506e
Reviewed-on: https://code.wireshark.org/review/7075
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Michael Mann 2015-02-11 22:16:01 -05:00 committed by Anders Broman
parent 297ef07b9b
commit 797ea88aef
6 changed files with 92 additions and 51 deletions

View File

@ -643,6 +643,7 @@ libwireshark.so.0 libwireshark0 #MINVER#
get_hash_ether_status@Base 1.99.3
get_hash_ether_hexaddr@Base 1.99.3
get_hash_ether_resolved_name@Base 1.99.3
get_hash_manuf_resolved_name@Base 1.99.3
get_host_ipaddr6@Base 1.9.1
get_host_ipaddr@Base 1.9.1
get_hostlist_filter@Base 1.99.0

View File

@ -198,8 +198,15 @@ typedef struct hashether {
char hexaddr[6*3];
char resolved_name[MAXNAMELEN];
} hashether_t;
/* internal ethernet type */
typedef struct hashmanuf {
guint status; /* (See above) */
guint8 addr[3];
char hexaddr[3*3];
char resolved_name[MAXNAMELEN];
} hashmanuf_t;
/* internal ethernet type */
typedef struct _ether
{
guint8 addr[6];
@ -207,7 +214,6 @@ typedef struct _ether
} ether_t;
/* internal ipxnet type */
typedef struct _ipxnet
{
guint addr;
@ -1258,12 +1264,39 @@ get_ethbyaddr(const guint8 *addr)
} /* get_ethbyaddr */
static hashmanuf_t *manuf_hash_new_entry(const guint8 *addr, char* name)
{
int *manuf_key;
hashmanuf_t *manuf_value;
char *endp;
/* manuf needs only the 3 most significant octets of the ethernet address */
manuf_key = (int *)g_new(int, 1);
*manuf_key = (int)((addr[0] << 16) + (addr[1] << 8) + addr[2]);
manuf_value = g_new(hashmanuf_t, 1);
memcpy(manuf_value->addr, addr, 3);
manuf_value->status = (name != NULL) ? HASHETHER_STATUS_RESOLVED_NAME : HASHETHER_STATUS_UNRESOLVED;
if (name != NULL) {
g_strlcpy(manuf_value->resolved_name, name, MAXNAMELEN);
manuf_value->status = HASHETHER_STATUS_RESOLVED_NAME;
}
else {
manuf_value->status = HASHETHER_STATUS_UNRESOLVED;
manuf_value->resolved_name[0] = '\0';
}
/* Values returned by bytes_to_hexstr_punct() are *not* null-terminated */
endp = bytes_to_hexstr_punct(manuf_value->hexaddr, addr, sizeof(manuf_value->hexaddr), ':');
*endp = '\0';
g_hash_table_insert(manuf_hashtable, manuf_key, manuf_value);
return manuf_value;
}
static void
add_manuf_name(const guint8 *addr, unsigned int mask, gchar *name)
{
guint8 *wka_key;
int *manuf_key;
/*
* XXX - can we use Standard Annotation Language annotations to
@ -1280,12 +1313,7 @@ add_manuf_name(const guint8 *addr, unsigned int mask, gchar *name)
if (mask == 0) {
/* This is a manufacturer ID; add it to the manufacturer ID hash table */
/* manuf needs only the 3 most significant octets of the ethernet address */
manuf_key = (int *)g_new(int, 1);
*manuf_key = (int)((addr[0] << 16) + (addr[1] << 8) + addr[2]);
g_hash_table_insert(manuf_hashtable, manuf_key, g_strdup(name));
manuf_hash_new_entry(addr, name);
return;
} /* mask == 0 */
@ -1299,12 +1327,12 @@ add_manuf_name(const guint8 *addr, unsigned int mask, gchar *name)
} /* add_manuf_name */
static gchar *
static hashmanuf_t *
manuf_name_lookup(const guint8 *addr)
{
gint32 manuf_key = 0;
guint8 oct;
gchar *name;
hashmanuf_t *manuf_value;
/* manuf needs only the 3 most significant octets of the ethernet address */
manuf_key = addr[0];
@ -1317,9 +1345,9 @@ manuf_name_lookup(const guint8 *addr)
/* first try to find a "perfect match" */
name = (gchar *)g_hash_table_lookup(manuf_hashtable, &manuf_key);
if(name != NULL){
return name;
manuf_value = (hashmanuf_t*)g_hash_table_lookup(manuf_hashtable, &manuf_key);
if (manuf_value != NULL) {
return manuf_value;
}
/* Mask out the broadcast/multicast flag but not the locally
@ -1329,13 +1357,14 @@ manuf_name_lookup(const guint8 *addr)
* 0x02 locally administered bit */
if((manuf_key & 0x00010000) != 0){
manuf_key &= 0x00FEFFFF;
name = (gchar *)g_hash_table_lookup(manuf_hashtable, &manuf_key);
if(name != NULL){
return name;
manuf_value = (hashmanuf_t*)g_hash_table_lookup(manuf_hashtable, &manuf_key);
if (manuf_value != NULL) {
return manuf_value;
}
}
return NULL;
/* Add the address as a hex string */
return manuf_hash_new_entry(addr, NULL);
} /* manuf_name_lookup */
@ -1459,6 +1488,7 @@ eth_name_lookup_cleanup(void)
static hashether_t *
eth_addr_resolve(hashether_t *tp) {
ether_t *eth;
hashmanuf_t *manuf_value;
const guint8 *addr = tp->addr;
if ( (eth = get_ethbyaddr(addr)) != NULL) {
@ -1515,9 +1545,10 @@ eth_addr_resolve(hashether_t *tp) {
}
/* Now try looking in the manufacturer table. */
if ((name = manuf_name_lookup(addr)) != NULL) {
manuf_value = manuf_name_lookup(addr);
if ((manuf_value != NULL) && (manuf_value->status != HASHETHER_STATUS_UNRESOLVED)) {
g_snprintf(tp->resolved_name, MAXNAMELEN, "%s_%02x:%02x:%02x",
name, addr[3], addr[4], addr[5]);
manuf_value->resolved_name, addr[3], addr[4], addr[5]);
tp->status = HASHETHER_STATUS_RESOLVED_DUMMY;
return tp;
}
@ -3066,10 +3097,10 @@ get_ipxnet_addr(const gchar *name, gboolean *known)
} /* get_ipxnet_addr */
gchar *
get_manuf_name(wmem_allocator_t *allocator, const guint8 *addr)
const gchar *
get_manuf_name(const guint8 *addr)
{
gchar *cur;
hashmanuf_t *manuf_value;
int manuf_key;
guint8 oct;
@ -3082,12 +3113,11 @@ get_manuf_name(wmem_allocator_t *allocator, const guint8 *addr)
oct = addr[2];
manuf_key = manuf_key | oct;
if (!gbl_resolv_flags.mac_name || ((cur = (gchar *)g_hash_table_lookup(manuf_hashtable, &manuf_key)) == NULL)) {
cur=wmem_strdup_printf(allocator, "%02x:%02x:%02x", addr[0], addr[1], addr[2]);
return cur;
}
manuf_value = manuf_name_lookup(addr);
if (gbl_resolv_flags.mac_name && manuf_value->status != HASHETHER_STATUS_UNRESOLVED)
return manuf_value->resolved_name;
return wmem_strdup(allocator, cur);
return manuf_value->hexaddr;
} /* get_manuf_name */
@ -3099,19 +3129,19 @@ uint_get_manuf_name(const guint oid)
addr[0] = (oid >> 16) & 0xFF;
addr[1] = (oid >> 8) & 0xFF;
addr[2] = (oid >> 0) & 0xFF;
return get_manuf_name(wmem_packet_scope(), addr);
return get_manuf_name(addr);
}
const gchar *
tvb_get_manuf_name(tvbuff_t *tvb, gint offset)
{
return get_manuf_name(wmem_packet_scope(), tvb_get_ptr(tvb, offset, 3));
return get_manuf_name(tvb_get_ptr(tvb, offset, 3));
}
const gchar *
get_manuf_name_if_known(const guint8 *addr)
{
gchar *cur;
hashmanuf_t *manuf_value;
int manuf_key;
guint8 oct;
@ -3124,24 +3154,26 @@ get_manuf_name_if_known(const guint8 *addr)
oct = addr[2];
manuf_key = manuf_key | oct;
if ((cur = (gchar *)g_hash_table_lookup(manuf_hashtable, &manuf_key)) == NULL) {
manuf_value = (hashmanuf_t *)g_hash_table_lookup(manuf_hashtable, &manuf_key);
if ((manuf_value == NULL) || (manuf_value->status != HASHETHER_STATUS_UNRESOLVED)) {
return NULL;
}
return cur;
return manuf_value->resolved_name;
} /* get_manuf_name_if_known */
const gchar *
uint_get_manuf_name_if_known(const guint manuf_key)
{
gchar *cur;
hashmanuf_t *manuf_value;
if ((cur = (gchar *)g_hash_table_lookup(manuf_hashtable, &manuf_key)) == NULL) {
manuf_value = (hashmanuf_t *)g_hash_table_lookup(manuf_hashtable, &manuf_key);
if ((manuf_value == NULL) || (manuf_value->status != HASHETHER_STATUS_UNRESOLVED)) {
return NULL;
}
return cur;
return manuf_value->resolved_name;
}
const gchar *
@ -3150,19 +3182,25 @@ tvb_get_manuf_name_if_known(tvbuff_t *tvb, gint offset)
return get_manuf_name_if_known(tvb_get_ptr(tvb, offset, 3));
}
char* get_hash_manuf_resolved_name(hashmanuf_t* manuf)
{
return manuf->resolved_name;
}
const gchar *
eui64_to_display(wmem_allocator_t *allocator, const guint64 addr_eui64)
{
gchar *name;
guint8 *addr = (guint8 *)wmem_alloc(allocator, 8);
hashmanuf_t *manuf_value;
/* Copy and convert the address to network byte order. */
*(guint64 *)(void *)(addr) = pntoh64(&(addr_eui64));
if (!gbl_resolv_flags.mac_name || ((name = manuf_name_lookup(addr)) == NULL)) {
manuf_value = manuf_name_lookup(addr);
if (!gbl_resolv_flags.mac_name || (manuf_value->status == HASHETHER_STATUS_UNRESOLVED)) {
return wmem_strdup_printf(allocator, "%02x:%02x:%02x%02x:%02x:%02x%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7]);
}
return wmem_strdup_printf(allocator, "%s_%02x:%02x:%02x:%02x:%02x", name, addr[3], addr[4], addr[5], addr[6], addr[7]);
return wmem_strdup_printf(allocator, "%s_%02x:%02x:%02x:%02x:%02x", manuf_value->resolved_name, addr[3], addr[4], addr[5], addr[6], addr[7]);
} /* eui64_to_display */

View File

@ -59,6 +59,9 @@ typedef struct _e_addr_resolve {
struct hashether;
typedef struct hashether hashether_t;
struct hashmanuf;
typedef struct hashmanuf hashmanuf_t;
typedef struct serv_port {
gchar *udp_name;
gchar *tcp_name;
@ -177,7 +180,7 @@ gchar *get_ether_name_if_known(const guint8 *addr);
* Given a sequence of 3 octets containing an OID, get_manuf_name()
* returns the vendor name, or "%02x:%02x:%02x" if not known.
*/
extern gchar *get_manuf_name(wmem_allocator_t *allocator, const guint8 *addr);
extern const gchar *get_manuf_name(const guint8 *addr);
/*
* Given a sequence of 3 octets containing an OID, get_manuf_name_if_known()
@ -223,6 +226,9 @@ WS_DLL_PUBLIC guint get_hash_ether_status(hashether_t* ether);
WS_DLL_PUBLIC char* get_hash_ether_hexaddr(hashether_t* ether);
WS_DLL_PUBLIC char* get_hash_ether_resolved_name(hashether_t* ether);
WS_DLL_PUBLIC char* get_hash_manuf_resolved_name(hashmanuf_t* manuf);
/* returns the ethernet address corresponding to name or NULL if not known */
extern guint8 *get_ether_addr(const gchar *name);

View File

@ -429,7 +429,7 @@ static gboolean fcwwn_to_str(const address* addr, gchar *buf, int buf_len)
const guint8 *addrp = (const guint8*)addr->data;
int fmt;
guint8 oui[6];
gchar *ethptr, *manuf_name;
gchar *ethptr;
if (buf_len < 200) { /* This is mostly for manufacturer name */
g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
@ -444,9 +444,7 @@ static gboolean fcwwn_to_str(const address* addr, gchar *buf, int buf_len)
case FC_NH_NAA_IEEE_E:
memcpy (oui, &addrp[2], 6);
manuf_name = get_manuf_name(NULL, oui);
g_snprintf (ethptr, buf_len-23, " (%s)", manuf_name);
wmem_free(NULL, manuf_name);
g_snprintf (ethptr, buf_len-23, " (%s)", get_manuf_name(oui));
break;
case FC_NH_NAA_IEEE_R:
@ -457,9 +455,7 @@ static gboolean fcwwn_to_str(const address* addr, gchar *buf, int buf_len)
oui[4] = ((addrp[4] & 0x0F) << 4) | ((addrp[5] & 0xF0) >> 4);
oui[5] = ((addrp[5] & 0x0F) << 4) | ((addrp[6] & 0xF0) >> 4);
manuf_name = get_manuf_name(NULL, oui);
g_snprintf (ethptr, buf_len-23, " (%s)", manuf_name);
wmem_free(NULL, manuf_name);
g_snprintf (ethptr, buf_len-23, " (%s)", get_manuf_name(oui));
break;
default:

View File

@ -920,10 +920,10 @@ static void dissect_nhrp_ext(tvbuff_t *tvb,
tvb_memcpy(tvb, manuf, offset, 3);
vendor_tree = proto_tree_add_subtree_format(nhrp_tree, tvb, offset, len,
ett_nhrp_vendor_ext, NULL, "Extension Data: Vendor ID=%s, Data=%s", get_manuf_name(wmem_packet_scope(), manuf),
ett_nhrp_vendor_ext, NULL, "Extension Data: Vendor ID=%s, Data=%s", get_manuf_name(manuf),
tvb_bytes_to_str(wmem_packet_scope(), tvb, offset + 3, len - 3));
proto_tree_add_bytes_format_value(vendor_tree, hf_nhrp_vendor_ext_id, tvb,
offset, 3, manuf, "%s", get_manuf_name(wmem_packet_scope(), manuf));
offset, 3, manuf, "%s", get_manuf_name(manuf));
if (len > 3) {
proto_tree_add_item(vendor_tree, hf_nhrp_vendor_ext_data, tvb, offset + 3, len - 3, ENC_NA);
}

View File

@ -71,10 +71,10 @@ manuf_hash_to_texbuff(gpointer key, gpointer value, gpointer user_data)
{
gchar string_buff[ADDRESS_STR_MAX];
GtkTextBuffer *buffer = (GtkTextBuffer*)user_data;
gchar *name = (gchar *)value;
hashmanuf_t *manuf = (hashmanuf_t*)value;
int eth_as_gint = *(int*)key;
g_snprintf(string_buff, ADDRESS_STR_MAX, "%.2X:%.2X:%.2X %s\n",eth_as_gint>>16, (eth_as_gint>>8)&0xff, eth_as_gint&0xff,name);
g_snprintf(string_buff, ADDRESS_STR_MAX, "%.2X:%.2X:%.2X %s\n",eth_as_gint>>16, (eth_as_gint>>8)&0xff, eth_as_gint&0xff, get_hash_manuf_resolved_name(manuf));
gtk_text_buffer_insert_at_cursor (buffer, string_buff, -1);
}