From 47d5cfab522706c1cadfb1598325a44e77f56815 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Thu, 24 Aug 2000 06:19:53 +0000 Subject: [PATCH] Instead of keeping in the information about an RPC call a count of the number of replies seen, keep the frame number of the first request seen for that call and the first reply seen for that call. Use that to determine whether a request or reply is a duplicate or not. That means that we don't have to reset the table of RPC calls on a rescan of the capture (which didn't even fix all the cases where we'd have misreported the original call or reply as a duplicate due to having seen it once on the initial pass through the file and once again when, for example, the user clicked on the packet); doing so causes plenty of other problems, so don't do that - and don't clear the "visited" flag on frames on a rescan, either, as that's only done because we were clearing out conversations and calling all protocols' "init" routines. As a free bonus, this means that, for a reply, we know what frame the request was in; put that information into the protocol tree for the reply, snoop-style. Make the table of RPC call information, and the routines that manipulate it, static to "packet-rpc.c"; nobody outside "packet-rpc.c" uses them. svn path=/trunk/; revision=2358 --- file.c | 15 +--------- packet-rpc.c | 82 ++++++++++++++++++++++++++++++++++++++-------------- packet-rpc.h | 20 +------------ 3 files changed, 62 insertions(+), 55 deletions(-) diff --git a/file.c b/file.c index b521d3e220..e569562dfa 100644 --- a/file.c +++ b/file.c @@ -1,7 +1,7 @@ /* file.c * File I/O routines * - * $Id: file.c,v 1.209 2000/08/21 21:24:01 deniel Exp $ + * $Id: file.c,v 1.210 2000/08/24 06:19:51 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -892,15 +892,6 @@ rescan_packets(capture_file *cf, const char *action, gboolean refilter) rebuild the clist, however. */ selected_row = -1; - /* We need to re-initialize all the state information that protocols - keep, because we're making a fresh pass through all the packets. */ - - /* Initialize the table of conversations. */ - conversation_init(); - - /* Initialize protocol-specific variables */ - init_all_protocols(); - /* Freeze the packet list while we redo it, so we don't get any screen updates while it happens. */ gtk_clist_freeze(GTK_CLIST(packet_list)); @@ -966,10 +957,6 @@ rescan_packets(capture_file *cf, const char *action, gboolean refilter) count++; - /* Since all state for the frame was destroyed, mark the frame - * as not visited. */ - fdata->flags.visited = 0; - wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header, cf->pd, fdata->cap_len); diff --git a/packet-rpc.c b/packet-rpc.c index 7fa88009f0..84727505c4 100644 --- a/packet-rpc.c +++ b/packet-rpc.c @@ -2,7 +2,7 @@ * Routines for rpc dissection * Copyright 1999, Uwe Girlich * - * $Id: packet-rpc.c,v 1.37 2000/08/14 07:47:19 girlich Exp $ + * $Id: packet-rpc.c,v 1.38 2000/08/24 06:19:52 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -301,11 +301,27 @@ char *rpc_prog_name(guint32 prog) /*--------------------------------------*/ /* static array, first quick implementation, I'll switch over to GList soon */ +typedef struct _rpc_call_info { + guint32 xid; + conversation_t *conversation; + guint32 req_num; /* frame number of first request seen */ + guint32 rep_num; /* frame number of first reply seen */ + guint32 prog; + guint32 vers; + guint32 proc; + guint32 flavor; + guint32 gss_proc; + guint32 gss_svc; + rpc_proc_info_value* proc_info; +} rpc_call_info; + +#define RPC_CALL_TABLE_LENGTH 1000 + rpc_call_info rpc_call_table[RPC_CALL_TABLE_LENGTH]; guint32 rpc_call_index = 0; guint32 rpc_call_firstfree = 0; -void +static void rpc_call_insert(rpc_call_info *call) { /* some space left? */ @@ -329,7 +345,7 @@ rpc_call_insert(rpc_call_info *call) } -rpc_call_info* +static rpc_call_info* rpc_call_lookup(rpc_call_info *call) { int i; @@ -1253,21 +1269,28 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree) rpc_call_msg.conversation = conversation; /* look up the request */ - if (rpc_call_lookup(&rpc_call_msg)) { - /* duplicate request */ - if (check_col(fd, COL_INFO)) { - col_append_fstr(fd, COL_INFO, " dup XID 0x%x", xid); - if (rpc_tree) { - proto_tree_add_uint_hidden(rpc_tree, - hf_rpc_dup, NullTVB, 0,0, xid); - proto_tree_add_uint_hidden(rpc_tree, - hf_rpc_call_dup, NullTVB, 0,0, xid); + if ((rpc_call = rpc_call_lookup(&rpc_call_msg)) != NULL) { + /* We've seen a request with this XID, with the same + source and destination, before - but was it + *this* request? */ + if (fd->num != rpc_call->req_num) { + /* No, so it's a duplicate request. + Mark it as such. */ + if (check_col(fd, COL_INFO)) { + col_append_fstr(fd, COL_INFO, " dup XID 0x%x", xid); + if (rpc_tree) { + proto_tree_add_uint_hidden(rpc_tree, + hf_rpc_dup, NullTVB, 0,0, xid); + proto_tree_add_uint_hidden(rpc_tree, + hf_rpc_call_dup, NullTVB, 0,0, xid); + } } } } else { /* prepare the value data */ - rpc_call_msg.replies = 0; + rpc_call_msg.req_num = fd->num; + rpc_call_msg.rep_num = 0xffffffff; rpc_call_msg.prog = prog; rpc_call_msg.vers = vers; rpc_call_msg.proc = proc; @@ -1298,6 +1321,11 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree) gss_proc = rpc_call->gss_proc; gss_svc = rpc_call->gss_svc; + /* Indicate the frame to which this is a reply. */ + proto_tree_add_text(rpc_tree, NullTVB, 0, 0, + "This is a reply to frame %u", + rpc_call->req_num); + if (rpc_call->proc_info != NULL) { dissect_function = rpc_call->proc_info->dissect_reply; if (rpc_call->proc_info->name != NULL) { @@ -1313,7 +1341,6 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree) sprintf(procname_static, "proc-%u", proc); procname = procname_static; } - rpc_call->replies++; rpc_prog_key.prog = prog; if ((rpc_prog = g_hash_table_lookup(rpc_progs,&rpc_prog_key)) == NULL) { @@ -1353,14 +1380,25 @@ dissect_rpc( const u_char *pd, int offset, frame_data *fd, proto_tree *tree) "Procedure: %s (%u)", procname, proc); } - if (rpc_call->replies>1) { - if (check_col(fd, COL_INFO)) { - col_append_fstr(fd, COL_INFO, " dup XID 0x%x", xid); - if (rpc_tree) { - proto_tree_add_uint_hidden(rpc_tree, - hf_rpc_dup, NullTVB, 0,0, xid); - proto_tree_add_uint_hidden(rpc_tree, - hf_rpc_reply_dup, NullTVB, 0,0, xid); + if (rpc_call->rep_num == 0xffffffff) { + /* We have not yet seen a reply to that call, so + this must be the first reply; remember its + frame number. */ + rpc_call->rep_num = fd->num; + } else { + /* We have seen a reply to this call - but was it + *this* reply? */ + if (rpc_call->rep_num != fd->num) { + /* No, so it's a duplicate reply. + Mark it as such. */ + if (check_col(fd, COL_INFO)) { + col_append_fstr(fd, COL_INFO, " dup XID 0x%x", xid); + if (rpc_tree) { + proto_tree_add_uint_hidden(rpc_tree, + hf_rpc_dup, NullTVB, 0,0, xid); + proto_tree_add_uint_hidden(rpc_tree, + hf_rpc_reply_dup, NullTVB, 0,0, xid); + } } } } diff --git a/packet-rpc.h b/packet-rpc.h index 70a3a1a227..4ef1e87178 100644 --- a/packet-rpc.h +++ b/packet-rpc.h @@ -1,6 +1,6 @@ /* packet-rpc.h * - * $Id: packet-rpc.h,v 1.17 2000/08/11 13:34:01 deniel Exp $ + * $Id: packet-rpc.h,v 1.18 2000/08/24 06:19:53 guy Exp $ * * (c) 1999 Uwe Girlich * @@ -102,26 +102,8 @@ typedef struct _rpc_prog_info_value { char* progname; } rpc_prog_info_value; -typedef struct _rpc_call_info { - guint32 xid; - conversation_t *conversation; - guint32 replies; - guint32 prog; - guint32 vers; - guint32 proc; - guint32 flavor; - guint32 gss_proc; - guint32 gss_svc; - rpc_proc_info_value* proc_info; -} rpc_call_info; - -#define RPC_CALL_TABLE_LENGTH 1000 - extern const value_string rpc_auth_flavor[]; -extern void rpc_call_insert(rpc_call_info *call); -extern rpc_call_info* rpc_call_lookup(rpc_call_info *call); - extern void rpc_init_proc_table(guint prog, guint vers, const vsff *proc_table); extern void rpc_init_prog(int proto, guint32 prog, int ett); extern char *rpc_prog_name(guint32 prog);