/* 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>
#include <glib.h>
#include "packet.h"
+#include "resolv.h"
#include "packet-arp.h"
#include "etypes.h"
}
}
+ 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,
/* 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>
*
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;
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;
}
#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 ) {
} else {
while(1) {
if( tp->addr == addr ) {
+ if (tp->is_dummy_entry)
+ *found = FALSE;
return tp->name;
}
if (tp->next == NULL) {
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
/* 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 */
if (hostp != NULL) {
strncpy(name, hostp->h_name, MAXNAMELEN);
name[MAXNAMELEN-1] = '\0';
+ *found = TRUE;
return name;
}
#ifdef AVOID_DNS_TIMEOUT
/* unknown host or DNS timeout */
#endif /* INET6 */
+ *found = FALSE;
sprintf(name, "%s", ip6_to_str(addr));
return (name);
}
} /* get_ethent */
-static ether_t *get_ethbyname(u_char *name)
+static ether_t *get_ethbyname(const u_char *name)
{
ether_t *eth;
} /* 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;
(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;
strncpy(tp->name, name, MAXNAMELEN);
tp->name[MAXNAMELEN-1] = '\0';
tp->next = NULL;
+ tp->is_dummy_entry = FALSE;
return tp;
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;
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)
(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));
tp->name[MAXNAMELEN-1] = '\0';
tp->addr = addr;
tp->next = NULL;
+ tp->is_dummy_entry = FALSE;
} /* add_host_name */
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;
}
} /* 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)
{