summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGilbert Ramirez <gram@alumni.rice.edu>2002-01-05 04:12:17 +0000
committerGilbert Ramirez <gram@alumni.rice.edu>2002-01-05 04:12:17 +0000
commit0b9b02c6ea4bbf4a7792aa1493b507fd68e8a87b (patch)
treeac264635defc42eb14ee180db1b32d9b5032458c
parent3ed03cadf65462aa5253098f0df781022cb3a0ed (diff)
downloadwireshark-0b9b02c6ea4bbf4a7792aa1493b507fd68e8a87b.tar.gz
Long NCP traces can easily have many packets whose "uniqueness"
variables wrap-around. Since the request/reply packets are related via a hash based on these uniqueness variables, long NCP traces can have mis-matches reqeust/reply records. Thus, only do the hash-lookup for the reply packet during the first sequential scan of the trace file. Once the pertinent info is found, store it in the packet's private data area. Since the memory allocated for the hash and for the structures that make up the keys are no longer needed after the first sequential run through the trace file, arrange to free that memory after the first sequential run. Similar to the register_init_routine() that allows dissectors to register callbacks for calling *before* a capture file is loaded, set up a register_postseq_cleanup_routine() function that allows dissectors to register callbacks for calling *after* the first sequential run-through of the trace file is made. This is not a *final* cleanup callback, since Ethereal will still have that trace file open for random-access reading. I didn't have tethereal call postseq_cleanup_all_protocols() since tethereal doesn't keep the trace file open for random-access reading. I could easily be swayed to make tethereal call that function, however. svn path=/trunk/; revision=4484
-rw-r--r--epan/packet.c33
-rw-r--r--epan/packet.h11
-rw-r--r--epan/plugins.c3
-rw-r--r--file.c10
-rw-r--r--packet-ncp-int.h9
-rw-r--r--packet-ncp.c60
-rw-r--r--packet-ncp2222.inc34
-rw-r--r--plugins/plugin_api.c3
-rw-r--r--plugins/plugin_api.h3
-rw-r--r--plugins/plugin_api_defs.h3
-rw-r--r--plugins/plugin_table.h4
11 files changed, 110 insertions, 63 deletions
diff --git a/epan/packet.c b/epan/packet.c
index 6ef976a430..2d240d166f 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -1,7 +1,7 @@
/* packet.c
* Routines for packet disassembly
*
- * $Id: packet.c,v 1.55 2001/12/18 19:09:03 gram Exp $
+ * $Id: packet.c,v 1.56 2002/01/05 04:12:16 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -150,6 +150,37 @@ init_all_protocols(void)
g_slist_foreach(init_routines, &call_init_routine, NULL);
}
+
+/* Allow protocols to register a "cleanup" routine to be
+ * run after the initial sequential run through the packets.
+ * Note that the file can still be open after this; this is not
+ * the final cleanup. */
+static GSList *postseq_cleanup_routines;
+
+void
+register_postseq_cleanup_routine(void (*func)(void))
+{
+ postseq_cleanup_routines = g_slist_append(postseq_cleanup_routines,
+ func);
+}
+
+/* Call all the registered "postseq_cleanup" routines. */
+static void
+call_postseq_cleanup_routine(gpointer routine, gpointer dummy)
+{
+ void (*func)(void) = routine;
+
+ (*func)();
+}
+
+void
+postseq_cleanup_all_protocols(void)
+{
+ g_slist_foreach(postseq_cleanup_routines,
+ &call_postseq_cleanup_routine, NULL);
+}
+
+
/* Creates the top-most tvbuff and calls dissect_frame() */
void
dissect_packet(epan_dissect_t *edt, union wtap_pseudo_header *pseudo_header,
diff --git a/epan/packet.h b/epan/packet.h
index 5d4a048c75..ad7b86da0c 100644
--- a/epan/packet.h
+++ b/epan/packet.h
@@ -1,7 +1,7 @@
/* packet.h
* Definitions for packet disassembly structures and routines
*
- * $Id: packet.h,v 1.48 2001/12/18 19:09:03 gram Exp $
+ * $Id: packet.h,v 1.49 2002/01/05 04:12:16 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -223,6 +223,15 @@ extern void register_init_routine(void (*func)(void));
/* Call all the registered "init" routines. */
extern void init_all_protocols(void);
+/* Allow protocols to register a "cleanup" routine to be
+ * run after the initial sequential run through the packets.
+ * Note that the file can still be open after this; this is not
+ * the final cleanup. */
+extern void register_postseq_cleanup_routine(void (*func)(void));
+
+/* Call all the registered "postseq_cleanup" routines. */
+extern void postseq_cleanup_all_protocols(void);
+
/*
* Dissectors should never modify the packet data.
*/
diff --git a/epan/plugins.c b/epan/plugins.c
index 1e3730dd01..e2b6779330 100644
--- a/epan/plugins.c
+++ b/epan/plugins.c
@@ -1,7 +1,7 @@
/* plugins.c
* plugin routines
*
- * $Id: plugins.c,v 1.44 2001/12/03 10:00:21 guy Exp $
+ * $Id: plugins.c,v 1.45 2002/01/05 04:12:16 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -293,6 +293,7 @@ init_plugins(const char *plugin_dir)
patable.p_col_set_str = col_set_str;
patable.p_register_init_routine = register_init_routine;
+ patable.p_register_postseq_cleanup_routine = register_postseq_cleanup_routine;
patable.p_conversation_new = conversation_new;
patable.p_find_conversation = find_conversation;
patable.p_match_strval = match_strval;
diff --git a/file.c b/file.c
index 04ced07bf8..284ba530db 100644
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
- * $Id: file.c,v 1.256 2002/01/03 22:27:44 guy Exp $
+ * $Id: file.c,v 1.257 2002/01/05 04:12:14 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -380,6 +380,10 @@ read_cap_file(capture_file *cf, int *err)
/* Close the sequential I/O side, to free up memory it requires. */
wtap_sequential_close(cf->wth);
+ /* Allow the protocol dissectors to free up memory that they
+ * don't need after the sequential run-through of the packets. */
+ postseq_cleanup_all_protocols();
+
/* Set the file encapsulation type now; we don't know what it is until
we've looked at all the packets, as we don't know until then whether
there's more than one type (and thus whether it's
@@ -558,6 +562,10 @@ finish_tail_cap_file(capture_file *cf, int *err)
sequential I/O side, to free up memory it requires. */
wtap_sequential_close(cf->wth);
+ /* Allow the protocol dissectors to free up memory that they
+ * don't need after the sequential run-through of the packets. */
+ postseq_cleanup_all_protocols();
+
/* Set the file encapsulation type now; we don't know what it is until
we've looked at all the packets, as we don't know until then whether
there's more than one type (and thus whether it's
diff --git a/packet-ncp-int.h b/packet-ncp-int.h
index c0fb933272..57262d0734 100644
--- a/packet-ncp-int.h
+++ b/packet-ncp-int.h
@@ -2,7 +2,7 @@
* Structures and functions for NetWare Core Protocol.
* Gilbert Ramirez <gram@alumni.rice.edu>
*
- * $Id: packet-ncp-int.h,v 1.4 2001/11/13 23:55:30 gram Exp $
+ * $Id: packet-ncp-int.h,v 1.5 2002/01/05 04:12:14 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -59,12 +59,9 @@ void dissect_ncp_reply(tvbuff_t *, packet_info*, guint16,
guint8, proto_tree*, proto_tree*);
void ncp_hash_insert(conversation_t *conversation, guint8 nw_sequence,
- guint16 ncp_type, const ncp_record *ncp_rec);
+ const ncp_record *ncp_rec);
-/* Returns TRUE or FALSE. If TRUE, the record was found and
- * ncp_type and ncp_rec are set. */
-gboolean ncp_hash_lookup(conversation_t*, guint8 nw_sequence,
- guint16 *ncp_type, const ncp_record **ncp_rec);
+const ncp_record* ncp_hash_lookup(conversation_t*, guint8 nw_sequence);
extern int proto_ncp;
diff --git a/packet-ncp.c b/packet-ncp.c
index af242f8024..cfe0c6ebfc 100644
--- a/packet-ncp.c
+++ b/packet-ncp.c
@@ -3,7 +3,7 @@
* Gilbert Ramirez <gram@alumni.rice.edu>
* Modified to allow NCP over TCP/IP decodes by James Coe <jammer@cin.net>
*
- * $Id: packet-ncp.c,v 1.52 2001/12/10 00:25:31 guy Exp $
+ * $Id: packet-ncp.c,v 1.53 2002/01/05 04:12:14 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -152,15 +152,9 @@ typedef struct {
guint8 nw_sequence;
} ncp_request_key;
-typedef struct {
- guint16 ncp_type;
- const ncp_record *ncp_record;
-} ncp_request_val;
-
static GHashTable *ncp_request_hash = NULL;
static GMemChunk *ncp_request_keys = NULL;
-static GMemChunk *ncp_request_records = NULL;
/* Hash Functions */
gint ncp_equal (gconstpointer v, gconstpointer v2)
@@ -190,23 +184,33 @@ ncp_init_protocol(void)
g_hash_table_destroy(ncp_request_hash);
if (ncp_request_keys)
g_mem_chunk_destroy(ncp_request_keys);
- if (ncp_request_records)
- g_mem_chunk_destroy(ncp_request_records);
ncp_request_hash = g_hash_table_new(ncp_hash, ncp_equal);
ncp_request_keys = g_mem_chunk_new("ncp_request_keys",
sizeof(ncp_request_key),
ncp_packet_init_count * sizeof(ncp_request_key), G_ALLOC_AND_FREE);
- ncp_request_records = g_mem_chunk_new("ncp_request_records",
- sizeof(ncp_request_val),
- ncp_packet_init_count * sizeof(ncp_request_val), G_ALLOC_AND_FREE);
+}
+
+/* After the sequential run, we don't need the ncp_request hash and keys
+ * anymore; the lookups have already been done and the vital info
+ * saved in the reply-packets' private_data in the frame_data struct. */
+static void
+ncp_postseq_cleanup(void)
+{
+ if (ncp_request_hash) {
+ g_hash_table_destroy(ncp_request_hash);
+ ncp_request_hash = NULL;
+ }
+ if (ncp_request_keys) {
+ g_mem_chunk_destroy(ncp_request_keys);
+ ncp_request_keys = NULL;
+ }
}
void
ncp_hash_insert(conversation_t *conversation, guint8 nw_sequence,
- guint16 ncp_type, const ncp_record *ncp_rec)
+ const ncp_record *ncp_rec)
{
- ncp_request_val *request_val;
ncp_request_key *request_key;
/* Now remember the request, so we can find it if we later
@@ -215,36 +219,19 @@ ncp_hash_insert(conversation_t *conversation, guint8 nw_sequence,
request_key->conversation = conversation;
request_key->nw_sequence = nw_sequence;
- request_val = g_mem_chunk_alloc(ncp_request_records);
- request_val->ncp_type = ncp_type;
- request_val->ncp_record = ncp_rec;
-
- g_hash_table_insert(ncp_request_hash, request_key, request_val);
+ g_hash_table_insert(ncp_request_hash, request_key, (void*)ncp_rec);
}
-/* Returns TRUE or FALSE. If TRUE, the record was found and
- * ncp_type and ncp_rec are set. */
-gboolean
-ncp_hash_lookup(conversation_t *conversation, guint8 nw_sequence,
- guint16 *ncp_type, const ncp_record **ncp_rec)
+/* Returns the ncp_rec*, or NULL if not found. */
+const ncp_record*
+ncp_hash_lookup(conversation_t *conversation, guint8 nw_sequence)
{
- ncp_request_val *request_val;
ncp_request_key request_key;
request_key.conversation = conversation;
request_key.nw_sequence = nw_sequence;
- request_val = (ncp_request_val*)
- g_hash_table_lookup(ncp_request_hash, &request_key);
-
- if (request_val) {
- *ncp_type = request_val->ncp_type;
- *ncp_rec = request_val->ncp_record;
- return TRUE;
- }
- else {
- return FALSE;
- }
+ return g_hash_table_lookup(ncp_request_hash, &request_key);
}
static void
@@ -386,6 +373,7 @@ proto_register_ncp(void)
proto_register_field_array(proto_ncp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
register_init_routine(&ncp_init_protocol);
+ register_postseq_cleanup_routine(&ncp_postseq_cleanup);
/* Register a configuration option for initial size of NCP hash */
ncp_module = prefs_register_protocol(proto_ncp, NULL);
diff --git a/packet-ncp2222.inc b/packet-ncp2222.inc
index b97ee7a150..e1cb842ec2 100644
--- a/packet-ncp2222.inc
+++ b/packet-ncp2222.inc
@@ -7,7 +7,7 @@
*
* Gilbert Ramirez <gram@alumni.rice.edu>
*
- * $Id: packet-ncp2222.inc,v 1.6 2001/12/10 00:25:31 guy Exp $
+ * $Id: packet-ncp2222.inc,v 1.7 2002/01/05 04:12:14 gram Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -182,15 +182,19 @@ dissect_ncp_request(tvbuff_t *tvb, packet_info *pinfo,
let the user select that conversation to be displayed.) */
conversation = find_conversation(&pinfo->src, &pinfo->dst,
PT_NCP, nw_connection, nw_connection, 0);
+
if (conversation == NULL) {
/* It's not part of any conversation - create a new one. */
conversation = conversation_new(&pinfo->src, &pinfo->dst,
PT_NCP, nw_connection, nw_connection, 0);
}
- ncp_hash_insert(conversation, sequence, 0x2222, ncp_rec);
+ ncp_hash_insert(conversation, sequence, ncp_rec);
}
if (ncp_tree) {
+ conversation = find_conversation(&pinfo->src, &pinfo->dst,
+ PT_NCP, nw_connection, nw_connection, 0);
+
switch (type) {
case 0x1111:
; /* nothing */
@@ -247,23 +251,27 @@ dissect_ncp_reply(tvbuff_t *tvb, packet_info *pinfo,
conversation_t *conversation;
const ncp_record *ncp_rec = NULL;
- guint16 ncp_type;
gboolean found_request = FALSE;
guint8 completion_code;
guint length;
ptvcursor_t *ptvc = NULL;
const char *error_string;
- /* Find the conversation whence the request would have come. */
- conversation = find_conversation(&pinfo->src, &pinfo->dst,
- PT_NCP, nw_connection, nw_connection, 0);
- if (conversation != NULL) {
- /* find the record telling us the request made that caused
- this reply */
- found_request = ncp_hash_lookup(conversation, sequence,
- &ncp_type, &ncp_rec);
+ if (!pinfo->fd->flags.visited) {
+ /* Find the conversation whence the request would have come. */
+ conversation = find_conversation(&pinfo->src, &pinfo->dst,
+ PT_NCP, nw_connection, nw_connection, 0);
+ if (conversation != NULL) {
+ /* find the record telling us the request made that caused
+ this reply */
+ ncp_rec = ncp_hash_lookup(conversation, sequence);
+ p_add_proto_data(pinfo->fd, proto_ncp, (void*) ncp_rec);
+ }
+ /* else... we haven't seen an NCP Request for that conversation and sequence. */
+ }
+ else {
+ ncp_rec = p_get_proto_data(pinfo->fd, proto_ncp);
}
- /* else... we haven't seen an NCP Request for that conversation and sequence. */
/* A completion code of 0 always means OK. Non-zero means failure,
* but each non-zero value has a different meaning. And the same value
@@ -317,7 +325,7 @@ dissect_ncp_reply(tvbuff_t *tvb, packet_info *pinfo,
if (completion_code != 0 && tvb_length(tvb) == 8) {
return;
}
-
+ /*printf("func=0x%x subfunc=0x%x\n", ncp_rec->func, ncp_rec->subfunc);*/
ptvc = ptvcursor_new(ncp_tree, tvb, 8);
process_ptvc_record(ptvc, ncp_rec->reply_ptvc);
ptvcursor_free(ptvc);
diff --git a/plugins/plugin_api.c b/plugins/plugin_api.c
index c6525a2a0c..1d83fde0ec 100644
--- a/plugins/plugin_api.c
+++ b/plugins/plugin_api.c
@@ -1,7 +1,7 @@
/* plugin_api.c
* Routines for Ethereal plugins.
*
- * $Id: plugin_api.c,v 1.32 2001/12/03 10:00:22 guy Exp $
+ * $Id: plugin_api.c,v 1.33 2002/01/05 04:12:17 gram Exp $
*
* Ethereal - Network traffic analyzer
* Copyright 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -42,6 +42,7 @@ plugin_address_table_init(plugin_address_table_t *pat)
p_col_append_str = pat->p_col_append_str;
p_col_set_str = pat->p_col_set_str;
p_register_init_routine = pat->p_register_init_routine;
+ p_register_postseq_cleanup_routine = pat->p_register_postseq_cleanup_routine;
p_conversation_new = pat->p_conversation_new;
p_find_conversation = pat->p_find_conversation;
p_match_strval = pat->p_match_strval;
diff --git a/plugins/plugin_api.h b/plugins/plugin_api.h
index 60d0b26161..f9bc5af54b 100644
--- a/plugins/plugin_api.h
+++ b/plugins/plugin_api.h
@@ -1,7 +1,7 @@
/* plugin_api.h
* Routines for Ethereal plugins.
*
- * $Id: plugin_api.h,v 1.32 2001/12/03 10:00:23 guy Exp $
+ * $Id: plugin_api.h,v 1.33 2002/01/05 04:12:17 gram Exp $
*
* Ethereal - Network traffic analyzer
* Copyright 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -43,6 +43,7 @@
#define col_set_str (*p_col_set_str)
#define register_init_routine (*p_register_init_routine)
+#define register_postseq_cleanup_routine (*p_register_postseq_cleanup_routine)
#define conversation_new (*p_conversation_new)
#define find_conversation (*p_find_conversation)
#define match_strval (*p_match_strval)
diff --git a/plugins/plugin_api_defs.h b/plugins/plugin_api_defs.h
index af1f5a8485..897399e6a7 100644
--- a/plugins/plugin_api_defs.h
+++ b/plugins/plugin_api_defs.h
@@ -1,7 +1,7 @@
/* plugin_api_defs.h
* Define the variables that hold pointers to plugin API functions
*
- * $Id: plugin_api_defs.h,v 1.8 2001/12/03 10:00:23 guy Exp $
+ * $Id: plugin_api_defs.h,v 1.9 2002/01/05 04:12:17 gram Exp $
*
* Ethereal - Network traffic analyzer
* Copyright 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -32,6 +32,7 @@ addr_col_append_str p_col_append_str;
addr_col_set_str p_col_set_str;
addr_register_init_routine p_register_init_routine;
+addr_register_postseq_cleanup_routine p_register_postseq_cleanup_routine;
addr_conversation_new p_conversation_new;
addr_find_conversation p_find_conversation;
addr_match_strval p_match_strval;
diff --git a/plugins/plugin_table.h b/plugins/plugin_table.h
index fe173345a3..7dd259811f 100644
--- a/plugins/plugin_table.h
+++ b/plugins/plugin_table.h
@@ -1,7 +1,7 @@
/* plugin_table.h
* Table of exported addresses for Ethereal plugins.
*
- * $Id: plugin_table.h,v 1.35 2001/12/10 01:48:27 guy Exp $
+ * $Id: plugin_table.h,v 1.36 2002/01/05 04:12:17 gram Exp $
*
* Ethereal - Network traffic analyzer
* Copyright 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
@@ -37,6 +37,7 @@ typedef void (*addr_col_append_str)(column_info*, gint, gchar*);
typedef void (*addr_col_set_str)(column_info*, gint, gchar*);
typedef void (*addr_register_init_routine)(void (*func)(void));
+typedef void (*addr_register_postseq_cleanup_routine)(void (*func)(void));
typedef conversation_t *(*addr_conversation_new)(address *, address *,
port_type, guint32, guint32, guint);
typedef conversation_t *(*addr_find_conversation)(address *, address *,
@@ -219,6 +220,7 @@ typedef struct {
addr_col_set_str p_col_set_str;
addr_register_init_routine p_register_init_routine;
+ addr_register_postseq_cleanup_routine p_register_postseq_cleanup_routine;
addr_conversation_new p_conversation_new;
addr_find_conversation p_find_conversation;
addr_match_strval p_match_strval;