Enable ether name resolution for packet summary lines of IPX packets
authorGilbert Ramirez <gram@alumni.rice.edu>
Sat, 20 Nov 1999 05:35:15 +0000 (05:35 -0000)
committerGilbert Ramirez <gram@alumni.rice.edu>
Sat, 20 Nov 1999 05:35:15 +0000 (05:35 -0000)
(in the src/dst of the CList). In order to do this, I had to:

1. Add a new function, ether_to_str_punct(const guint8*, char) which
turns a 6-byt ether address into a string, using whatever punctuation
is passed as the char. If a null char is passed, no separator
is put between the hex digits. Unresolved IPX addresses look better
with the ether portion having no punctuation (IMHO)

2. Changed ether_to_str() to call ether_to_str_punct with ':' as the char
argument. That is, code abstraction.

3. MAXNAMELEN was moved from resolv.c to resolv.h so that packet-ipx.c
could see it.

4. A new resolve function, get_ether_name_if_known(), returns the resolved name
of an ether address, or NULL if there is none.  This differs
from get_ether_name() by returning NULL rather than a text version
of the ether address.

svn path=/trunk/; revision=1076

packet-ipx.c
packet.c
packet.h
resolv.c
resolv.h

index 12a3ff5bc0aca39d703f599244c3ddebf3221d08..0f9af48a206c673bf19aea7f6e4c62227ea86e14 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for NetWare's IPX
  * Gilbert Ramirez <gram@verdict.uthscsa.edu>
  *
- * $Id: packet-ipx.c,v 1.33 1999/11/17 02:17:06 guy Exp $
+ * $Id: packet-ipx.c,v 1.34 1999/11/20 05:35:13 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@unicom.net>
@@ -37,6 +37,7 @@
 #include "packet.h"
 #include "packet-ipx.h"
 #include "packet-ncp.h"
+#include "resolv.h"
 
 /* The information in this module (IPX, SPX, NCP) comes from:
        NetWare LAN Analysis, Second Edition
@@ -229,7 +230,7 @@ static const value_string ipx_packet_type_vals[] = {
 gchar*
 ipxnet_to_string(const guint8 *ad)
 {
-       static gchar    str[3][12];
+       static gchar    str[3][8+3+1]; /* 8 digits, 3 spaces, 1 null */
        static gchar    *cur;
 
        if (cur == &str[0][0]) {
@@ -244,11 +245,17 @@ ipxnet_to_string(const guint8 *ad)
        return cur;
 }
 
+/* We use a different representation of hardware addresses
+ * than ether_to_str(); we don't put punctuation between the hex
+ * digits.
+ */
+
 gchar*
 ipx_addr_to_str(guint32 net, const guint8 *ad)
 {
-       static gchar    str[3][22];
+       static gchar    str[3][8+1+MAXNAMELEN+1]; /* 8 digits, 1 period, NAME, 1 null */
        static gchar    *cur;
+       char            *name;
 
        if (cur == &str[0][0]) {
                cur = &str[1][0];
@@ -258,8 +265,14 @@ ipx_addr_to_str(guint32 net, const guint8 *ad)
                cur = &str[0][0];
        }
 
-       sprintf(cur, "%X.%02x%02x%02x%02x%02x%02x", net, 
-               ad[0], ad[1], ad[2], ad[3], ad[4], ad[5]);
+       name = get_ether_name_if_known(ad);
+
+       if (name) {
+               sprintf(cur, "%X.%s", net, name);
+       }
+       else {
+               sprintf(cur, "%X.%s", net, ether_to_str_punct(ad, '\0'));
+       }
        return cur;
 }
 
index 48f158cd739a4a7554c97ad81bf1f556295d413a..fa9ee0ea5b2e988899aff2ed3e05e90e16c36d77 100644 (file)
--- a/packet.c
+++ b/packet.c
@@ -1,7 +1,7 @@
 /* packet.c
  * Routines for packet disassembly
  *
- * $Id: packet.c,v 1.55 1999/11/17 21:58:32 guy Exp $
+ * $Id: packet.c,v 1.56 1999/11/20 05:35:14 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -76,8 +76,21 @@ static int hf_frame_capture_len = -1;
 
 static gint ett_frame = -1;
 
+/* Wrapper for the most common case of asking
+ * for a string using a colon as the hex-digit separator.
+ */
+gchar *
+ether_to_str(const guint8 *ad)
+{
+       return ether_to_str_punct(ad, ':');
+}
+
+/* Places char punct in the string as the hex-digit separator.
+ * If punct is '\0', no punctuation is applied (and thus
+ * the resulting string is 5 bytes shorter)
+ */
 gchar *
