X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=epan%2Fstream.c;h=3ac068c94741e62f359734b21145485973407ef4;hb=370d13026a4c6abf23178681ea27f438f0daa5b6;hp=01020681963428428cfb7665d48fbeb7eb00a8a1;hpb=05d8d0c76f801027da9ed58a89f4245c98ad44a6;p=metze%2Fwireshark%2Fwip.git diff --git a/epan/stream.c b/epan/stream.c index 0102068196..3ac068c947 100644 --- a/epan/stream.c +++ b/epan/stream.c @@ -4,10 +4,8 @@ * which are handled as streams, and don't have lengths * and IDs such as are required for reassemble.h * - * $Id$ - * - * Ethereal - Network traffic analyzer - * By Gerald Combs + * Wireshark - Network traffic analyzer + * By Gerald Combs * Copyright 1998 Gerald Combs * * This program is free software; you can redistribute it and/or @@ -22,12 +20,10 @@ * * 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. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "config.h" #include #include @@ -35,20 +31,11 @@ #include #include -/* number of streams to allocate memory for at once */ -#define MEMCHUNK_STREAM_COUNT 20 - -/* ditto pdus */ -#define MEMCHUNK_PDU_COUNT 100 - -/* ditto fragments */ -#define MEMCHUNK_FRAGMENT_COUNT 100 - typedef struct { - fragment_data *fd_head; /* the reassembled data, NULL - * until we add the last fragment */ - guint32 pdu_number; /* Number of this PDU within the stream */ + fragment_head *fd_head; /* the reassembled data, NULL + * until we add the last fragment */ + guint32 pdu_number; /* Number of this PDU within the stream */ /* id of this pdu (globally unique) */ guint32 id; @@ -57,7 +44,7 @@ typedef struct { struct stream_pdu_fragment { - guint32 len; /* the length of this fragment */ + guint32 len; /* the length of this fragment */ stream_pdu_t *pdu; gboolean final_fragment; }; @@ -92,88 +79,73 @@ typedef struct stream_key { that here */ gboolean is_circuit; union { - const struct circuit *circuit; - const struct conversation *conv; + const struct circuit *circuit; + const struct conversation *conv; } circ; int p2p_dir; } stream_key_t; /* hash func */ -guint stream_hash_func(gconstpointer k) +static guint stream_hash_func(gconstpointer k) { const stream_key_t *key = (const stream_key_t *)k; /* is_circuit is redundant to the circuit/conversation pointer */ - return ((guint)key->circ.circuit) ^ key->p2p_dir; + return (GPOINTER_TO_UINT(key->circ.circuit)) ^ key->p2p_dir; } /* compare func */ -gboolean stream_compare_func(gconstpointer a, - gconstpointer b) +static gboolean stream_compare_func(gconstpointer a, + gconstpointer b) { const stream_key_t *key1 = (const stream_key_t *)a; const stream_key_t *key2 = (const stream_key_t *)b; if( key1 -> p2p_dir != key2 -> p2p_dir || - key1-> is_circuit != key2 -> is_circuit ) - return FALSE; - + key1-> is_circuit != key2 -> is_circuit ) + return FALSE; + if( key1 -> is_circuit ) - return (key1 -> circ.circuit == key2 -> circ.circuit ); + return (key1 -> circ.circuit == key2 -> circ.circuit ); else - return (key1 -> circ.conv == key2 -> circ.conv ); + return (key1 -> circ.conv == key2 -> circ.conv ); } -/* memory pools */ -static GMemChunk *stream_keys = NULL; -static GMemChunk *streams = NULL; - - /* the hash table */ static GHashTable *stream_hash; -/* init/reset function, call from stream_init() */ -static void init_stream_hash( void ) { +/* cleanup reset function, call from stream_cleanup() */ +static void cleanup_stream_hash( void ) { if( stream_hash != NULL ) { - g_hash_table_destroy( stream_hash ); - stream_hash = NULL; - } - - if( stream_keys != NULL ) { - g_mem_chunk_destroy( stream_keys ); - stream_keys = NULL; + g_hash_table_destroy( stream_hash ); + stream_hash = NULL; } +} - if( streams != NULL ) { - g_mem_chunk_destroy( streams ); - streams = NULL; - } - - streams = g_mem_chunk_create(stream_t, - MEMCHUNK_STREAM_COUNT, - G_ALLOC_ONLY); - - stream_keys = g_mem_chunk_create(stream_key_t, - MEMCHUNK_STREAM_COUNT, - G_ALLOC_ONLY); - +/* init function, call from stream_init() */ +static void init_stream_hash( void ) { + g_assert(stream_hash==NULL); stream_hash = g_hash_table_new(stream_hash_func, - stream_compare_func); + stream_compare_func); } - /* lookup function, returns null if not found */ static stream_t *stream_hash_lookup_circ( const struct circuit *circuit, int p2p_dir ) { - stream_key_t key = {TRUE,{circuit}, p2p_dir}; + stream_key_t key; + key.is_circuit=TRUE; + key.circ.circuit=circuit; + key.p2p_dir=p2p_dir; return (stream_t *)g_hash_table_lookup(stream_hash, &key); } static stream_t *stream_hash_lookup_conv( const struct conversation *conv, int p2p_dir ) { - stream_key_t key = {FALSE,{NULL}, p2p_dir}; + stream_key_t key; + key.is_circuit=FALSE; key.circ.conv = conv; + key.p2p_dir=p2p_dir; return (stream_t *)g_hash_table_lookup(stream_hash, &key); } @@ -181,8 +153,8 @@ static stream_t *stream_hash_lookup_conv( const struct conversation *conv, int p static stream_t *new_stream( stream_key_t *key ) { stream_t *val; - - val = g_mem_chunk_alloc(streams); + + val = wmem_new(wmem_file_scope(), stream_t); val -> key = key; val -> pdu_counter = 0; val -> current_pdu = NULL; @@ -199,7 +171,7 @@ static stream_t *stream_hash_insert_circ( const struct circuit *circuit, int p2p { stream_key_t *key; - key = g_mem_chunk_alloc(stream_keys); + key = wmem_new(wmem_file_scope(), stream_key_t); key->is_circuit = TRUE; key->circ.circuit = circuit; key->p2p_dir = p2p_dir; @@ -211,7 +183,7 @@ static stream_t *stream_hash_insert_conv( const struct conversation *conv, int p { stream_key_t *key; - key = g_mem_chunk_alloc(stream_keys); + key = wmem_new(wmem_file_scope(), stream_key_t); key->is_circuit = FALSE; key->circ.conv = conv; key->p2p_dir = p2p_dir; @@ -224,22 +196,16 @@ static stream_t *stream_hash_insert_conv( const struct conversation *conv, int p * * PDU data */ -static GMemChunk *pdus = NULL; /* pdu counter, for generating unique pdu ids */ static guint32 pdu_counter; +static void stream_cleanup_pdu_data(void) +{ +} static void stream_init_pdu_data(void) { - if( pdus != NULL ) { - g_mem_chunk_destroy( pdus ); - pdus = NULL; - } - - pdus = g_mem_chunk_create(stream_pdu_t, - MEMCHUNK_PDU_COUNT, - G_ALLOC_ONLY); pdu_counter = 0; } @@ -248,7 +214,7 @@ static void stream_init_pdu_data(void) static stream_pdu_t *stream_new_pdu(stream_t *stream) { stream_pdu_t *pdu; - pdu = g_mem_chunk_alloc(pdus); + pdu = wmem_new(wmem_file_scope(), stream_pdu_t); pdu -> fd_head = NULL; pdu -> pdu_number = stream -> pdu_counter++; pdu -> id = pdu_counter++; @@ -269,66 +235,53 @@ typedef struct fragment_key { /* hash func */ -guint fragment_hash_func(gconstpointer k) +static guint fragment_hash_func(gconstpointer k) { const fragment_key_t *key = (const fragment_key_t *)k; - return ((guint)key->stream) + ((guint)key -> framenum) + ((guint)key->offset); + return (GPOINTER_TO_UINT(key->stream)) + ((guint)key -> framenum) + ((guint)key->offset); } /* compare func */ -gboolean fragment_compare_func(gconstpointer a, - gconstpointer b) +static gboolean fragment_compare_func(gconstpointer a, + gconstpointer b) { const fragment_key_t *key1 = (const fragment_key_t *)a; const fragment_key_t *key2 = (const fragment_key_t *)b; return (key1 -> stream == key2 -> stream && - key1 -> framenum == key2 -> framenum && - key1 -> offset == key2 -> offset ); + key1 -> framenum == key2 -> framenum && + key1 -> offset == key2 -> offset ); } - -/* memory pools */ -static GMemChunk *fragment_keys = NULL; -static GMemChunk *fragment_vals = NULL; /* the hash table */ static GHashTable *fragment_hash; -/* init/reset function, call from stream_init() */ -static void init_fragment_hash( void ) { +/* cleanup function, call from stream_cleanup() */ +static void cleanup_fragment_hash( void ) { if( fragment_hash != NULL ) { - g_hash_table_destroy( fragment_hash ); - fragment_hash = NULL; - } - - if( fragment_vals != NULL ) { - g_mem_chunk_destroy( fragment_vals ); - fragment_vals = NULL; + g_hash_table_destroy( fragment_hash ); + fragment_hash = NULL; } +} - if( fragment_keys != NULL ) { - g_mem_chunk_destroy( fragment_keys ); - fragment_keys = NULL; - } - - fragment_keys = g_mem_chunk_create(fragment_key_t, - MEMCHUNK_FRAGMENT_COUNT, - G_ALLOC_ONLY); - - fragment_vals = g_mem_chunk_create(stream_pdu_fragment_t, - MEMCHUNK_FRAGMENT_COUNT, - G_ALLOC_ONLY); - +/* init function, call from stream_init() */ +static void init_fragment_hash( void ) { + g_assert(fragment_hash==NULL); fragment_hash = g_hash_table_new(fragment_hash_func, - fragment_compare_func); + fragment_compare_func); } /* lookup function, returns null if not found */ static stream_pdu_fragment_t *fragment_hash_lookup( const stream_t *stream, guint32 framenum, guint32 offset ) { - fragment_key_t key = {stream, framenum, offset}; - stream_pdu_fragment_t *val = g_hash_table_lookup(fragment_hash, &key); + fragment_key_t key; + stream_pdu_fragment_t *val; + + key.stream = stream; + key.framenum = framenum; + key.offset = offset; + val = (stream_pdu_fragment_t *)g_hash_table_lookup(fragment_hash, &key); return val; } @@ -336,17 +289,17 @@ static stream_pdu_fragment_t *fragment_hash_lookup( const stream_t *stream, guin /* insert function */ static stream_pdu_fragment_t *fragment_hash_insert( const stream_t *stream, guint32 framenum, guint32 offset, - guint32 length) + guint32 length) { fragment_key_t *key; stream_pdu_fragment_t *val; - key = g_mem_chunk_alloc(fragment_keys); + key = wmem_new(wmem_file_scope(), fragment_key_t); key->stream = stream; key->framenum = framenum; key->offset = offset; - val = g_mem_chunk_alloc(fragment_vals); + val = wmem_new(wmem_file_scope(), stream_pdu_fragment_t); val->len = length; val->pdu = NULL; val->final_fragment = FALSE; @@ -357,9 +310,8 @@ static stream_pdu_fragment_t *fragment_hash_insert( const stream_t *stream, guin /*****************************************************************************/ -/* fragmentation hash tables */ -static GHashTable *stream_fragment_table = NULL; -static GHashTable *stream_reassembled_table = NULL; +/* reassembly table */ +static reassembly_table stream_reassembly_table; /* Initialise a new stream. Call this when you first identify a distinct * stream. */ @@ -370,10 +322,10 @@ stream_t *stream_new_circ ( const struct circuit *circuit, int p2p_dir ) /* we don't want to replace the previous data if we get called twice on the same circuit, so do a lookup first */ stream = stream_hash_lookup_circ(circuit, p2p_dir); - g_assert( stream == NULL ); + DISSECTOR_ASSERT( stream == NULL ); stream = stream_hash_insert_circ(circuit, p2p_dir); - + return stream; } @@ -384,15 +336,13 @@ stream_t *stream_new_conv ( const struct conversation *conv, int p2p_dir ) /* we don't want to replace the previous data if we get called twice on the same conversation, so do a lookup first */ stream = stream_hash_lookup_conv(conv, p2p_dir); - g_assert( stream == NULL ); + DISSECTOR_ASSERT( stream == NULL ); stream = stream_hash_insert_conv(conv, p2p_dir); return stream; } - - /* retrieve a previously-created stream. * * Returns null if no matching stream was found. @@ -406,6 +356,18 @@ stream_t *find_stream_conv ( const struct conversation *conv, int p2p_dir ) return stream_hash_lookup_conv(conv,p2p_dir); } +/* cleanup the stream routines */ +/* Note: stream_cleanup must only be called when seasonal memory + * is also freed since the hash tables countain pointers to + * wmem_file_scoped memory. + */ +void stream_cleanup( void ) +{ + cleanup_stream_hash(); + cleanup_fragment_hash(); + stream_cleanup_pdu_data(); + reassembly_table_destroy(&stream_reassembly_table); +} /* initialise the stream routines */ void stream_init( void ) @@ -414,55 +376,52 @@ void stream_init( void ) init_fragment_hash(); stream_init_pdu_data(); - fragment_table_init(&stream_fragment_table); - reassembled_table_init(&stream_reassembled_table); + reassembly_table_init(&stream_reassembly_table, + &addresses_reassembly_table_functions); } - - - /*****************************************************************************/ stream_pdu_fragment_t *stream_find_frag( stream_t *stream, guint32 framenum, guint32 offset ) { return fragment_hash_lookup( stream, framenum, offset ); } - + stream_pdu_fragment_t *stream_add_frag( stream_t *stream, guint32 framenum, guint32 offset, - tvbuff_t *tvb, packet_info *pinfo, gboolean more_frags ) + tvbuff_t *tvb, packet_info *pinfo, gboolean more_frags ) { - fragment_data *fd_head; + fragment_head *fd_head; stream_pdu_t *pdu; stream_pdu_fragment_t *frag_data; - g_assert(stream); + DISSECTOR_ASSERT(stream); /* check that this fragment is at the end of the stream */ - g_assert( framenum > stream->lastfrag_framenum || - (framenum == stream->lastfrag_framenum && offset > stream->lastfrag_offset)); + DISSECTOR_ASSERT( framenum > stream->lastfrag_framenum || + (framenum == stream->lastfrag_framenum && offset > stream->lastfrag_offset)); pdu = stream->current_pdu; if( pdu == NULL ) { - /* start a new pdu */ - pdu = stream->current_pdu = stream_new_pdu(stream); + /* start a new pdu */ + pdu = stream->current_pdu = stream_new_pdu(stream); } - + /* add it to the reassembly tables */ - fd_head = fragment_add_seq_next(tvb, 0, pinfo, pdu->id, - stream_fragment_table, stream_reassembled_table, - tvb_reported_length(tvb), more_frags); + fd_head = fragment_add_seq_next(&stream_reassembly_table, + tvb, 0, pinfo, pdu->id, NULL, + tvb_reported_length(tvb), more_frags); /* add it to our hash */ frag_data = fragment_hash_insert( stream, framenum, offset, tvb_reported_length(tvb)); frag_data -> pdu = pdu; if( fd_head != NULL ) { - /* if this was the last fragment, update the pdu data. - */ - pdu -> fd_head = fd_head; - - /* start a new pdu next time */ - stream->current_pdu = NULL; + /* if this was the last fragment, update the pdu data. + */ + pdu -> fd_head = fd_head; + + /* start a new pdu next time */ + stream->current_pdu = NULL; frag_data -> final_fragment = TRUE; } @@ -477,12 +436,12 @@ stream_pdu_fragment_t *stream_add_frag( stream_t *stream, guint32 framenum, guin tvbuff_t *stream_process_reassembled( tvbuff_t *tvb, int offset, packet_info *pinfo, - char *name, const stream_pdu_fragment_t *frag, + const char *name, const stream_pdu_fragment_t *frag, const struct _fragment_items *fit, gboolean *update_col_infop, proto_tree *tree) { stream_pdu_t *pdu; - g_assert(frag); + DISSECTOR_ASSERT(frag); pdu = frag->pdu; /* we handle non-terminal fragments ourselves, because @@ -499,21 +458,34 @@ tvbuff_t *stream_process_reassembled( return process_reassembled_data(tvb, offset, pinfo, name, pdu->fd_head, fit, update_col_infop, tree); } - + guint32 stream_get_frag_length( const stream_pdu_fragment_t *frag) { - g_assert( frag ); + DISSECTOR_ASSERT( frag ); return frag->len; } -fragment_data *stream_get_frag_data( const stream_pdu_fragment_t *frag) +fragment_head *stream_get_frag_data( const stream_pdu_fragment_t *frag) { - g_assert( frag ); + DISSECTOR_ASSERT( frag ); return frag->pdu->fd_head; } guint32 stream_get_pdu_no( const stream_pdu_fragment_t *frag) { - g_assert( frag ); + DISSECTOR_ASSERT( frag ); return frag->pdu->pdu_number; } + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */