diff --git a/Makefile.am b/Makefile.am index 04df5e5afa9..419aba24386 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Ethereal # -# $Id: Makefile.am,v 1.94 1999/10/21 22:18:33 guy Exp $ +# $Id: Makefile.am,v 1.95 1999/10/22 07:17:27 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs @@ -120,6 +120,8 @@ ethereal_SOURCES = \ colors.h \ column.c \ column.h \ + conversation.c \ + conversation.h \ dfilter-int.h \ dfilter-grammar.y \ dfilter-scanner.l \ diff --git a/conversation.c b/conversation.c new file mode 100644 index 00000000000..0cef652d2e2 --- /dev/null +++ b/conversation.c @@ -0,0 +1,294 @@ +/* conversation.c + * Routines for building lists of packets that are part of a "conversation" + * + * $Id: conversation.c,v 1.1 1999/10/22 07:17:28 guy Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#include +#include +#include "packet.h" + +static GHashTable *conversation_hashtable = NULL; +static GMemChunk *conversation_key_chunk = NULL; +static GMemChunk *conversation_val_chunk = NULL; + +typedef struct conversation_key { + struct conversation_key *next; + address src; + address dst; + port_type ptype; + guint16 port_src; + guint16 port_dst; +} conversation_key; + +/* + * Linked list of conversation keys, so we can, before freeing them all, + * free the address data allocations associated with them. + */ +static conversation_key *conversation_keys; + +typedef struct conversation_val { + struct conversation_val *next; + guint32 index; +} conversation_val; + +static guint32 new_index; + +static int conversation_init_count = 200; + +/* + * Compare two conversation keys. + */ +static gint +conversation_equal(gconstpointer v, gconstpointer w) +{ + conversation_key *v1 = (conversation_key *)v; + conversation_key *v2 = (conversation_key *)w; + + /* + * We assume that a source and a destination address for a given + * packet in a conversation have the same type. + */ + if (v1->src.type != v2->src.type) + return 0; /* different types of addresses */ + + if (v1->ptype != v2->ptype) + return 0; /* different types of port */ + + if (v1->src.len == v2->src.len && + memcmp(v1->src.data, v2->src.data, v1->src.len) == 0) { + /* + * The first and second source addresses are the same. + */ + if (v1->dst.len == v2->dst.len && + memcmp(v1->dst.data, v2->dst.data, v1->dst.len) == 0) { + /* + * The first and second destination addresses + * are the same, so they're both going from + * the same machine and they're both going to + * the same machine. + */ + if (v1->port_src == v2->port_src && + v1->port_dst == v2->port_dst) { + /* + * The first and second source ports + * are the same, and the first and second + * destination ports are the same, so + * it's the same conversation, and the two + * address/port pairs are going in the same + * direction. + */ + return 1; + } + } + } else if (v1->src.len == v2->dst.len && + memcmp(v1->src.data, v2->dst.data, v1->src.len) == 0) { + /* + * The first source address is the same as the second + * destination address. + */ + if (v1->dst.len == v2->src.len && + memcmp(v1->dst.data, v2->src.data, v1->dst.len) == 0) { + /* + * The first destination address is the same as + * the second source address, so they're going + * between the same machines, but in opposite + * directions. + */ + if (v1->port_src == v2->port_dst && + v1->port_dst == v2->port_src) { + /* + * The first source port is the same as + * the second destination port, and the + * first destination port is the same as + * the second source port, so it's + * the same conversation, and the two + * address/port pairs are going in + * opposite directions. + */ + return 1; + } + } + } + + /* + * The addresses or the ports don't match. + */ + return 0; +} + +/* + * Compute the hash value for a given set of source and destination + * addresses and ports. + */ +static guint +conversation_hash(gconstpointer v) +{ + conversation_key *key = (conversation_key *)v; + guint hash_val; + int i; + + hash_val = 0; + for (i = 0; i < key->src.len; i++) + hash_val += key->src.data[i]; + for (i = 0; i < key->dst.len; i++) + hash_val += key->dst.data[i]; + hash_val += key->port_src + key->port_dst; + + return hash_val; +} + +/* + * Initialize some variables every time a file is loaded or re-loaded. + * Destroy all existing conversations, and create a new hash table + * for the conversations in the new file. + */ +void +conversation_init(void) +{ + conversation_key *key; + + /* + * Free the addresses associated with the conversation keys. + */ + for (key = conversation_keys; key != NULL; key = key->next) { + /* + * Grr. I guess the theory here is that freeing + * something sure as heck modifies it, so you + * want to ban attempts to free it, but, alas, + * if we make the "data" field of an "address" + * structure not a "const", the compiler whines if + * we try to make it point into the data for a packet, + * as that's a "const" array (and should be, as dissectors + * shouldn't trash it). + * + * So we cast the complaint into oblivion, and rely on + * the fact that these addresses are known to have had + * their data mallocated, i.e. they don't point into, + * say, the middle of the data for a packet. + */ + g_free((gpointer)key->src.data); + g_free((gpointer)key->dst.data); + } + if (conversation_hashtable != NULL) + g_hash_table_destroy(conversation_hashtable); + if (conversation_key_chunk != NULL) + g_mem_chunk_destroy(conversation_key_chunk); + if (conversation_val_chunk != NULL) + g_mem_chunk_destroy(conversation_val_chunk); + + conversation_hashtable = g_hash_table_new(conversation_hash, + conversation_equal); + conversation_key_chunk = g_mem_chunk_new("conversation_key_chunk", + sizeof(conversation_key), + conversation_init_count * sizeof(struct conversation_key), + G_ALLOC_AND_FREE); + conversation_val_chunk = g_mem_chunk_new("conversation_val_chunk", + sizeof(conversation_val), + conversation_init_count * sizeof(struct conversation_val), + G_ALLOC_AND_FREE); + + /* + * Start the conversation indices over at 0. + */ + new_index = 0; +} + +/* + * Copy an address, allocating a new buffer for the address data. + */ +static void +copy_address(address *to, address *from) +{ + guint8 *data; + + to->type = from->type; + to->len = from->len; + data = g_malloc(from->len); + memcpy(data, from->data, from->len); + to->data = data; +} + +/* + * Given source and destination addresses and ports for a packet, add + * it to the conversation containing packets between those address/port + * pairs, creating a new conversation if none exists between them. + * + * Returns an index to use to refer to the conversation. + */ +guint32 +add_to_conversation(address *src, address *dst, port_type ptype, + guint16 src_port, guint16 dst_port) +{ + conversation_val *conversation; + conversation_key key, *new_key; + + /* + * We don't make a copy of the address data, we just copy the + * pointer to it, as "key" disappears when we return. + */ + key.src = *src; + key.dst = *dst; + key.ptype = ptype; + key.port_src = src_port; + key.port_dst = dst_port; + conversation = + (conversation_val *)g_hash_table_lookup(conversation_hashtable, + &key); + if (conversation == NULL) { + /* + * No such conversation yet. + * Allocate a new one. + * Here, we *do* have to copy the address data. + */ + new_key = g_mem_chunk_alloc(conversation_key_chunk); + new_key->next = conversation_keys; + conversation_keys = new_key; + copy_address(&new_key->src, src); + copy_address(&new_key->dst, dst); + new_key->ptype = ptype; + new_key->port_src = src_port; + new_key->port_dst = dst_port; + + conversation = g_mem_chunk_alloc(conversation_val_chunk); + conversation->index = new_index; + new_index++; + + g_hash_table_insert(conversation_hashtable, new_key, + conversation); + } + return conversation->index; +} diff --git a/conversation.h b/conversation.h new file mode 100644 index 00000000000..5b722051aa5 --- /dev/null +++ b/conversation.h @@ -0,0 +1,28 @@ +/* conversation.h + * Routines for building lists of packets that are part of a "conversation" + * + * $Id: conversation.h,v 1.1 1999/10/22 07:17:28 guy Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +extern void conversation_init(void); +extern guint32 add_to_conversation(address *src, address *dst, port_type ptype, + guint16 src_port, guint16 dst_port); diff --git a/file.c b/file.c index 51619f2065a..1488c52c05f 100644 --- a/file.c +++ b/file.c @@ -1,7 +1,7 @@ /* file.c * File I/O routines * - * $Id: file.c,v 1.109 1999/10/20 16:41:16 gram Exp $ + * $Id: file.c,v 1.110 1999/10/22 07:17:28 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -83,6 +83,13 @@ #include "gtk/proto_draw.h" #include "dfilter.h" #include "timestamp.h" +#include "conversation.h" + +#ifndef __RESOLV_H__ +#include "resolv.h" +#endif + +#include "packet-ipv6.h" #include "packet-ncp.h" @@ -130,6 +137,9 @@ open_cap_file(char *fname, capture_file *cf) { and fill in the information for this file. */ close_cap_file(cf, info_bar, file_ctx); + /* Initialize the table of conversations. */ + conversation_init(); + /* Initialize protocol-specific variables */ afs_init_protocol(); ncp_init_protocol(); @@ -525,14 +535,14 @@ tail_cap_file(char *fname, capture_file *cf) { /* To do: Add check_col checks to the col_add* routines */ static void -col_add_abs_time(frame_data *fd, gint el) +col_set_abs_time(frame_data *fd, int col) { struct tm *tmp; time_t then; then = fd->abs_secs; tmp = localtime(&then); - col_add_fstr(fd, el, "%02d:%02d:%02d.%04ld", + snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%02d:%02d:%02d.%04ld", tmp->tm_hour, tmp->tm_min, tmp->tm_sec, @@ -540,54 +550,232 @@ col_add_abs_time(frame_data *fd, gint el) } static void -col_add_rel_time(frame_data *fd, gint el) +col_set_rel_time(frame_data *fd, int col) { - col_add_fstr(fd, el, "%d.%06d", fd->rel_secs, fd->rel_usecs); + snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%d.%06d", fd->rel_secs, + fd->rel_usecs); } static void -col_add_delta_time(frame_data *fd, gint el) +col_set_delta_time(frame_data *fd, int col) { - col_add_fstr(fd, el, "%d.%06d", fd->del_secs, fd->del_usecs); + snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%d.%06d", fd->del_secs, + fd->del_usecs); } /* Add "command-line-specified" time. */ static void -col_add_cls_time(frame_data *fd) +col_set_cls_time(frame_data *fd, int col) { switch (timestamp_type) { case ABSOLUTE: - col_add_abs_time(fd, COL_CLS_TIME); + col_set_abs_time(fd, col); break; case RELATIVE: - col_add_rel_time(fd, COL_CLS_TIME); + col_set_rel_time(fd, col); break; case DELTA: - col_add_delta_time(fd, COL_CLS_TIME); + col_set_delta_time(fd, col); + break; + } +} + +static void +col_set_addr(frame_data *fd, int col, address *addr, gboolean is_res) +{ + u_int ipv4_addr; + struct e_in6_addr ipv6_addr; + + switch (addr->type) { + + case AT_ETHER: + if (is_res) + strncpy(fd->cinfo->col_data[col], get_ether_name(addr->data), COL_MAX_LEN); + else + strncpy(fd->cinfo->col_data[col], ether_to_str(addr->data), COL_MAX_LEN); + break; + + case AT_IPv4: + memcpy(&ipv4_addr, addr->data, sizeof ipv4_addr); + if (is_res) + strncpy(fd->cinfo->col_data[col], get_hostname(ipv4_addr), COL_MAX_LEN); + else + strncpy(fd->cinfo->col_data[col], ip_to_str(addr->data), COL_MAX_LEN); + break; + + case AT_IPv6: + memcpy(&ipv6_addr.s6_addr, addr->data, sizeof ipv6_addr.s6_addr); + if (is_res) + strncpy(fd->cinfo->col_data[col], get_hostname6(&ipv6_addr), COL_MAX_LEN); + else + strncpy(fd->cinfo->col_data[col], ip6_to_str(&ipv6_addr), COL_MAX_LEN); + break; + + case AT_IPX: + strncpy(fd->cinfo->col_data[col], + ipx_addr_to_str(pntohl(&addr->data[0]), &addr->data[4]), COL_MAX_LEN); + break; + + case AT_SNA: + switch (addr->len) { + + case 1: + snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%04X", addr->data[0]); + break; + + case 2: + snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%04X", + pntohs(&addr->data[0])); break; + } + break; + + default: + break; } + fd->cinfo->col_data[col][COL_MAX_LEN - 1] = '\0'; +} + +static void +col_set_port(frame_data *fd, int col, port_type ptype, guint32 port, + gboolean is_res) +{ + switch (ptype) { + + case PT_TCP: + if (is_res) + strncpy(fd->cinfo->col_data[col], get_tcp_port(port), COL_MAX_LEN); + else + snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%u", port); + break; + + case PT_UDP: + if (is_res) + strncpy(fd->cinfo->col_data[col], get_udp_port(port), COL_MAX_LEN); + else + snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%u", port); + break; + + default: + break; + } + fd->cinfo->col_data[col][COL_MAX_LEN - 1] = '\0'; } static void fill_in_columns(frame_data *fd) { - if (check_col(fd, COL_NUMBER)) - col_add_fstr(fd, COL_NUMBER, "%u", fd->num); - - /* Set any time stamp columns. */ - if (check_col(fd, COL_CLS_TIME)) - col_add_cls_time(fd); - if (check_col(fd, COL_ABS_TIME)) - col_add_abs_time(fd, COL_ABS_TIME); - if (check_col(fd, COL_REL_TIME)) - col_add_rel_time(fd, COL_REL_TIME); - if (check_col(fd, COL_DELTA_TIME)) - col_add_delta_time(fd, COL_DELTA_TIME); - - if (check_col(fd, COL_PACKET_LENGTH)) - col_add_fstr(fd, COL_PACKET_LENGTH, "%d", fd->pkt_len); + int i; + + for (i = 0; i < fd->cinfo->num_cols; i++) { + switch (fd->cinfo->col_fmt[i]) { + + case COL_NUMBER: + snprintf(fd->cinfo->col_data[i], COL_MAX_LEN, "%u", fd->num); + break; + + case COL_CLS_TIME: + col_set_cls_time(fd, i); + break; + + case COL_ABS_TIME: + col_set_abs_time(fd, i); + break; + + case COL_REL_TIME: + col_set_rel_time(fd, i); + break; + + case COL_DELTA_TIME: + col_set_delta_time(fd, i); + break; + + case COL_DEF_SRC: + case COL_RES_SRC: /* COL_DEF_SRC is currently just like COL_RES_SRC */ + col_set_addr(fd, i, &pi.src, TRUE); + break; + + case COL_UNRES_SRC: + col_set_addr(fd, i, &pi.src, FALSE); + break; + + case COL_DEF_DL_SRC: + case COL_RES_DL_SRC: + col_set_addr(fd, i, &pi.dl_src, TRUE); + break; + + case COL_UNRES_DL_SRC: + col_set_addr(fd, i, &pi.dl_src, FALSE); + break; + + case COL_DEF_NET_SRC: + case COL_RES_NET_SRC: + col_set_addr(fd, i, &pi.net_src, TRUE); + break; + + case COL_UNRES_NET_SRC: + col_set_addr(fd, i, &pi.net_src, FALSE); + break; + + case COL_DEF_DST: + case COL_RES_DST: /* COL_DEF_DST is currently just like COL_RES_DST */ + col_set_addr(fd, i, &pi.dst, TRUE); + break; + + case COL_UNRES_DST: + col_set_addr(fd, i, &pi.dst, FALSE); + break; + + case COL_DEF_DL_DST: + case COL_RES_DL_DST: + col_set_addr(fd, i, &pi.dl_dst, TRUE); + break; + + case COL_UNRES_DL_DST: + col_set_addr(fd, i, &pi.dl_dst, FALSE); + break; + + case COL_DEF_NET_DST: + case COL_RES_NET_DST: + col_set_addr(fd, i, &pi.net_dst, TRUE); + break; + + case COL_UNRES_NET_DST: + col_set_addr(fd, i, &pi.net_dst, FALSE); + break; + + case COL_DEF_SRC_PORT: + case COL_RES_SRC_PORT: /* COL_DEF_SRC_PORT is currently just like COL_RES_SRC_PORT */ + col_set_port(fd, i, pi.ptype, pi.srcport, TRUE); + break; + + case COL_UNRES_SRC_PORT: + col_set_port(fd, i, pi.ptype, pi.srcport, FALSE); + break; + + case COL_DEF_DST_PORT: + case COL_RES_DST_PORT: /* COL_DEF_DST_PORT is currently just like COL_RES_DST_PORT */ + col_set_port(fd, i, pi.ptype, pi.destport, TRUE); + break; + + case COL_UNRES_DST_PORT: + col_set_port(fd, i, pi.ptype, pi.destport, FALSE); + break; + + case COL_PROTOCOL: /* currently done by dissectors */ + case COL_INFO: /* currently done by dissectors */ + break; + + case COL_PACKET_LENGTH: + snprintf(fd->cinfo->col_data[i], COL_MAX_LEN, "%d", fd->pkt_len); + break; + + case NUM_COL_FMTS: /* keep compiler happy - shouldn't get here */ + break; + } + } } static void @@ -1072,14 +1260,12 @@ change_time_formats(capture_file *cf) if (check_col(fd, COL_CLS_TIME)) { /* There are columns that show the time in the "command-line-specified" format; update them. */ - for (i = 0; i < cf->cinfo.num_cols; i++) { - cf->cinfo.col_data[i][0] = '\0'; - } - col_add_cls_time(fd); for (i = 0; i < cf->cinfo.num_cols; i++) { if (cf->cinfo.fmt_matx[i][COL_CLS_TIME]) { /* This is one of the columns that shows the time in "command-line-specified" format; update it. */ + cf->cinfo.col_data[i][0] = '\0'; + col_set_cls_time(fd, i); gtk_clist_set_text(GTK_CLIST(packet_list), fd->row, i, cf->cinfo.col_data[i]); } diff --git a/follow.c b/follow.c index 215c677abc4..e24b495eb80 100644 --- a/follow.c +++ b/follow.c @@ -1,6 +1,6 @@ /* follow.c * - * $Id: follow.c,v 1.15 1999/09/09 02:42:25 gram Exp $ + * $Id: follow.c,v 1.16 1999/10/22 07:17:29 guy Exp $ * * Copyright 1998 Mike Hall * @@ -50,7 +50,7 @@ extern FILE* data_out_file; gboolean incomplete_tcp_stream = FALSE; -static u_long ip_address[2]; +static guint32 ip_address[2]; static u_int tcp_port[2]; static int check_fragments( int ); @@ -63,20 +63,21 @@ static void write_packet_data( const u_char *, int ); char* build_follow_filter( packet_info *pi ) { char* buf = malloc(1024); - if( pi->ipproto == 6 ) { - /* TCP */ + if( pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4 + && pi->ipproto == 6 ) { + /* TCP over IPv4 */ sprintf( buf, "(ip.addr eq %s and ip.addr eq %s) and (tcp.port eq %d and tcp.port eq %d)", - ip_to_str( (guint8 *) &pi->ip_src), - ip_to_str( (guint8 *) &pi->ip_dst), + ip_to_str( pi->net_src.data), + ip_to_str( pi->net_dst.data), pi->srcport, pi->destport ); } else { free( buf ); return NULL; } - ip_address[0] = pi->ip_src; - ip_address[1] = pi->ip_dst; + memcpy(&ip_address[0], pi->net_src.data, sizeof ip_address[0]); + memcpy(&ip_address[1], pi->net_dst.data, sizeof ip_address[1]); tcp_port[0] = pi->srcport; tcp_port[1] = pi->destport; return buf; @@ -88,16 +89,23 @@ build_follow_filter( packet_info *pi ) { static tcp_frag *frags[2] = { 0, 0}; static u_long seq[2]; -static u_long src[2] = { 0, 0 }; +static guint32 src[2] = { 0, 0 }; void -reassemble_tcp( u_long sequence, u_long length, const char* data, u_long data_length, int synflag, u_long srcx, u_long dstx, u_int srcport, u_int dstport ) { +reassemble_tcp( u_long sequence, u_long length, const char* data, + u_long data_length, int synflag, address *net_src, + address *net_dst, u_int srcport, u_int dstport ) { + guint32 srcx, dstx; int src_index, j, first = 0; u_long newseq; tcp_frag *tmp_frag; src_index = -1; /* first check if this packet should be processed */ + if (net_src->type != AT_IPv4 || net_dst->type != AT_IPv4) + return; + memcpy(&srcx, net_src->data, sizeof srcx); + memcpy(&dstx, net_dst->data, sizeof dstx); if ((srcx != ip_address[0] && srcx != ip_address[1]) || (dstx != ip_address[0] && dstx != ip_address[1]) || (srcport != tcp_port[0] && srcport != tcp_port[1]) || diff --git a/follow.h b/follow.h index bce8e0a6755..15b798aa6a5 100644 --- a/follow.h +++ b/follow.h @@ -1,6 +1,6 @@ /* follow.h * - * $Id: follow.h,v 1.5 1999/07/31 13:55:16 deniel Exp $ + * $Id: follow.h,v 1.6 1999/10/22 07:17:29 guy Exp $ * * Copyright 1998 Mike Hall * @@ -42,7 +42,7 @@ typedef struct _tcp_frag { char* build_follow_filter( packet_info * ); void reassemble_tcp( u_long, u_long, const char*, u_long, int, - u_long, u_long, u_int, u_int ); + address *, address *, u_int, u_int ); void reset_tcp_reassembly( void ); #endif diff --git a/gtk/main.c b/gtk/main.c index 46ec957cfcc..9d5bb4a674d 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1,6 +1,6 @@ /* main.c * - * $Id: main.c,v 1.26 1999/10/22 06:31:07 guy Exp $ + * $Id: main.c,v 1.27 1999/10/22 07:18:23 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -519,14 +519,6 @@ file_quit_cmd_cb (GtkWidget *widget, gpointer data) { gtk_exit(0); } -void blank_packetinfo() { - pi.ip_src = 0; - pi.ip_dst = 0; - pi.ipproto = 0; - pi.srcport = 0; - pi.destport = 0; -} - /* call initialization routines at program startup time */ static void ethereal_proto_init(void) { diff --git a/packet-afs.c b/packet-afs.c index b3f9240bb9f..3d0301dc3fd 100644 --- a/packet-afs.c +++ b/packet-afs.c @@ -6,7 +6,7 @@ * Portions based on information retrieved from the RX definitions * in Arla, the free AFS client at http://www.stacken.kth.se/project/arla/ * - * $Id: packet-afs.c,v 1.1 1999/10/20 16:41:17 gram Exp $ + * $Id: packet-afs.c,v 1.2 1999/10/22 07:17:30 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -46,6 +46,7 @@ #include #include #include "packet.h" +#include "conversation.h" #include "packet-rx.h" #include "packet-afs.h" #include "resolv.h" @@ -377,8 +378,8 @@ static const value_string volume_types[] = { int afs_packet_init_count = 100; struct afs_request_key { - guint32 ip_src, ip_dst, callnumber; - guint16 port_src, port_dst, service; + guint32 conversation, callnumber; + guint16 service; }; struct afs_request_val { @@ -574,11 +575,8 @@ afs_equal(gconstpointer v, gconstpointer w) struct afs_request_key *v1 = (struct afs_request_key *)v; struct afs_request_key *v2 = (struct afs_request_key *)w; - if (v1 -> ip_src == v2 -> ip_src && - v1 -> ip_dst == v2 -> ip_dst && - v1 -> port_src == v2 -> port_src && - v1 -> port_dst == v2 -> port_dst && - v1 -> service == v2 -> service && + if (v1 -> conversation == v2 -> conversation && + v1 -> service == v2 -> service && v1 -> callnumber == v2 -> callnumber ) { return 1; @@ -593,9 +591,7 @@ afs_hash (gconstpointer v) struct afs_request_key *key = (struct afs_request_key *)v; guint val; - val = key -> ip_src + key -> ip_dst + - key -> port_src + key -> port_dst + - key -> service + key -> callnumber; + val = key -> conversation + key -> service + key -> callnumber; return val; } @@ -659,10 +655,22 @@ dissect_afs(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) reply = (rxh->flags & RX_CLIENT_INITIATED) == 0; port = ((reply == 0) ? pi.destport : pi.srcport ); - request_key.ip_src = ((reply == 0) ? pi.ip_src : pi.ip_dst); - request_key.ip_dst = ((reply == 0) ? pi.ip_dst : pi.ip_src); - request_key.port_src = ((reply == 0) ? pi.srcport : pi.destport); - request_key.port_dst = ((reply == 0) ? pi.destport : pi.srcport); + /* + * Find out what conversation this packet is part of, or add it to a + * new conversation if it's not already part of one. + * XXX - this should really be done by the transport-layer protocol, + * although for connectionless transports, we may not want to do that + * unless we know some higher-level protocol will want it - or we + * may want to do it, so you can say e.g. "show only the packets in + * this UDP 'connection'". + * + * Note that we don't have to worry about the direction this packet + * was going - the conversation code handles that for us, treating + * packets from A:X to B:Y as being part of the same conversation as + * packets from B:Y to A:X. + */ + request_key.conversation = add_to_conversation(&pi.src, &pi.dst, + pi.ptype, pi.srcport, pi.destport); request_key.service = ntohs(rxh->serviceId); request_key.callnumber = ntohl(rxh->callNumber); diff --git a/packet-eth.c b/packet-eth.c index d8f357ac0eb..7ce9437ed64 100644 --- a/packet-eth.c +++ b/packet-eth.c @@ -1,7 +1,7 @@ /* packet-eth.c * Routines for ethernet packet disassembly * - * $Id: packet-eth.c,v 1.20 1999/10/12 06:20:04 gram Exp $ + * $Id: packet-eth.c,v 1.21 1999/10/22 07:17:31 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -118,14 +118,11 @@ dissect_eth(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { return; } - if (check_col(fd, COL_RES_DL_DST)) - col_add_str(fd, COL_RES_DL_DST, get_ether_name((u_char *)&pd[offset+0])); - if (check_col(fd, COL_RES_DL_SRC)) - col_add_str(fd, COL_RES_DL_SRC, get_ether_name((u_char *)&pd[offset+6])); - if (check_col(fd, COL_UNRES_DL_DST)) - col_add_str(fd, COL_UNRES_DL_DST, ether_to_str((u_char *)&pd[offset+0])); - if (check_col(fd, COL_UNRES_DL_SRC)) - col_add_str(fd, COL_UNRES_DL_SRC, ether_to_str((u_char *)&pd[offset+6])); + SET_ADDRESS(&pi.dl_src, AT_ETHER, 6, &pd[offset+6]); + SET_ADDRESS(&pi.src, AT_ETHER, 6, &pd[offset+6]); + SET_ADDRESS(&pi.dl_dst, AT_ETHER, 6, &pd[offset+0]); + SET_ADDRESS(&pi.dst, AT_ETHER, 6, &pd[offset+0]); + if (check_col(fd, COL_PROTOCOL)) col_add_str(fd, COL_PROTOCOL, "Ethernet"); diff --git a/packet-fddi.c b/packet-fddi.c index e5513a7b77d..6f9538bb14a 100644 --- a/packet-fddi.c +++ b/packet-fddi.c @@ -3,7 +3,7 @@ * * Laurent Deniel * - * $Id: packet-fddi.c,v 1.23 1999/10/16 19:36:56 deniel Exp $ + * $Id: packet-fddi.c,v 1.24 1999/10/22 07:17:31 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -254,7 +254,7 @@ void dissect_fddi(const u_char *pd, frame_data *fd, proto_tree *tree, proto_tree *fh_tree; proto_item *ti; gchar *fc_str; - u_char src[6], dst[6]; + static u_char src[6], dst[6]; u_char src_swapped[6], dst_swapped[6]; if (fd->cap_len < FDDI_HEADER_SIZE) { @@ -275,14 +275,13 @@ void dissect_fddi(const u_char *pd, frame_data *fd, proto_tree *tree, fc = (int) pd[FDDI_P_FC]; fc_str = fddifc_to_str(fc); - if (check_col(fd, COL_RES_DL_SRC)) - col_add_str(fd, COL_RES_DL_SRC, get_ether_name(src)); - if (check_col(fd, COL_RES_DL_DST)) - col_add_str(fd, COL_RES_DL_DST, get_ether_name(dst)); - if (check_col(fd, COL_UNRES_DL_SRC)) - col_add_str(fd, COL_UNRES_DL_SRC, ether_to_str(src)); - if (check_col(fd, COL_UNRES_DL_DST)) - col_add_str(fd, COL_UNRES_DL_DST, ether_to_str(dst)); + /* XXX - copy them to some buffer associated with "pi", rather than + just making "src" and "dst" static? */ + SET_ADDRESS(&pi.dl_src, AT_ETHER, 6, &src[0]); + SET_ADDRESS(&pi.src, AT_ETHER, 6, &src[0]); + SET_ADDRESS(&pi.dl_dst, AT_ETHER, 6, &dst[0]); + SET_ADDRESS(&pi.dst, AT_ETHER, 6, &dst[0]); + if (check_col(fd, COL_PROTOCOL)) col_add_str(fd, COL_PROTOCOL, "FDDI"); if (check_col(fd, COL_INFO)) diff --git a/packet-ip.c b/packet-ip.c index c07d70884e8..91aa23150b6 100644 --- a/packet-ip.c +++ b/packet-ip.c @@ -1,7 +1,7 @@ /* packet-ip.c * Routines for IP and miscellaneous IP protocol packet disassembly * - * $Id: packet-ip.c,v 1.57 1999/10/22 03:52:06 guy Exp $ + * $Id: packet-ip.c,v 1.58 1999/10/22 07:17:32 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -173,6 +173,18 @@ typedef struct _e_ip { guint32 ip_dst; } e_ip; +/* Offsets of fields within an IP header. */ +#define IPH_V_HL 0 +#define IPH_TOS 1 +#define IPH_LEN 2 +#define IPH_ID 4 +#define IPH_TTL 6 +#define IPH_OFF 8 +#define IPH_P 9 +#define IPH_SUM 10 +#define IPH_SRC 12 +#define IPH_DST 16 + /* Minimum IP header length. */ #define IPH_MIN_LEN 20 @@ -730,15 +742,6 @@ dissect_ip(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { ipprotostr(iph.ip_p), iph.ip_p); } - if (check_col(fd, COL_RES_NET_SRC)) - col_add_str(fd, COL_RES_NET_SRC, get_hostname(iph.ip_src)); - if (check_col(fd, COL_UNRES_NET_SRC)) - col_add_str(fd, COL_UNRES_NET_SRC, ip_to_str((guint8 *) &iph.ip_src)); - if (check_col(fd, COL_RES_NET_DST)) - col_add_str(fd, COL_RES_NET_DST, get_hostname(iph.ip_dst)); - if (check_col(fd, COL_UNRES_NET_DST)) - col_add_str(fd, COL_UNRES_NET_DST, ip_to_str((guint8 *) &iph.ip_dst)); - if (tree) { switch (IPTOS_TOS(iph.ip_tos)) { @@ -832,8 +835,10 @@ dissect_ip(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { pi.ipproto = iph.ip_p; pi.iplen = iph.ip_len; pi.iphdrlen = lo_nibble(iph.ip_v_hl); - pi.ip_src = iph.ip_src; - pi.ip_dst = iph.ip_dst; + SET_ADDRESS(&pi.net_src, AT_IPv4, 4, &pd[offset + IPH_SRC]); + SET_ADDRESS(&pi.src, AT_IPv4, 4, &pd[offset + IPH_SRC]); + SET_ADDRESS(&pi.net_dst, AT_IPv4, 4, &pd[offset + IPH_DST]); + SET_ADDRESS(&pi.dst, AT_IPv4, 4, &pd[offset + IPH_DST]); /* Skip over header + options */ offset += hlen; diff --git a/packet-ipv6.c b/packet-ipv6.c index 382d4666e74..4622ca7bc41 100644 --- a/packet-ipv6.c +++ b/packet-ipv6.c @@ -1,7 +1,7 @@ /* packet-ipv6.c * Routines for IPv6 packet disassembly * - * $Id: packet-ipv6.c,v 1.23 1999/10/15 16:59:12 itojun Exp $ + * $Id: packet-ipv6.c,v 1.24 1999/10/22 07:17:32 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -252,16 +252,13 @@ dissect_ipv6(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { memcpy(&ipv6, (void *) &pd[offset], sizeof(ipv6)); + SET_ADDRESS(&pi.net_src, AT_IPv6, 16, &pd[offset + IP6H_SRC]); + SET_ADDRESS(&pi.src, AT_IPv6, 16, &pd[offset + IP6H_SRC]); + SET_ADDRESS(&pi.net_dst, AT_IPv6, 16, &pd[offset + IP6H_DST]); + SET_ADDRESS(&pi.dst, AT_IPv6, 16, &pd[offset + IP6H_DST]); + if (check_col(fd, COL_PROTOCOL)) col_add_str(fd, COL_PROTOCOL, "IPv6"); - if (check_col(fd, COL_RES_NET_SRC)) - col_add_str(fd, COL_RES_NET_SRC, get_hostname6(&ipv6.ip6_src)); - if (check_col(fd, COL_UNRES_NET_SRC)) - col_add_str(fd, COL_UNRES_NET_SRC, ip6_to_str(&ipv6.ip6_src)); - if (check_col(fd, COL_RES_NET_DST)) - col_add_str(fd, COL_RES_NET_DST, get_hostname6(&ipv6.ip6_dst)); - if (check_col(fd, COL_UNRES_NET_DST)) - col_add_str(fd, COL_UNRES_NET_DST, ip6_to_str(&ipv6.ip6_dst)); if (tree) { /* !!! specify length */ diff --git a/packet-ipv6.h b/packet-ipv6.h index f451de7b533..70ae4ecb812 100644 --- a/packet-ipv6.h +++ b/packet-ipv6.h @@ -1,7 +1,7 @@ /* packet-ipv6.h * Definitions for IPv6 packet disassembly * - * $Id: packet-ipv6.h,v 1.6 1999/10/14 05:41:30 itojun Exp $ + * $Id: packet-ipv6.h,v 1.7 1999/10/22 07:17:33 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -86,6 +86,16 @@ struct ip6_hdr { #define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim #define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim +/* Offsets of fields within an IPv6 header. */ +#define IP6H_CTL 0 +#define IP6H_CTL_FLOW 0 +#define IP6H_CTL_PLEN 4 +#define IP6H_CTL_NXT 6 +#define IP6H_CTL_HLIM 7 +#define IP6H_CTL_VFC 0 +#define IP6H_SRC 8 +#define IP6H_DST 24 + #define IPV6_VERSION 0x60 #define IPV6_VERSION_MASK 0xf0 diff --git a/packet-ipx.c b/packet-ipx.c index dbe30ab80d4..66a9a6f08de 100644 --- a/packet-ipx.c +++ b/packet-ipx.c @@ -2,7 +2,7 @@ * Routines for NetWare's IPX * Gilbert Ramirez * - * $Id: packet-ipx.c,v 1.29 1999/10/17 09:23:43 deniel Exp $ + * $Id: packet-ipx.c,v 1.30 1999/10/22 07:17:34 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -269,7 +269,7 @@ dissect_ipx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { ipx_length = pntohs(&pd[offset+2]); /* Length of IPX datagram plus headers above it. */ - len = ipx_length + offset; + len = ipx_length + offset; /* Set the payload and captured-payload lengths to the minima of (the IPX length plus the length of the headers above it) and @@ -279,12 +279,10 @@ dissect_ipx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { if (pi.captured_len > len) pi.captured_len = len; - if (check_col(fd, COL_RES_DL_DST)) - col_add_str(fd, COL_RES_DL_DST, - ipx_addr_to_str(pntohl(ipx_dnet), ipx_dnode)); - if (check_col(fd, COL_RES_DL_SRC)) - col_add_str(fd, COL_RES_DL_SRC, - ipx_addr_to_str(pntohl(ipx_snet), ipx_snode)); + SET_ADDRESS(&pi.net_src, AT_IPX, 10, &pd[offset+18]); + SET_ADDRESS(&pi.src, AT_IPX, 10, &pd[offset+18]); + SET_ADDRESS(&pi.net_dst, AT_IPX, 10, &pd[offset+6]); + SET_ADDRESS(&pi.dst, AT_IPX, 10, &pd[offset+6]); if (check_col(fd, COL_PROTOCOL)) col_add_str(fd, COL_PROTOCOL, "IPX"); diff --git a/packet-smb.c b/packet-smb.c index 5687033c142..1cf0188c585 100644 --- a/packet-smb.c +++ b/packet-smb.c @@ -2,7 +2,7 @@ * Routines for smb packet dissection * Copyright 1999, Richard Sharpe * - * $Id: packet-smb.c,v 1.30 1999/10/16 20:26:37 deniel Exp $ + * $Id: packet-smb.c,v 1.31 1999/10/22 07:17:37 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -42,6 +42,7 @@ #include #include #include "packet.h" +#include "conversation.h" #include "smb.h" #include "alignment.h" @@ -60,8 +61,7 @@ char *decode_smb_name(unsigned char); int smb_packet_init_count = 200; struct smb_request_key { - guint32 ip_src, ip_dst; - guint16 port_src, port_dst; + guint32 conversation; guint16 mid; }; @@ -81,17 +81,14 @@ smb_equal(gconstpointer v, gconstpointer w) struct smb_request_key *v1 = (struct smb_request_key *)v; struct smb_request_key *v2 = (struct smb_request_key *)w; - #if defined(DEBUG_SMB_HASH) - printf("Comparing %08X:%08X:%d:%d:%d\n and %08X:%08X:%d:%d:%d\n", - v1 -> ip_src, v1 -> ip_dst, v1 -> port_src, v1 -> port_dst, v1 -> mid, - v2 -> ip_src, v2 -> ip_dst, v2 -> port_src, v2 -> port_dst, v2 -> mid); - #endif +#if defined(DEBUG_SMB_HASH) + printf("Comparing %08X:%u\n and %08X:%u\n", + v1 -> conversation, v1 -> mid, + v2 -> conversation, v2 -> mid); +#endif - if (v1 -> ip_src == v2 -> ip_src && - v1 -> ip_dst == v2 -> ip_dst && - v1 -> port_src == v2 -> port_src && - v1 -> port_dst == v2 -> port_dst && - v1 -> mid == v2 -> mid) { + if (v1 -> conversation == v2 -> conversation && + v1 -> mid == v2 -> mid) { return 1; @@ -106,12 +103,11 @@ smb_hash (gconstpointer v) struct smb_request_key *key = (struct smb_request_key *)v; guint val; - val = key -> ip_src + key -> ip_dst + key -> port_src + key -> port_dst + - key -> mid; + val = key -> conversation + key -> mid; - #if defined(DEBUG_SMB_HASH) - printf("SMB Hash calculated as %d\n", val); - #endif +#if defined(DEBUG_SMB_HASH) + printf("SMB Hash calculated as %u\n", val); +#endif return val; @@ -124,9 +120,9 @@ smb_hash (gconstpointer v) void smb_init_protocol(void) { - #if defined(DEBUG_SMB_HASH) +#if defined(DEBUG_SMB_HASH) printf("Initializing SMB hashtable area\n"); - #endif +#endif if (smb_request_hash) g_hash_table_destroy(smb_request_hash); @@ -8179,6 +8175,7 @@ char *decode_trans2_name(int code) return trans2_cmd_names[code]; } + void dissect_transact2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree *tree, struct smb_info si, int max_data, int SMB_offset, int errcode, int dirn) @@ -8211,31 +8208,40 @@ dissect_transact2_smb(const u_char *pd, int offset, frame_data *fd, proto_tree * guint16 DataCount; guint16 ByteCount; const char *TransactName; + guint32 conversation; struct smb_request_key request_key, *new_request_key; struct smb_request_val *request_val; /* - * Check for and insert entry in hash table if does not exist - * Since we want request and response to hash to the same, we make - * sure that src and dst swapped for response + * Find out what conversation this packet is part of, or add it to a + * new conversation if it's not already part of one. + * XXX - this should really be done by the transport-layer protocol, + * although for connectionless transports, we may not want to do that + * unless we know some higher-level protocol will want it - or we + * may want to do it, so you can say e.g. "show only the packets in + * this UDP 'connection'". + * + * Note that we don't have to worry about the direction this packet + * was going - the conversation code handles that for us, treating + * packets from A:X to B:Y as being part of the same conversation as + * packets from B:Y to A:X. */ + conversation = add_to_conversation(&pi.src, &pi.dst, pi.ptype, + pi.srcport, pi.destport); - request_key.ip_src = ((dirn == 0) ? pi.ip_src : pi.ip_dst); - request_key.ip_dst = ((dirn == 0) ? pi.ip_dst : pi.ip_src); - request_key.port_src = ((dirn == 0) ? pi.srcport : pi.destport); - request_key.port_dst = ((dirn == 0) ? pi.destport : pi.srcport); - request_key.mid = si.mid; + /* + * Check for and insert entry in request hash table if does not exist + */ + request_key.conversation = conversation; + request_key.mid = si.mid; request_val = (struct smb_request_val *) g_hash_table_lookup(smb_request_hash, &request_key); if (!request_val) { /* Create one */ new_request_key = g_mem_chunk_alloc(smb_request_keys); - new_request_key -> ip_src = ((dirn == 0) ? pi.ip_src : pi.ip_dst); - new_request_key -> ip_dst = ((dirn == 0) ? pi.ip_dst : pi.ip_src); - new_request_key -> port_src = ((dirn == 0) ? pi.srcport : pi.destport); - new_request_key -> port_dst = ((dirn == 0) ? pi.destport : pi.srcport); - new_request_key -> mid = si.mid; + new_request_key -> conversation = conversation; + new_request_key -> mid = si.mid; request_val = g_mem_chunk_alloc(smb_request_vals); request_val -> mid = si.mid; diff --git a/packet-sna.c b/packet-sna.c index 130f464c969..63b7f06af29 100644 --- a/packet-sna.c +++ b/packet-sna.c @@ -2,7 +2,7 @@ * Routines for SNA * Gilbert Ramirez * - * $Id: packet-sna.c,v 1.5 1999/10/21 04:35:40 gram Exp $ + * $Id: packet-sna.c,v 1.6 1999/10/22 07:17:41 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -409,14 +409,10 @@ dissect_fid0_1 (const u_char *pd, int offset, frame_data *fd, proto_tree *tree) snf = pntohs(&pd[offset+6]); dcf = pntohs(&pd[offset+8]); - if (check_col(fd, COL_RES_NET_DST)) - col_add_fstr(fd, COL_RES_NET_DST, "%04X", daf); - if (check_col(fd, COL_UNRES_NET_DST)) - col_add_fstr(fd, COL_UNRES_NET_DST, "%04X", daf); - if (check_col(fd, COL_RES_NET_SRC)) - col_add_fstr(fd, COL_RES_NET_SRC, "%04X", oaf); - if (check_col(fd, COL_UNRES_NET_SRC)) - col_add_fstr(fd, COL_UNRES_NET_SRC, "%04X", oaf); + SET_ADDRESS(&pi.net_src, AT_SNA, 2, &pd[offset+4]); + SET_ADDRESS(&pi.src, AT_SNA, 2, &pd[offset+4]); + SET_ADDRESS(&pi.net_dst, AT_SNA, 2, &pd[offset+2]); + SET_ADDRESS(&pi.dst, AT_SNA, 2, &pd[offset+2]); if (!tree) { return bytes_in_header; @@ -461,14 +457,10 @@ dissect_fid2 (const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { oaf = pd[offset+3]; /* Addresses in FID 2 are FT_UINT8 */ - if (check_col(fd, COL_RES_NET_DST)) - col_add_fstr(fd, COL_RES_NET_DST, "%02X", daf); - if (check_col(fd, COL_UNRES_NET_DST)) - col_add_fstr(fd, COL_UNRES_NET_DST, "%02X", daf); - if (check_col(fd, COL_RES_NET_SRC)) - col_add_fstr(fd, COL_RES_NET_SRC, "%02X", oaf); - if (check_col(fd, COL_RES_NET_SRC)) - col_add_fstr(fd, COL_UNRES_NET_SRC, "%02X", oaf); + SET_ADDRESS(&pi.net_src, AT_SNA, 1, &pd[offset+3]); + SET_ADDRESS(&pi.src, AT_SNA, 1, &pd[offset+3]); + SET_ADDRESS(&pi.net_dst, AT_SNA, 1, &pd[offset+2]); + SET_ADDRESS(&pi.dst, AT_SNA, 1, &pd[offset+2]); if (!tree) { return bytes_in_header; diff --git a/packet-tcp.c b/packet-tcp.c index 7899189f8e8..597a418e60c 100644 --- a/packet-tcp.c +++ b/packet-tcp.c @@ -1,7 +1,7 @@ /* packet-tcp.c * Routines for TCP packet disassembly * - * $Id: packet-tcp.c,v 1.37 1999/10/15 17:00:46 itojun Exp $ + * $Id: packet-tcp.c,v 1.38 1999/10/22 07:17:42 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -381,14 +381,6 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { hlen = hi_nibble(th.th_off_x2) * 4; /* TCP header length, in bytes */ - if (check_col(fd, COL_RES_SRC_PORT)) - col_add_str(fd, COL_RES_SRC_PORT, get_tcp_port(th.th_sport)); - if (check_col(fd, COL_UNRES_SRC_PORT)) - col_add_fstr(fd, COL_UNRES_SRC_PORT, "%u", th.th_sport); - if (check_col(fd, COL_RES_DST_PORT)) - col_add_str(fd, COL_RES_DST_PORT, get_tcp_port(th.th_dport)); - if (check_col(fd, COL_UNRES_DST_PORT)) - col_add_fstr(fd, COL_UNRES_DST_PORT, "%u", th.th_dport); if (check_col(fd, COL_PROTOCOL)) col_add_str(fd, COL_PROTOCOL, "TCP"); if (check_col(fd, COL_INFO)) { @@ -463,6 +455,7 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { /* Skip over header + options */ offset += hlen; + pi.ptype = PT_TCP; pi.srcport = th.th_sport; pi.destport = th.th_dport; @@ -529,8 +522,8 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { ( pd+offset ), /* data */ ( pi.captured_len - offset ), /* captured data length */ ( th.th_flags & TH_SYN ), /* is syn set? */ - pi.ip_src, - pi.ip_dst, + &pi.net_src, + &pi.net_dst, pi.srcport, pi.destport); } diff --git a/packet-tr.c b/packet-tr.c index c1c1227791e..f29ead77c32 100644 --- a/packet-tr.c +++ b/packet-tr.c @@ -2,7 +2,7 @@ * Routines for Token-Ring packet disassembly * Gilbert Ramirez * - * $Id: packet-tr.c,v 1.29 1999/10/12 06:20:18 gram Exp $ + * $Id: packet-tr.c,v 1.30 1999/10/22 07:17:43 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -285,7 +285,7 @@ dissect_tr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { guint16 trn_rseg[8]; /* routing registers */ /* non-source-routed version of source addr */ - guint8 trn_shost_nonsr[6]; + static guint8 trn_shost_nonsr[6]; int x; /* Token-Ring Strings */ @@ -397,12 +397,14 @@ dissect_tr(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { } } + /* XXX - copy it to some buffer associated with "pi", rather than + just making "trn_shost_nonsr" static? */ + SET_ADDRESS(&pi.dl_src, AT_ETHER, 6, &trn_shost_nonsr[0]); + SET_ADDRESS(&pi.src, AT_ETHER, 6, &trn_shost_nonsr[0]); + SET_ADDRESS(&pi.dl_dst, AT_ETHER, 6, &pd[offset + 2]); + SET_ADDRESS(&pi.dst, AT_ETHER, 6, &pd[offset + 2]); + /* information window */ - if (check_col(fd, COL_RES_DL_DST)) - col_add_str(fd, COL_RES_DL_DST, - ether_to_str((guint8 *)&pd[offset + 2])); - if (check_col(fd, COL_RES_DL_SRC)) - col_add_str(fd, COL_RES_DL_SRC, ether_to_str(trn_shost_nonsr)); if (check_col(fd, COL_PROTOCOL)) col_add_str(fd, COL_PROTOCOL, "TR"); if (check_col(fd, COL_INFO)) diff --git a/packet-udp.c b/packet-udp.c index 30f165e6eb8..051fceb8efa 100644 --- a/packet-udp.c +++ b/packet-udp.c @@ -1,7 +1,7 @@ /* packet-udp.c * Routines for UDP packet disassembly * - * $Id: packet-udp.c,v 1.30 1999/10/20 16:41:19 gram Exp $ + * $Id: packet-udp.c,v 1.31 1999/10/22 07:17:45 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -196,14 +196,6 @@ dissect_udp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { if (check_col(fd, COL_INFO)) col_add_fstr(fd, COL_INFO, "Source port: %s Destination port: %s", get_udp_port(uh_sport), get_udp_port(uh_dport)); - if (check_col(fd, COL_RES_SRC_PORT)) - col_add_str(fd, COL_RES_SRC_PORT, get_udp_port(uh_sport)); - if (check_col(fd, COL_UNRES_SRC_PORT)) - col_add_fstr(fd, COL_UNRES_SRC_PORT, "%u", uh_sport); - if (check_col(fd, COL_RES_DST_PORT)) - col_add_str(fd, COL_RES_DST_PORT, get_udp_port(uh_dport)); - if (check_col(fd, COL_UNRES_DST_PORT)) - col_add_fstr(fd, COL_UNRES_DST_PORT, "%u", uh_dport); if (tree) { ti = proto_tree_add_item(tree, proto_udp, offset, 8); @@ -225,53 +217,54 @@ dissect_udp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { /* Skip over header */ offset += 8; - pi.srcport = uh_sport; - pi.destport = uh_dport; + pi.ptype = PT_UDP; + pi.srcport = uh_sport; + pi.destport = uh_dport; /* XXX - we should do all of this through the table of ports. */ #define PORT_IS(port) (uh_sport == port || uh_dport == port) - if (PORT_IS(UDP_PORT_BOOTPS)) + if (PORT_IS(UDP_PORT_BOOTPS)) dissect_bootp(pd, offset, fd, tree); - else if (PORT_IS(UDP_PORT_DNS)) + else if (PORT_IS(UDP_PORT_DNS)) dissect_dns(pd, offset, fd, tree); - else if (PORT_IS(UDP_PORT_ISAKMP)) + else if (PORT_IS(UDP_PORT_ISAKMP)) dissect_isakmp(pd, offset, fd, tree); - else if (PORT_IS(UDP_PORT_RIP)) { + else if (PORT_IS(UDP_PORT_RIP)) { /* we should check the source port too (RIP: UDP src and dst port 520) */ dissect_rip(pd, offset, fd, tree); - } else if (PORT_IS(UDP_PORT_RIPNG)) + } else if (PORT_IS(UDP_PORT_RIPNG)) dissect_ripng(pd, offset, fd, tree); - else if (PORT_IS(UDP_PORT_NBNS)) + else if (PORT_IS(UDP_PORT_NBNS)) dissect_nbns(pd, offset, fd, tree); - else if (PORT_IS(UDP_PORT_NBDGM)) + else if (PORT_IS(UDP_PORT_NBDGM)) dissect_nbdgm(pd, offset, fd, tree); - else if (PORT_IS(UDP_PORT_NTP)) + else if (PORT_IS(UDP_PORT_NTP)) dissect_ntp(pd, offset, fd, tree); - else if (PORT_IS(UDP_PORT_IPX)) /* RFC 1234 */ + else if (PORT_IS(UDP_PORT_IPX)) /* RFC 1234 */ dissect_ipx(pd, offset, fd, tree); - else if ((uh_sport >= UDP_PORT_RX_LOW && uh_sport <= UDP_PORT_RX_HIGH) || + else if ((uh_sport >= UDP_PORT_RX_LOW && uh_sport <= UDP_PORT_RX_HIGH) || (uh_dport >= UDP_PORT_RX_LOW && uh_dport <= UDP_PORT_RX_HIGH) || PORT_IS(UDP_PORT_RX_AFS_BACKUPS)) dissect_rx(pd, offset, fd, tree); /* transarc AFS's RX protocol */ #if defined(HAVE_UCD_SNMP_SNMP_H) || defined(HAVE_SNMP_SNMP_H) - else if (PORT_IS(UDP_PORT_SNMP)) + else if (PORT_IS(UDP_PORT_SNMP)) dissect_snmp(pd, offset, fd, tree); #endif - else if (PORT_IS(UDP_PORT_VINES)) { + else if (PORT_IS(UDP_PORT_VINES)) { /* FIXME: AFAIK, src and dst port must be the same */ dissect_vines_frp(pd, offset, fd, tree); - } else if (PORT_IS(UDP_PORT_TFTP)) { + } else if (PORT_IS(UDP_PORT_TFTP)) { /* This is the first point of call, but it adds a dynamic call */ udp_hash_add(MAX(uh_sport, uh_dport), dissect_tftp); /* Add to table */ dissect_tftp(pd, offset, fd, tree); - } else if (PORT_IS(UDP_PORT_RADIUS) || + } else if (PORT_IS(UDP_PORT_RADIUS) || PORT_IS(UDP_PORT_RADACCT) || PORT_IS(UDP_PORT_RADIUS_NEW) || PORT_IS(UDP_PORT_RADACCT_NEW) ) { dissect_radius(pd, offset, fd, tree); - } else if ( PORT_IS(UDP_PORT_ICP)) { + } else if ( PORT_IS(UDP_PORT_ICP)) { dissect_icp(pd,offset,fd,tree); - } else { + } else { /* OK, find a routine in the table, else use the default */ if ((dissect_routine = udp_find_hash_ent(uh_sport))) { diff --git a/packet.c b/packet.c index 18a064749ab..71b996f033f 100644 --- a/packet.c +++ b/packet.c @@ -1,7 +1,7 @@ /* packet.c * Routines for packet disassembly * - * $Id: packet.c,v 1.50 1999/10/15 20:32:57 guy Exp $ + * $Id: packet.c,v 1.51 1999/10/22 07:17:45 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -682,6 +682,19 @@ col_append_str(frame_data *fd, gint el, gchar* str) { } } +void blank_packetinfo(void) +{ + pi.dl_src.type = AT_NONE; + pi.dl_dst.type = AT_NONE; + pi.net_src.type = AT_NONE; + pi.net_dst.type = AT_NONE; + pi.src.type = AT_NONE; + pi.dst.type = AT_NONE; + pi.ipproto = 0; + pi.ptype = PT_NONE; + pi.srcport = 0; + pi.destport = 0; +} /* this routine checks the frame type from the cf structure */ void @@ -722,6 +735,8 @@ dissect_packet(const u_char *pd, frame_data *fd, proto_tree *tree) plurality(fd->cap_len, "", "s")); } + blank_packetinfo(); + /* Set the initial payload to the packet length, and the initial captured payload to the capture length (other protocols may reduce them if their headers say they're less). */ diff --git a/packet.h b/packet.h index 6fcd40f871c..defb96de961 100644 --- a/packet.h +++ b/packet.h @@ -1,7 +1,7 @@ /* packet.h * Definitions for packet disassembly structures and routines * - * $Id: packet.h,v 1.116 1999/10/20 22:41:12 guy Exp $ + * $Id: packet.h,v 1.117 1999/10/22 07:17:47 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -106,6 +106,12 @@ typedef struct _packet_counts { gint total; } packet_counts; +/* XXX - some of this stuff is used only while a packet is being dissected; + should we keep around a separate data structure for that, to save + memory? + + Also, should the pseudo-header be supplied by Wiretap when you do a + seek-and-read, so that we don't have to save it for all frames? */ typedef struct _frame_data { struct _frame_data *next; /* Next element in list */ guint32 num; /* Frame number */ @@ -125,17 +131,51 @@ typedef struct _frame_data { union pseudo_header pseudo_header; /* "pseudo-header" from wiretap */ } frame_data; +/* Types of addresses Ethereal knows about. */ +typedef enum { + AT_NONE, /* no link-layer address */ + AT_ETHER, /* MAC (Ethernet, 802.x, FDDI) address */ + AT_IPv4, /* IPv4 */ + AT_IPv6, /* IPv6 */ + AT_IPX, /* IPX */ + AT_SNA /* SNA */ +} address_type; + +typedef struct _address { + address_type type; /* type of address */ + int len; /* length of address, in bytes */ + const guint8 *data; /* bytes that constitute address */ +} address; + +#define SET_ADDRESS(addr, addr_type, addr_len, addr_data) { \ + (addr)->type = (addr_type); \ + (addr)->len = (addr_len); \ + (addr)->data = (addr_data); \ + } + +/* Types of port numbers Ethereal knows about. */ +typedef enum { + PT_NONE, /* no port number */ + PT_TCP, /* TCP */ + PT_UDP /* UDP */ +} port_type; + typedef struct _packet_info { - int len; - int captured_len; - guint32 ip_src; - guint32 ip_dst; + int len; + int captured_len; + address dl_src; /* link-layer source address */ + address dl_dst; /* link-layer destination address */ + address net_src; /* network-layer source address */ + address net_dst; /* network-layer destination address */ + address src; /* source address (net if present, DL otherwise )*/ + address dst; /* destination address (net if present, DL otherwise )*/ guint32 ipproto; - guint32 srcport; - guint32 destport; + port_type ptype; /* type of the following two port numbers */ + guint32 srcport; /* source port */ + guint32 destport; /* destination port */ guint32 match_port; - int iplen; - int iphdrlen; + int iplen; + int iphdrlen; } packet_info; extern packet_info pi; @@ -387,6 +427,7 @@ gchar* ether_to_str(const guint8 *); gchar* ip_to_str(const guint8 *); struct e_in6_addr; gchar* ip6_to_str(struct e_in6_addr *); +gchar* ipx_addr_to_str(guint32, const guint8 *); gchar* abs_time_to_str(struct timeval*); gchar* rel_time_to_str(struct timeval*); gchar* time_secs_to_str(guint32); @@ -418,11 +459,13 @@ void col_append_fstr(frame_data *, gint, gchar *, ...); void col_add_str(frame_data *, gint, const gchar *); void col_append_str(frame_data *, gint, gchar *); +void blank_packetinfo(void); void afs_init_protocol(void); void smb_init_protocol(void); void dissect_packet(const u_char *, frame_data *, proto_tree *); + /* * Routines in packet-*.c * Routines should take three args: packet data *, cap_len, packet_counts * diff --git a/resolv.c b/resolv.c index 62c84a1fac1..6955a9ddf1f 100644 --- a/resolv.c +++ b/resolv.c @@ -1,7 +1,7 @@ /* resolv.c * Routines for network object lookup * - * $Id: resolv.c,v 1.15 1999/10/14 06:55:10 guy Exp $ + * $Id: resolv.c,v 1.16 1999/10/22 07:17:50 guy Exp $ * * Laurent Deniel * @@ -484,7 +484,7 @@ static ether_t *get_ethbyname(u_char *name) } /* get_ethbyname */ -static ether_t *get_ethbyaddr(u_char *addr) +static ether_t *get_ethbyaddr(const u_char *addr) { ether_t *eth; @@ -538,7 +538,7 @@ static void add_manuf_name(u_char *addr, u_char *name) } /* add_manuf_name */ -static hashmanuf_t *manuf_name_lookup(u_char *addr) +static hashmanuf_t *manuf_name_lookup(const u_char *addr) { hashmanuf_t *tp; @@ -591,7 +591,7 @@ static hashether_t *add_eth_name(u_char *addr, u_char *name) } /* add_eth_name */ -static u_char *eth_name_lookup(u_char *addr) +static u_char *eth_name_lookup(const u_char *addr) { hashmanuf_t *manufp; hashether_t *tp; @@ -795,7 +795,7 @@ extern u_char *get_tcp_port(u_int port) } /* get_tcp_port */ -extern u_char *get_ether_name(u_char *addr) +extern u_char *get_ether_name(const u_char *addr) { if (!g_resolving_actif) return ether_to_str((guint8 *)addr); diff --git a/resolv.h b/resolv.h index dffa493276d..9453449981b 100644 --- a/resolv.h +++ b/resolv.h @@ -1,7 +1,7 @@ /* resolv.h * Definitions for network object lookup * - * $Id: resolv.h,v 1.8 1999/10/15 03:11:52 itojun Exp $ + * $Id: resolv.h,v 1.9 1999/10/22 07:17:51 guy Exp $ * * Laurent Deniel * @@ -60,7 +60,7 @@ gchar* get_hostname6(struct e_in6_addr *ad); /* get_ether_name returns the logical name if found in ethers files else "_%02x:%02x:%02x" if the vendor code is known else "%02x:%02x:%02x:%02x:%02x:%02x" */ -extern u_char *get_ether_name(u_char *addr); +extern u_char *get_ether_name(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);