-ether_to_str(const guint8 *ad) {
+ether_to_str_punct(const guint8 *ad, char punct) {
   static gchar  str[3][18];
   static gchar *cur;
   gchar        *p;
@@ -102,7 +115,8 @@ ether_to_str(const guint8 *ad) {
     *--p = hex_digits[octet&0xF];
     if (i == 0)
       break;
-    *--p = ':';
+    if (punct)
+      *--p = punct;
     i--;
   }
   return p;
index 875bc1f53d17ea65e41a806d6fec4fe41a03d4a5..dcb9ed477bd9cc2de732e4aaaf6ed0c2794cb820 100644 (file)
--- a/packet.h
+++ b/packet.h
@@ -1,7 +1,7 @@
 /* packet.h
  * Definitions for packet disassembly structures and routines
  *
- * $Id: packet.h,v 1.146 1999/11/19 09:55:38 guy Exp $
+ * $Id: packet.h,v 1.147 1999/11/20 05:35:14 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -208,6 +208,7 @@ typedef struct tcp_extra_data {
 
 /* Utility routines used by packet*.c */
 gchar*     ether_to_str(const guint8 *);
+gchar*     ether_to_str_punct(const guint8 *, char);
 gchar*     ip_to_str(const guint8 *);
 struct e_in6_addr;
 gchar*     ip6_to_str(struct e_in6_addr *);
index e3c990cf6cde7cadbd272e57cc1d459423e24fa2..988f5888401dfcfeceb4760d47f7b03d8e72208f 100644 (file)
--- a/resolv.c
+++ b/resolv.c
@@ -1,7 +1,7 @@
 /* resolv.c
  * Routines for network object lookup
  *
- * $Id: resolv.c,v 1.17 1999/11/20 03:39:20 gram Exp $
+ * $Id: resolv.c,v 1.18 1999/11/20 05:35:15 gram Exp $
  *
  * Laurent Deniel <deniel@worldnet.fr>
  *
@@ -76,9 +76,6 @@
 #include "globals.h"
 #include "resolv.h"
 
-#ifndef MAXNAMELEN
-#define MAXNAMELEN     64      /* max name length (hostname and port name) */
-#endif
 #define MAXMANUFLEN    9       /* max vendor name length with ending '\0' */
 #define HASHETHSIZE    1024
 #define HASHHOSTSIZE   1024
@@ -104,6 +101,7 @@ typedef struct hashmanuf {
 typedef struct hashether {
   u_char               addr[6];
   char                         name[MAXNAMELEN];
+  gboolean             is_name_from_file;
   struct hashether             *next;
 } hashether_t;
 
@@ -561,6 +559,37 @@ static hashmanuf_t *manuf_name_lookup(const u_char *addr)
 
 } /* manuf_name_lookup */
 
+static void initialize_ethers(void)
+{
+  ether_t *eth;
+
+#ifdef DEBUG_RESOLV
+  signal(SIGSEGV, SIG_IGN);
+#endif
+
+  /* Set g_pethers_path here, but don't actually do anything
+   * with it. It's used in get_ethbyname() and get_ethbyaddr()
+   */
+  if (g_pethers_path == NULL) {
+    g_pethers_path = g_malloc(strlen(getenv("HOME")) + 
+                             strlen(EPATH_PERSONAL_ETHERS) + 2);
+    sprintf(g_pethers_path, "%s/%s", 
+           (char *)getenv("HOME"), EPATH_PERSONAL_ETHERS);
+  }
+
+  /* manuf hash table initialization */
+
+  set_ethent(g_manuf_path);
+
+  while ((eth = get_ethent(0))) {
+    add_manuf_name(eth->addr, eth->name);
+    printf("Add manuf? %02x:%02x:%02x... %s\n", eth->addr[0], eth->addr[1], eth->addr[2], eth->name);
+  }
+
+  end_ethent();
+
+} /* initialize_ethers */
+
 static hashether_t *add_eth_name(u_char *addr, u_char *name)
 {
   hashether_t *tp;
@@ -639,15 +668,78 @@ static u_char *eth_name_lookup(const u_char *addr)
       sprintf(tp->name, "%s_%02x:%02x:%02x", 
              manufp->name, addr[3], addr[4], addr[5]);
 
+    tp->is_name_from_file = FALSE;
+
   } else {
     strncpy(tp->name, eth->name, MAXNAMELEN);
     tp->name[MAXNAMELEN-1] = '\0';
+    tp->is_name_from_file = TRUE;
   }
 
   return (tp->name);
 
 } /* eth_name_lookup */
 
+/* Look for an ether name in the hash, and return it if found.
+ * If it's not found, simply return NULL. We DO NOT make a new
+ * hash entry for it with the hex digits turned into a string.
+ */
+u_char *get_ether_name_if_known(const u_char *addr)
+{
+  hashether_t *tp;
+  hashether_t **table = eth_table;
+  int i,j;
+
+  /* Initialize ether structs if we're the first
+   * ether-related function called */
+  if (!g_resolving_actif)
+    return NULL;
+  
+  if (!eth_resolution_initialized) {
+    initialize_ethers();
+    eth_resolution_initialized = 1;
+  }
+
+  j = (addr[2] << 8) | addr[3];
+  i = (addr[4] << 8) | addr[5];
+
+  tp = table[ (i ^ j) & (HASHETHSIZE - 1)];
+
+  if( tp == NULL ) {
+         /* Hash key not found in table.
+          * Force a lookup (and a hash entry) for addr, then call
+          * myself. I plan on not getting into an infinite loop because
+          * eth_name_lookup() is guaranteed to make a hashtable entry,
+          * so when I call myself again, I can never get into this
+          * block of code again. Knock on wood...
+          */
+         (void) eth_name_lookup(addr);
+         return get_ether_name_if_known(addr); /* a well-placed goto would suffice */
+  }
+  else { 
+    while(1) {
+      if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
+             if (tp->is_name_from_file) {
+               /* A name was found, and its origin is an ethers file */
+               return tp->name;
+             }
+             else {
+               /* A name was found, but it was created, not found in a file */
+               return NULL;
+             }
+      }
+      if (tp->next == NULL) {
+         /* Read my reason above for why I'm sure I can't get into an infinite loop */
+         (void) eth_name_lookup(addr);
+         return get_ether_name_if_known(addr); /* a well-placed goto would suffice */
+      }
+      tp = tp->next;
+    }
+  }
+  g_assert_not_reached();
+  return NULL;
+}
+
 static u_char *eth_addr_lookup(u_char *name)
 {
   ether_t *eth;
@@ -678,32 +770,6 @@ static u_char *eth_addr_lookup(u_char *name)
 
 } /* eth_addr_lookup */
 
