[Reassembly] Fix a reassembly case where the two fragments are in the same

frame
but in different SCTP DATA chunks, whitout the patch the message is
reassembled in both chunks leading to duplicated upper layer PDU:s in the
frame.

Change-Id: Ie31142c38c728018178947544b571622447d8e8f
Reviewed-on: https://code.wireshark.org/review/7716
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
AndersBroman 2015-03-17 12:59:27 +01:00 committed by Anders Broman
parent ae2d2447d8
commit 98b7f21370
2 changed files with 30 additions and 20 deletions

View File

@ -819,6 +819,7 @@ fragment_reassembled(reassembly_table *table, fragment_head *fd_head,
}
fd_head->flags |= FD_DEFRAGMENTED;
fd_head->reassembled_in = pinfo->fd->num;
fd_head->reas_in_layer_num = pinfo->curr_layer_num;
}
static void
@ -909,6 +910,7 @@ fragment_add_work(fragment_head *fd_head, tvbuff_t *tvb, const int offset,
fd_head->flags &= (~FD_TOOLONGFRAGMENT) & (~FD_MULTIPLETAILS);
fd_head->datalen=0;
fd_head->reassembled_in=0;
fd_head->reas_in_layer_num = 0;
} else {
/*
* No. Bail out since we have no idea what to
@ -1187,6 +1189,7 @@ fragment_add_work(fragment_head *fd_head, tvbuff_t *tvb, const int offset,
allows us to skip any trailing fragments */
fd_head->flags |= FD_DEFRAGMENTED;
fd_head->reassembled_in=pinfo->fd->num;
fd_head->reas_in_layer_num = pinfo->curr_layer_num;
/* we don't throw until here to avoid leaking old_data and others */
if (fd_head->error) {
@ -1538,6 +1541,7 @@ fragment_defragment_and_free (fragment_head *fd_head, const packet_info *pinfo)
*/
fd_head->flags |= FD_DEFRAGMENTED;
fd_head->reassembled_in=pinfo->fd->num;
fd_head->reas_in_layer_num = pinfo->curr_layer_num;
}
/*
@ -1595,6 +1599,7 @@ fragment_add_seq_work(fragment_head *fd_head, tvbuff_t *tvb, const int offset,
fd_head->flags &= (~FD_TOOLONGFRAGMENT) & (~FD_MULTIPLETAILS);
fd_head->datalen=0;
fd_head->reassembled_in=0;
fd_head->reas_in_layer_num = 0;
}
@ -1843,6 +1848,7 @@ fragment_add_seq_common(reassembly_table *table, tvbuff_t *tvb,
if (orig_keyp != NULL)
*orig_keyp = NULL;
fd_head->reassembled_in=pinfo->fd->num;
fd_head->reas_in_layer_num = pinfo->curr_layer_num;
return fd_head;
}
@ -2088,6 +2094,7 @@ fragment_start_seq_check(reassembly_table *table, const packet_info *pinfo,
fd_head->flags = FD_BLOCKSEQUENCE|FD_DATALEN_SET;
fd_head->tvb_data = NULL;
fd_head->reassembled_in = 0;
fd_head->reas_in_layer_num = 0;
fd_head->error = NULL;
insert_fd_head(table, fd_head, pinfo, id, data);
@ -2167,7 +2174,7 @@ process_reassembled_data(tvbuff_t *tvb, const int offset, packet_info *pinfo,
gboolean update_col_info;
proto_item *frag_tree_item;
if (fd_head != NULL && pinfo->fd->num == fd_head->reassembled_in) {
if (fd_head != NULL && pinfo->fd->num == fd_head->reassembled_in && pinfo->curr_layer_num == fd_head->reas_in_layer_num) {
/*
* OK, we've reassembled this.
* Is this something that's been reassembled from more

View File

@ -70,26 +70,29 @@
typedef struct _fragment_item {
struct _fragment_item *next;
guint32 frame; /* XXX - does this apply to reassembly heads? */
guint32 offset; /* XXX - does this apply to reassembly heads? */
guint32 len; /* XXX - does this apply to reassembly heads? */
guint32 fragment_nr_offset; /* offset for frame numbering, for sequences, where the
* provided fragment number of the first fragment does
* not start with 0
* XXX - does this apply only to reassembly heads? */
guint32 datalen; /* Only valid in first item of list and when
* flags&FD_DATALEN_SET is set;
* number of bytes or (if flags&FD_BLOCKSEQUENCE set)
* segments in the datagram */
guint32 reassembled_in; /* frame where this PDU was reassembled,
only valid in the first item of the list
and when FD_DEFRAGMENTED is set*/
guint32 flags; /* XXX - do some of these apply only to reassembly
heads and others only to fragments within
a reassembly? */
guint32 frame; /* XXX - does this apply to reassembly heads? */
guint32 offset; /* XXX - does this apply to reassembly heads? */
guint32 len; /* XXX - does this apply to reassembly heads? */
guint32 fragment_nr_offset; /**< offset for frame numbering, for sequences, where the
* provided fragment number of the first fragment does
* not start with 0
* XXX - does this apply only to reassembly heads? */
guint32 datalen; /**< Only valid in first item of list and when
* flags&FD_DATALEN_SET is set;
* number of bytes or (if flags&FD_BLOCKSEQUENCE set)
* segments in the datagram */
guint32 reassembled_in; /**< frame where this PDU was reassembled,
only valid in the first item of the list
and when FD_DEFRAGMENTED is set*/
guint8 reas_in_layer_num; /**< The current "depth" or layer number in the current frame where reassembly was completed.
* Example: in SCTP there can be several data chunks and we want the reassemblied tvb for the final
* segment only.
*/
guint32 flags; /**< XXX - do some of these apply only to reassembly
heads and others only to fragments within
a reassembly? */
tvbuff_t *tvb_data;
/*
/**
* Null if the reassembly had no error; non-null if it had
* an error, in which case it's the string for the error.
*