- rename is_name_from_file to is_dummy_entry since now a real
authordeniel <deniel@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 10 Aug 2000 20:09:29 +0000 (20:09 +0000)
committerdeniel <deniel@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 10 Aug 2000 20:09:29 +0000 (20:09 +0000)
  name can be added from file reading but also from the dissectors.
- add is_dummy_entry in the hosts hashtable.
- check in add_xxx that the entry is not already there, if so
  do nothing except if this is a dummy entry (in this case, it is
  simply replaced).
- add found boolean parameter to host_name_lookup[6]
- add the add_ether_byip procedure which adds a new ether entry
  knowing the IP address (if the IP address can be resolved).
- and finally call this new procedure from ARP dissector.

(ipxnets (among other things) to be updated).

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@2248 f5534014-38df-0310-8fa8-9805f1628bb7

packet-arp.c
resolv.c
resolv.h

index e33874d68e6c6abd3c307249b40ab254d59806f4..b043eb9c327c2adad60c8a9de477b7f20a14f256 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-arp.c
  * Routines for ARP packet disassembly
  *
- * $Id: packet-arp.c,v 1.31 2000/08/07 03:20:21 guy Exp $
+ * $Id: packet-arp.c,v 1.32 2000/08/10 20:09:29 deniel Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -33,6 +33,7 @@
 
 #include <glib.h>
 #include "packet.h"
+#include "resolv.h"
 #include "packet-arp.h"
 #include "etypes.h"
 
@@ -637,6 +638,25 @@ dissect_arp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
     }
   }
 