-static void initialize_ethers(void)
-{
-  ether_t *eth;
-
-#ifdef DEBUG_RESOLV
-  signal(SIGSEGV, SIG_IGN);
-#endif
-
-  if (g_pethers_path == NULL) {
-    g_pethers_path = g_malloc(strlen(getenv("HOME")) + 
-                             strlen(EPATH_PERSONAL_ETHERS) + 2);
-    sprintf(g_pethers_path, "%s/%s", 
-           (char *)getenv("HOME"), EPATH_PERSONAL_ETHERS);
-  }
-
-  /* manuf hash table initialization */
-
-  set_ethent(g_manuf_path);
-
-  while ((eth = get_ethent(0))) {
-    add_manuf_name(eth->addr, eth->name);
-  }
-
-  end_ethent();
-
-} /* initialize_ethers */
 
 /* 
  *  External Functions
index 9453449981b94bdd23aa68d0c5e09ed32752a4db..c2406ab250d627b3abcb15fc1daa2bc66e487984 100644 (file)
--- a/resolv.h
+++ b/resolv.h
@@ -1,7 +1,7 @@
 /* resolv.h
  * Definitions for network object lookup
  *
- * $Id: resolv.h,v 1.9 1999/10/22 07:17:51 guy Exp $
+ * $Id: resolv.h,v 1.10 1999/11/20 05:35:15 gram Exp $
  *
  * Laurent Deniel <deniel@worldnet.fr>
  *
 #define EPATH_MANUF            DATAFILE_DIR "/manuf"
 #define EPATH_PERSONAL_ETHERS  ".ethereal/ethers" /* with "$HOME/" prefix */
 
+#ifndef MAXNAMELEN
+#define MAXNAMELEN     64      /* max name length (hostname and port name) */
+#endif
+
 /* global variables */
 
 extern gchar *g_ethers_path;
@@ -62,6 +66,9 @@ gchar* get_hostname6(struct e_in6_addr *ad);
    "%02x:%02x:%02x:%02x:%02x:%02x" */
 extern u_char *get_ether_name(const u_char *addr);
 
+/* get_ether_name returns the logical name if found in ethers files else NULL */
+extern u_char *get_ether_name_if_known(const u_char *addr);
+
 /* get_manuf_name returns the vendor name or "%02x:%02x:%02x" if not known */
 extern u_char *get_manuf_name(u_char *addr);