Make get_manuf_name return a const string.
authorMichael Mann <mmann78@netscape.net>
Thu, 12 Feb 2015 03:16:01 +0000 (22:16 -0500)
committerAnders Broman <a.broman58@gmail.com>
Thu, 12 Feb 2015 07:36:20 +0000 (07:36 +0000)
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>
debian/libwireshark0.symbols
epan/addr_resolv.c
epan/addr_resolv.h
epan/address_types.c
epan/dissectors/packet-nhrp.c
ui/gtk/addr_resolution_dlg.c

index bcf216b9aad9883503f006772a3151f02f36cbf4..311751dc318337bcb34976c706ad4c4bbb575cd3 100644 (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
index 171b8918296b2531ae6443aeaa38cded82410c11..b24ad07796ff6097e4e16cd73ffd795254b7db03 100644 (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 */
 
index eda5885bb8063deb5281b1576f57af920d4adb64..068a741460878fd0bb8cee02fc9fbff2b3dc9e31 100644 (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);
 
index 61d3f52a2d08ee2cedfcd6c27c6b71f89661de9b..4c447c6a9468e16c3a40c226a0f2416389144651 100644 (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:
index dc35490cc6b35885141256adf5239f0c0b3a429f..06abf3fe83efebd40786f3ed6fa8de5cbbe16d87 100644 (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);
                     }
index d7ec0a0ecea01cd5803d8dbed9dbc9a205b7c588..cca7db805cb928cfa7fb479e0a50de12d858ce22 100644 (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);
 
 }