aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Lamping <ulf.lamping@web.de>2005-09-12 00:16:57 +0000
committerUlf Lamping <ulf.lamping@web.de>2005-09-12 00:16:57 +0000
commit55c3e85a95f7c2d6d695f0e1244c307006ab31e6 (patch)
tree38bc6ea2dcbe1c0d0545f2f43fbb7943e720fcb7
parentaee0e1600b1b600d64f46d361ed73aae6e4fe0fd (diff)
fix reassembling problem I've introduced yesterday, by using fragment_add_seq_next() function instead of fragment_add()
in addition, I had to implement fragment_get_reassembled() in addition to fragment_get(), which works with reassembled_table svn path=/trunk/; revision=15762
-rw-r--r--epan/dissectors/packet-dcerpc.c78
-rw-r--r--epan/reassemble.c21
-rw-r--r--epan/reassemble.h4
3 files changed, 35 insertions, 68 deletions
diff --git a/epan/dissectors/packet-dcerpc.c b/epan/dissectors/packet-dcerpc.c
index 494d5944ae..846e721381 100644
--- a/epan/dissectors/packet-dcerpc.c
+++ b/epan/dissectors/packet-dcerpc.c
@@ -519,19 +519,24 @@ get_next_di(void)
static gboolean dcerpc_cn_desegment = TRUE;
/* reassemble DCE/RPC fragments */
-/* reassembly of dcerpc fragments will not work for the case where ONE frame
+/* reassembly of cl dcerpc fragments will not work for the case where ONE frame
might contain multiple dcerpc fragments for different PDUs.
this case would be so unusual/weird so if you got captures like that:
too bad
+
+ reassembly of co dcerpc fragments will not work for the case where TCP/SMB frames
+ are coming in out of sequence, but that will hurt in a lot of other places as well.
*/
static gboolean dcerpc_reassemble = FALSE;
+static GHashTable *dcerpc_co_fragment_table = NULL;
static GHashTable *dcerpc_co_reassemble_table = NULL;
static GHashTable *dcerpc_cl_reassemble_table = NULL;
static void
dcerpc_reassemble_init(void)
{
- fragment_table_init(&dcerpc_co_reassemble_table);
+ fragment_table_init(&dcerpc_co_fragment_table);
+ reassembled_table_init(&dcerpc_co_reassemble_table);
dcerpc_fragment_table_init(&dcerpc_cl_reassemble_table);
}
@@ -2956,7 +2961,7 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
gint length, reported_length;
gboolean save_fragmented;
fragment_data *fd_head=NULL;
- guint32 tot_len;
+
tvbuff_t *auth_tvb, *payload_tvb, *decrypted_tvb;
proto_item *pi;
proto_item *parent_pi;
@@ -3075,7 +3080,7 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
then exit
*/
if(pinfo->fd->flags.visited){
- fd_head=fragment_get(pinfo, frame, dcerpc_co_reassemble_table);
+ fd_head=fragment_get_reassembled(pinfo, frame, dcerpc_co_reassemble_table);
goto end_cn_stub;
}
@@ -3106,65 +3111,16 @@ dissect_dcerpc_cn_stub (tvbuff_t *tvb, int offset, packet_info *pinfo,
goto end_cn_stub;
}
- /* defragmentation is a bit tricky here, as there's no offset of the fragment
+ /* defragmentation is a bit tricky, as there's no offset of the fragment
* in the protocol data.
*
- * The allocation hint will contain the remaining bytes of all fragments following.
- *
- * Currently two possible ways:
- * - the transmitter sends an alloc_hint != 0, use it
- * - the transmitter sends an alloc_hint == 0, simply append fragments
- */
-
- /* if this is the first fragment we need to start reassembly
+ * just use fragment_add_seq_next() and hope that TCP/SMB segments coming
+ * in with the correct sequence.
*/
- if(hdr->flags&PFC_FIRST_FRAG){
- fragment_add(decrypted_tvb, 0, pinfo, frame,
- dcerpc_co_reassemble_table,
- 0 /* fragment offset */, tvb_length(decrypted_tvb), TRUE /* more_frags */);
- fragment_set_tot_len(pinfo, frame,
- dcerpc_co_reassemble_table, alloc_hint ? alloc_hint : tvb_length(decrypted_tvb));
-
- goto end_cn_stub;
- }
-
- /* if this is a middle fragment, just add it and exit */
- if(!(hdr->flags&PFC_LAST_FRAG)){
- tot_len = fragment_get_tot_len(pinfo, frame,
- dcerpc_co_reassemble_table);
- if(alloc_hint == 0) {
- fragment_set_tot_len(pinfo, frame,
- dcerpc_co_reassemble_table, tot_len + tvb_length(decrypted_tvb));
- } else {
- /* the alloc_hint shouldn't be larger than the expected remaining length */
- if(alloc_hint > (tot_len - tvb_length(decrypted_tvb))) {
- THROW(ReportedBoundsError);
- }
- }
- fragment_add(decrypted_tvb, 0, pinfo, frame,
- dcerpc_co_reassemble_table,
- tot_len-alloc_hint /* fragment offset */, tvb_length(decrypted_tvb),
- TRUE /* more_frags */);
-
- goto end_cn_stub;
- }
-
- /* this was the last fragment add it to reassembly
- */
- tot_len = fragment_get_tot_len(pinfo, frame,
- dcerpc_co_reassemble_table);
- /* the alloc_hint shouldn't be larger than the expected remaining length */
- if(alloc_hint != 0 && alloc_hint > (tot_len - tvb_length(decrypted_tvb))) {
- THROW(ReportedBoundsError);
- }
- fd_head = fragment_add(decrypted_tvb, 0, pinfo, frame,
- dcerpc_co_reassemble_table,
- tot_len-alloc_hint /* fragment offset */, tvb_length(decrypted_tvb),
- FALSE /* more_frags */);
- if(alloc_hint == 0) {
- fragment_set_tot_len(pinfo, frame,
- dcerpc_co_reassemble_table, tot_len + tvb_length(decrypted_tvb));
- }
+ fd_head = fragment_add_seq_next(decrypted_tvb, 0, pinfo, frame,
+ dcerpc_co_fragment_table, dcerpc_co_reassemble_table,
+ tvb_length(decrypted_tvb),
+ hdr->flags&PFC_LAST_FRAG ? FALSE : TRUE /* more_frags */);
end_cn_stub:
@@ -3178,7 +3134,7 @@ end_cn_stub:
tvbuff_t *next_tvb;
proto_item *frag_tree_item;
- next_tvb = tvb_new_real_data(fd_head->data, fd_head->datalen, fd_head->datalen);
+ next_tvb = tvb_new_real_data(fd_head->data, fd_head->len, fd_head->len);
tvb_set_child_real_data_tvbuff(decrypted_tvb, next_tvb);
add_new_data_source(pinfo, next_tvb, "Reassembled DCE/RPC");
show_fragment_tree(fd_head, &dcerpc_frag_items,
diff --git a/epan/reassemble.c b/epan/reassemble.c
index 688e07d405..2c43fd786f 100644
--- a/epan/reassemble.c
+++ b/epan/reassemble.c
@@ -386,6 +386,20 @@ fragment_get(packet_info *pinfo, guint32 id, GHashTable *fragment_table)
return fd_head;
}
+fragment_data *
+fragment_get_reassembled(packet_info *pinfo, guint32 id, GHashTable *reassembled_table)
+{
+ fragment_data *fd_head;
+ reassembled_key key;
+
+ /* create key to search hash with */
+ key.frame = id;
+ key.id = id;
+ fd_head = g_hash_table_lookup(reassembled_table, &key);
+
+ return fd_head;
+}
+
/* This function can be used to explicitely set the total length (if known)
* for reassembly of a PDU.
* This is useful for reassembly of PDUs where one may have the total length specified
@@ -711,13 +725,6 @@ fragment_add_work(fragment_data *fd_head, tvbuff_t *tvb, int offset,
fd_head->flags |= FD_TOOLONGFRAGMENT;
}
- if(more_frags) {
- /* dissector told us, that this isn't the last fragment,
- * trust this information and don't try to defragment for now.
- */
- return FALSE;
- }
-
/* we have received an entire packet, defragment it and
* free all fragments
*/
diff --git a/epan/reassemble.h b/epan/reassemble.h
index e0598da225..69ebf94e1f 100644
--- a/epan/reassemble.h
+++ b/epan/reassemble.h
@@ -200,6 +200,10 @@ fragment_set_partial_reassembly(packet_info *pinfo, guint32 id, GHashTable *frag
extern fragment_data *
fragment_get(packet_info *pinfo, guint32 id, GHashTable *fragment_table);
+/* The same for the reassemble table */
+extern fragment_data *
+fragment_get_reassembled(packet_info *pinfo, guint32 id, GHashTable *reassembled_table);
+
/* This will free up all resources and delete reassembly state for this PDU.
* Except if the PDU is completely reassembled, then it would NOT deallocate the
* buffer holding the reassembled data but instead return the pointer to that