Add a "fragment_add_multiple_ok()" routine that skips the check for a

fragment having been added already.  In protocols using the ONC
RPC-over-TCP record-marking mechanism (RPC-over-TCP and NDMP), there can
be more than one record-marking-layer fragment in a single TCP segment,
and thus can be more than one fragment in a frame being added to a given
higher-level packet.

svn path=/trunk/; revision=7508
This commit is contained in:
Guy Harris 2003-04-20 00:27:29 +00:00
parent ea29d0768a
commit 8140efea8e
3 changed files with 42 additions and 13 deletions

View File

@ -2,7 +2,7 @@
* Routines for rpc dissection
* Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
*
* $Id: packet-rpc.c,v 1.117 2003/04/18 06:34:42 sahlberg Exp $
* $Id: packet-rpc.c,v 1.118 2003/04/20 00:27:29 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -2651,8 +2651,8 @@ dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
/*
* Start defragmentation.
*/
ipfd_head = fragment_add(tvb, offset + 4, pinfo,
rfk->start_seq, rpc_fragment_table,
ipfd_head = fragment_add_multiple_ok(tvb, offset + 4,
pinfo, rfk->start_seq, rpc_fragment_table,
rfk->offset, len - 4, TRUE);
/*
@ -2700,14 +2700,15 @@ dissect_rpc_fragment(tvbuff_t *tvb, int offset, packet_info *pinfo,
* a record. This means we must defragment it.
* Add it to the defragmentation lists.
*/
ipfd_head = fragment_add(tvb, offset + 4, pinfo,
ipfd_head = fragment_add_multiple_ok(tvb, offset + 4, pinfo,
rfk->start_seq, rpc_fragment_table,
rfk->offset, len - 4, !(rpc_rm & RPC_RM_LASTFRAG));
if (ipfd_head == NULL) {
/*
* fragment_add() returned NULL, This means that
* defragmentation is not completed yet.
* fragment_add_multiple_ok() returned NULL.
* This means that defragmentation is not
* completed yet.
*
* We must add an entry to the hash table with
* the sequence number following this fragment

View File

@ -1,7 +1,7 @@
/* reassemble.c
* Routines for {fragment,segment} reassembly
*
* $Id: reassemble.c,v 1.33 2003/04/20 00:11:28 guy Exp $
* $Id: reassemble.c,v 1.34 2003/04/20 00:27:29 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -638,9 +638,10 @@ fragment_add_work(fragment_data *fd_head, tvbuff_t *tvb, int offset,
}
fragment_data *
fragment_add(tvbuff_t *tvb, int offset, packet_info *pinfo, guint32 id,
fragment_add_common(tvbuff_t *tvb, int offset, packet_info *pinfo, guint32 id,
GHashTable *fragment_table, guint32 frag_offset,
guint32 frag_data_len, gboolean more_frags)
guint32 frag_data_len, gboolean more_frags,
gboolean check_already_added)
{
fragment_key key, *new_key;
fragment_data *fd_head;
@ -660,8 +661,9 @@ fragment_add(tvbuff_t *tvb, int offset, packet_info *pinfo, guint32 id,
* we've already done all the reassembly and added all the
* fragments.
*
* If it's not true, just check if we have seen this fragment before,
* i.e., if we have already added it to reassembly.
* If it's not true, but "check_already_added" is true, just check
* if we have seen this fragment before, i.e., if we have already
* added it to reassembly.
* That can be true even if "pinfo->fd->flags.visited" is false
* since we sometimes might call a subdissector multiple times.
* As an additional check, just make sure we have not already added
@ -671,7 +673,7 @@ fragment_add(tvbuff_t *tvb, int offset, packet_info *pinfo, guint32 id,
* We don't check it because its "frame" member isn't initialized
* to anything, and because it doesn't count in any case.
*/
if (!already_added && fd_head != NULL) {
if (!already_added && check_already_added && fd_head != NULL) {
for(fd_item=fd_head->next;fd_item;fd_item=fd_item->next){
if(pinfo->fd->num==fd_item->frame){
already_added=TRUE;
@ -732,6 +734,29 @@ fragment_add(tvbuff_t *tvb, int offset, packet_info *pinfo, guint32 id,
}
}
fragment_data *
fragment_add(tvbuff_t *tvb, int offset, packet_info *pinfo, guint32 id,
GHashTable *fragment_table, guint32 frag_offset,
guint32 frag_data_len, gboolean more_frags)
{
return fragment_add_common(tvb, offset, pinfo, id, fragment_table,
frag_offset, frag_data_len, more_frags, TRUE);
}
/*
* For use when you can have multiple fragments in the same frame added
* to the same reassembled PDU, e.g. with ONC RPC-over-TCP.
*/
fragment_data *
fragment_add_multiple_ok(tvbuff_t *tvb, int offset, packet_info *pinfo,
guint32 id, GHashTable *fragment_table,
guint32 frag_offset, guint32 frag_data_len,
gboolean more_frags)
{
return fragment_add_common(tvb, offset, pinfo, id, fragment_table,
frag_offset, frag_data_len, more_frags, FALSE);
}
fragment_data *
fragment_add_check(tvbuff_t *tvb, int offset, packet_info *pinfo,
guint32 id, GHashTable *fragment_table,

View File

@ -1,7 +1,7 @@
/* reassemble.h
* Declarations of outines for {fragment,segment} reassembly
*
* $Id: reassemble.h,v 1.15 2003/04/20 00:11:28 guy Exp $
* $Id: reassemble.h,v 1.16 2003/04/20 00:27:29 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -93,6 +93,9 @@ void reassemble_init(void);
extern fragment_data *fragment_add(tvbuff_t *tvb, int offset, packet_info *pinfo,
guint32 id, GHashTable *fragment_table, guint32 frag_offset,
guint32 frag_data_len, gboolean more_frags);
extern fragment_data *fragment_add_multiple_ok(tvbuff_t *tvb, int offset,
packet_info *pinfo, guint32 id, GHashTable *fragment_table,
guint32 frag_offset, guint32 frag_data_len, gboolean more_frags);
extern fragment_data *fragment_add_check(tvbuff_t *tvb, int offset,
packet_info *pinfo, guint32 id, GHashTable *fragment_table,