From 6f5b18e7cc33565935dbea9e6c66700424f990e4 Mon Sep 17 00:00:00 2001 From: Laurent Deniel Date: Thu, 10 Aug 2000 20:09:29 +0000 Subject: - 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 --- packet-arp.c | 22 ++++++++++++++++- resolv.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++------------ resolv.h | 5 +++- 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 @@ -33,6 +33,7 @@ #include #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 * @@ -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 * @@ -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. */ -- cgit v1.2.3