+  if ((ar_op == ARPOP_REPLY || ar_op == ARPOP_REQUEST) &&
+      ar_hln == 6 && ar_pln == 4) {
+
+    /* inform resolv.c module of the new discovered addresses */
+
+    u_int ip;
+
+    /* add sender address in all cases */
+
+    memcpy(&ip, &pd[spa_offset], sizeof(ip));
+    add_ether_byip(ip, &pd[sha_offset]);
+    
+    if (ar_op == ARPOP_REQUEST) {
+      /* add destination address */
+      memcpy(&ip, &pd[tpa_offset], sizeof(ip));
+      add_ether_byip(ip, &pd[tha_offset]);
+    }
+  }
+
   if (tree) {
     if ((op_str = match_strval(ar_op, op_vals)))
       ti = proto_tree_add_protocol_format(tree, proto_arp, NullTVB, offset, tot_len,
index f17327bddab9f238854ea5241ae112332f7ed88f..09e9a3beada9edb80e3163d1849371799334e798 100644 (file)
--- a/resolv.c
+++ b/resolv.c
@@ -1,7 +1,7 @@
 /* resolv.c
  * Routines for network object lookup
  *
- * $Id: resolv.c,v 1.25 2000/08/08 16:21:24 deniel Exp $
+ * $Id: resolv.c,v 1.26 2000/08/10 20:09:28 deniel Exp $
  *
  * Laurent Deniel <deniel@worldnet.fr>
  *
@@ -96,6 +96,7 @@
 typedef struct hashname {
   u_int                        addr;
   u_char               name[MAXNAMELEN];
+  gboolean              is_dummy_entry;        /* name is IP address in dot format */
   struct hashname      *next;
 } hashname_t;
 
@@ -114,7 +115,7 @@ typedef struct hashmanuf {
 typedef struct hashether {
   u_char               addr[6];
   char                         name[MAXNAMELEN];
-  gboolean             is_name_from_file;
+  gboolean             is_dummy_entry;         /* not a complete entry */
   struct hashether             *next;
 } hashether_t;
 
@@ -234,13 +235,15 @@ static void abort_network_query(int sig)
 }
 #endif /* AVOID_DNS_TIMEOUT */
 
-static u_char *host_name_lookup(u_int addr)
+static u_char *host_name_lookup(u_int addr, gboolean *found)
 {
 
   hashname_t * volatile tp;
   hashname_t **table = host_table;
   struct hostent *hostp;
 
+  *found = TRUE;
+
   tp = table[ addr & (HASHHOSTSIZE - 1)];
 
   if( tp == NULL ) {
@@ -249,6 +252,8 @@ static u_char *host_name_lookup(u_int addr)
   } else {  
     while(1) {
       if( tp->addr == addr ) {
+       if (tp->is_dummy_entry)
+         *found = FALSE;
        return tp->name;
       }
       if (tp->next == NULL) {
@@ -279,6 +284,7 @@ static u_char *host_name_lookup(u_int addr)
     if (hostp != NULL) {
       strncpy(tp->name, hostp->h_name, MAXNAMELEN);
       tp->name[MAXNAMELEN-1] = '\0';
+      tp->is_dummy_entry = FALSE;
       return tp->name;
     }
 #ifdef AVOID_DNS_TIMEOUT
@@ -288,17 +294,18 @@ static u_char *host_name_lookup(u_int addr)
   /* unknown host or DNS timeout */
 
   sprintf(tp->name, "%s", ip_to_str((guint8 *)&addr));  
+  tp->is_dummy_entry = TRUE;
+  *found = FALSE;
 
   return (tp->name);
 
 } /* host_name_lookup */
 
-static u_char *host_name_lookup6(struct e_in6_addr *addr)
+static u_char *host_name_lookup6(struct e_in6_addr *addr, gboolean *found)
 {
   static u_char name[MAXNAMELEN];
 #ifdef INET6
   struct hostent *hostp;
-
 #ifdef AVOID_DNS_TIMEOUT
     
   /* Quick hack to avoid DNS/YP timeout */
@@ -314,6 +321,7 @@ static u_char *host_name_lookup6(struct e_in6_addr *addr)
     if (hostp != NULL) {
       strncpy(name, hostp->h_name, MAXNAMELEN);
       name[MAXNAMELEN-1] = '\0';
+      *found = TRUE;
       return name;
     }
 #ifdef AVOID_DNS_TIMEOUT
@@ -322,6 +330,7 @@ static u_char *host_name_lookup6(struct e_in6_addr *addr)
 
   /* unknown host or DNS timeout */
 #endif /* INET6 */
+  *found = FALSE;
   sprintf(name, "%s", ip6_to_str(addr));  
   return (name);
 }
@@ -488,7 +497,7 @@ static ether_t *get_ethent(int six_bytes)
 
 } /* get_ethent */
 
-static ether_t *get_ethbyname(u_char *name)
+static ether_t *get_ethbyname(const u_char *name)
 {
   ether_t *eth;
   
@@ -615,7 +624,7 @@ static void initialize_ethers(void)
 
 } /* initialize_ethers */
 
-static hashether_t *add_eth_name(u_char *addr, u_char *name)
+static hashether_t *add_eth_name(const u_char *addr, const u_char *name)
 {
   hashether_t *tp;
   hashether_t **table = eth_table;
@@ -631,6 +640,15 @@ static hashether_t *add_eth_name(u_char *addr, u_char *name)
       (hashether_t *)g_malloc(sizeof(hashether_t));
   } else {  
     while(1) {
+      if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
+       /* address already known */
+       if (!tp->is_dummy_entry) {
+         return tp;
+       } else {
+         /* replace this dummy (manuf) entry with a real name */
+         break;
+       }
+      }
       if (tp->next == NULL) {
        tp->next = (hashether_t *)g_malloc(sizeof(hashether_t));
        tp = tp->next;
@@ -644,6 +662,7 @@ static hashether_t *add_eth_name(u_char *addr, u_char *name)
   strncpy(tp->name, name, MAXNAMELEN);
   tp->name[MAXNAMELEN-1] = '\0';
   tp->next = NULL;
+  tp->is_dummy_entry = FALSE;
 
   return tp;
 
@@ -693,19 +712,19 @@ 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;
+    tp->is_dummy_entry = TRUE;
 
   } else {
     strncpy(tp->name, eth->name, MAXNAMELEN);
     tp->name[MAXNAMELEN-1] = '\0';
-    tp->is_name_from_file = TRUE;
+    tp->is_dummy_entry = FALSE;
   }
 
   return (tp->name);
 
 } /* eth_name_lookup */
 
-static u_char *eth_addr_lookup(u_char *name)
+static u_char *eth_addr_lookup(const u_char *name)
 {
   ether_t *eth;
   hashether_t *tp;
@@ -1008,21 +1027,26 @@ static u_int ipxnet_addr_lookup(u_char *name, gboolean *success)
 
 extern u_char *get_hostname(u_int addr) 
 {
+  gboolean found;
+
   if (!g_resolving_actif)
     return ip_to_str((guint8 *)&addr);
 
-  return host_name_lookup(addr);
+  return host_name_lookup(addr, &found);
 }
 
 extern gchar *get_hostname6(struct e_in6_addr *addr) 
 {
+  gboolean found;
+
 #ifdef INET6
   if (!g_resolving_actif)
     return ip6_to_str(addr);
   if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_MULTICAST(addr))
     return ip6_to_str(addr);
 #endif
-  return host_name_lookup6(addr);
+
+  return host_name_lookup6(addr, &found);
 }
 
 extern void add_host_name(u_int addr, u_char *name)
@@ -1038,9 +1062,14 @@ extern void add_host_name(u_int addr, u_char *name)
       (hashname_t *)g_malloc(sizeof(hashname_t));
   } else {  
     while(1) {
-      if (tp->addr == addr && strcmp(tp->name, name) == 0) {
+      if (tp->addr == addr) {
        /* address already known */
-       return;
+       if (!tp->is_dummy_entry) {
+         return;
+       } else {
+         /* replace this dummy entry with the new one */
+         break;
+       }
       }
       if (tp->next == NULL) {
        tp->next = (hashname_t *)g_malloc(sizeof(hashname_t));
@@ -1055,6 +1084,7 @@ extern void add_host_name(u_int addr, u_char *name)
   tp->name[MAXNAMELEN-1] = '\0';
   tp->addr = addr;
   tp->next = NULL;
+  tp->is_dummy_entry = FALSE;
 
 } /* add_host_name */
 
@@ -1153,7 +1183,7 @@ u_char *get_ether_name_if_known(const u_char *addr)
   else { 
     while(1) {
       if (memcmp(tp->addr, addr, sizeof(tp->addr)) == 0) {
-             if (tp->is_name_from_file) {
+             if (!tp->is_dummy_entry) {
                /* A name was found, and its origin is an ethers file */
                return tp->name;
              }
@@ -1189,6 +1219,23 @@ extern u_char *get_ether_addr(u_char *name)
 
 } /* get_ether_addr */
 
+extern void add_ether_byip(u_int ip, const u_char *eth)
+{
+
+  u_char *host;
+  gboolean found;
+
+  /* first check that IP address can be resolved */
+
+  if ((host = host_name_lookup(ip, &found)) == NULL)
+    return;
+  
+  /* ok, we can add this entry in the ethers hashtable */
+
+  if (found)
+    add_eth_name(eth, host);
+
+} /* add_ether_byip */
 
 extern u_char *get_ipxnet_name(const guint32 addr)
 {
index 2a7723e90db316519a55f5f8c78f6e57336fa073..59603b869d88a02a2849b0dcf1ebcbe8b3a868d2 100644 (file)
--- a/resolv.h
+++ b/resolv.h
@@ -1,7 +1,7 @@
 /* resolv.h
  * Definitions for network object lookup
  *
- * $Id: resolv.h,v 1.11 1999/11/21 16:32:16 gram Exp $
+ * $Id: resolv.h,v 1.12 2000/08/10 20:09:29 deniel Exp $
  *
  * Laurent Deniel <deniel@worldnet.fr>
  *
@@ -90,6 +90,9 @@ guint32 get_ipxnet_addr(u_char *name, gboolean *known);
 /* adds a hostname/IP in the hash table */
 extern void add_host_name(u_int addr, u_char *name);
 
+/* add ethernet address / name corresponding to IP address  */
+extern void add_ether_byip(u_int ip, const u_char *eth);
+
 /* Translates a string representing the hostname or dotted-decimal IP address
  * into a numeric IP address value, returning TRUE if it succeeds and
  * FALSE if it fails. */