aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Deniel <laurent.deniel@free.fr>2000-08-10 20:09:29 +0000
committerLaurent Deniel <laurent.deniel@free.fr>2000-08-10 20:09:29 +0000
commit6f5b18e7cc33565935dbea9e6c66700424f990e4 (patch)
tree9bca3c1fe4db9bab44895639a35254759723baa4
parent9fd68ec37fb2dc6bf35a900e7a6c0db8191b5a2b (diff)
- rename is_name_from_file to is_dummy_entry since now a real
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). svn path=/trunk/; revision=2248
-rw-r--r--packet-arp.c22
-rw-r--r--resolv.c77
-rw-r--r--resolv.h5
3 files changed, 87 insertions, 17 deletions
diff --git a/packet-arp.c b/packet-arp.c
index e33874d68e..b043eb9c32 100644
--- a/packet-arp.c
+++ b/packet-arp.c
@@ -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,
diff --git a/resolv.c b/resolv.c
index f17327bdda..09e9a3bead 100644
--- 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)
{
diff --git a/resolv.h b/resolv.h
index 2a7723e90d..59603b869d 100644
--- 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. */