When reassembly is off, catch ReportedBoundsError when calling a subdissector

on the first fragment of a fragmented message.  This allows us to continue
dissecting chunks even if one of the first chunks in the frame was fragmented.
(It's useful to keep doing this partial dissection just so we have some idea
what's in that chunk.)

(One could rightfully argue that you should only see a fragmented chunk
bundled with another chunk when retransmitting but, well, I'm staring at
traces of an implementation--to remain nameless to protect the guilty--which
is sometimes fragmenting and then bundling the fragments into one packet.)

svn path=/trunk/; revision=23471
This commit is contained in:
Jeff Morriss 2007-11-16 22:04:27 +00:00
parent 512833a4c1
commit 3fa633d626
2 changed files with 33 additions and 6 deletions

View File

@ -440,7 +440,7 @@ show_reported_bounds_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
*/
if (check_col(pinfo->cinfo, COL_INFO))
col_append_fstr(pinfo->cinfo, COL_INFO,
"[Unreassembled Packet%s]",
"[Unreassembled Packet%s] ",
pinfo->noreassembly_reason);
item = proto_tree_add_protocol_format(tree, proto_unreassembled,
tvb, 0, 0, "[Unreassembled Packet%s: %s]",

View File

@ -60,6 +60,7 @@
#include <epan/sctpppids.h>
#include <epan/emem.h>
#include <epan/expert.h>
#include <packet-frame.h>
#define LT(x, y) ((gint32)((x) - (y)) < 0)
@ -2622,12 +2623,14 @@ dissect_fragmented_payload(tvbuff_t *payload_tvb, packet_info *pinfo, proto_tree
/* add fragement to list of known fragments. returns NULL if segment is a duplicate */
fragment = add_fragment(payload_tvb, pinfo, chunk_tree, tsn, stream_id, stream_seq_num, b_bit, e_bit);
if (fragment) new_tvb = fragment_reassembly(payload_tvb, fragment, pinfo, chunk_tree, stream_id, stream_seq_num);
if (fragment)
new_tvb = fragment_reassembly(payload_tvb, fragment, pinfo, chunk_tree, stream_id, stream_seq_num);
/* pass reassembled data to next dissector, if possible */
if (new_tvb) return dissect_payload(new_tvb, pinfo, tree, ppi);
if (new_tvb)
return dissect_payload(new_tvb, pinfo, tree, ppi);
/* no reasemmbly done, do nothing */
/* no reassembly done, do nothing */
return TRUE;
}
@ -2740,14 +2743,38 @@ dissect_data_chunk(tvbuff_t *chunk_tvb,
* almost certainly not understand the data.
*/
if (b_bit)
return dissect_payload(payload_tvb, pinfo, tree, payload_proto_id);
{
gboolean retval;
/*
* If this particular fragment happens to get a ReportedBoundsError
* exception (which in fact we expect it to since it's a fragment),
* don't stop dissecting chunks within this frame.
*
* If it gets a BoundsError, we can stop, as there's nothing more to
* see, so we just re-throw it.
*/
TRY {
retval = dissect_payload(payload_tvb, pinfo, tree, payload_proto_id);
}
CATCH(BoundsError) {
RETHROW;
}
CATCH(ReportedBoundsError) {
show_reported_bounds_error(payload_tvb, pinfo, tree);
}
ENDTRY;
return retval;
}
/* else */
return FALSE;
}
/* if unordered set stream_seq_num to 0 for easier handling */
if (u_bit) stream_seq_num = 0;
if (u_bit)
stream_seq_num = 0;
/* start reassembly */
return dissect_fragmented_payload(payload_tvb, pinfo, tree, chunk_tree, tsn, payload_proto_id, stream_id, stream_seq_num, b_bit, e_bit);