diff options
author | John Thacker <johnthacker@gmail.com> | 2022-03-27 09:55:44 -0400 |
---|---|---|
committer | John Thacker <johnthacker@gmail.com> | 2022-04-06 07:53:02 -0400 |
commit | 444e3f230c78e9366abe874a0ca5e4e92d6fe94b (patch) | |
tree | 58bcf4a31e477078f8c07f3bd92251ea9a963e68 | |
parent | 4e184104afa46c99876da3e0d538f07f3eebaafe (diff) |
tcp reassembly: Add fragment_add_out_of_order
-rw-r--r-- | epan/reassemble.c | 44 | ||||
-rw-r--r-- | epan/reassemble.h | 21 | ||||
-rw-r--r-- | packaging/debian/libwireshark0.symbols | 1 |
3 files changed, 56 insertions, 10 deletions
diff --git a/epan/reassemble.c b/epan/reassemble.c index c38f994c56..3bc7d42090 100644 --- a/epan/reassemble.c +++ b/epan/reassemble.c @@ -993,7 +993,8 @@ MERGE_FRAG(fragment_head *fd_head, fragment_item *fd) static gboolean fragment_add_work(fragment_head *fd_head, tvbuff_t *tvb, const int offset, const packet_info *pinfo, const guint32 frag_offset, - const guint32 frag_data_len, const gboolean more_frags) + const guint32 frag_data_len, const gboolean more_frags, + const guint32 frag_frame) { fragment_item *fd; fragment_item *fd_i; @@ -1005,7 +1006,7 @@ fragment_add_work(fragment_head *fd_head, tvbuff_t *tvb, const int offset, fd = g_slice_new(fragment_item); fd->next = NULL; fd->flags = 0; - fd->frame = pinfo->num; + fd->frame = frag_frame; fd->offset = frag_offset; fd->fragment_nr_offset = 0; /* will only be used with sequence */ fd->len = frag_data_len; @@ -1338,7 +1339,8 @@ fragment_add_common(reassembly_table *table, tvbuff_t *tvb, const int offset, const packet_info *pinfo, const guint32 id, const void *data, const guint32 frag_offset, const guint32 frag_data_len, const gboolean more_frags, - const gboolean check_already_added) + const gboolean check_already_added, + const guint32 frag_frame) { fragment_head *fd_head; fragment_item *fd_item; @@ -1396,7 +1398,7 @@ fragment_add_common(reassembly_table *table, tvbuff_t *tvb, const int offset, * reassembly; if this frame is later than that * frame, we know it hasn't been added yet. */ - if (pinfo->num <= fd_head->frame) { + if (frag_frame <= fd_head->frame) { already_added = FALSE; /* * The first item in the reassembly list @@ -1406,7 +1408,7 @@ fragment_add_common(reassembly_table *table, tvbuff_t *tvb, const int offset, */ for (fd_item = fd_head->next; fd_item; fd_item = fd_item->next) { - if (pinfo->num == fd_item->frame && + if (frag_frame == fd_item->frame && frag_offset == fd_item->offset) { already_added = TRUE; break; @@ -1455,7 +1457,7 @@ fragment_add_common(reassembly_table *table, tvbuff_t *tvb, const int offset, * Is it later in the capture than all of the * fragments in the reassembly? */ - if (pinfo->num > fd_head->frame) { + if (frag_frame > fd_head->frame) { /* * Yes, so report this as a problem, * possibly a retransmission. @@ -1510,7 +1512,7 @@ fragment_add_common(reassembly_table *table, tvbuff_t *tvb, const int offset, } if (fragment_add_work(fd_head, tvb, offset, pinfo, frag_offset, - frag_data_len, more_frags)) { + frag_data_len, more_frags, frag_frame)) { /* * Reassembly is complete. */ @@ -1530,7 +1532,7 @@ fragment_add(reassembly_table *table, tvbuff_t *tvb, const int offset, const gboolean more_frags) { return fragment_add_common(table, tvb, offset, pinfo, id, data, - frag_offset, frag_data_len, more_frags, TRUE); + frag_offset, frag_data_len, more_frags, TRUE, pinfo->num); } /* @@ -1545,7 +1547,29 @@ fragment_add_multiple_ok(reassembly_table *table, tvbuff_t *tvb, const guint32 frag_data_len, const gboolean more_frags) { return fragment_add_common(table, tvb, offset, pinfo, id, data, - frag_offset, frag_data_len, more_frags, FALSE); + frag_offset, frag_data_len, more_frags, FALSE, pinfo->num); +} + +/* + * For use in protocols like TCP when you are adding an out of order segment + * that arrived in an earlier frame because the correct fragment id could not + * be determined until later. By allowing fd->frame to be different than + * pinfo->num, show_fragment_tree will display the correct fragment numbers. + * + * Note that pinfo is still used to set reassembled_in if we have all the + * fragments, so that results on subsequent passes can be the same as the + * first pass. + */ +fragment_head * +fragment_add_out_of_order(reassembly_table *table, tvbuff_t *tvb, + const int offset, const packet_info *pinfo, + const guint32 id, const void *data, + const guint32 frag_offset, + const guint32 frag_data_len, + const gboolean more_frags, const guint32 frag_frame) +{ + return fragment_add_common(table, tvb, offset, pinfo, id, data, + frag_offset, frag_data_len, more_frags, TRUE, frag_frame); } fragment_head * @@ -1594,7 +1618,7 @@ fragment_add_check(reassembly_table *table, tvbuff_t *tvb, const int offset, } if (fragment_add_work(fd_head, tvb, offset, pinfo, frag_offset, - frag_data_len, more_frags)) { + frag_data_len, more_frags, pinfo->num)) { /* * Reassembly is complete. * Remove this from the table of in-progress diff --git a/epan/reassemble.h b/epan/reassemble.h index 18613a63f8..8a2077c68d 100644 --- a/epan/reassemble.h +++ b/epan/reassemble.h @@ -213,6 +213,27 @@ fragment_add_multiple_ok(reassembly_table *table, tvbuff_t *tvb, const gboolean more_frags); /* + * Like fragment_add, except that the fragment may originate from a frame + * other than pinfo->num. For use when you are adding an out of order segment + * that arrived in an earlier frame, so that show_fragment_tree will display + * the correct fragment numbers. + * + * This is for protocols like TCP, where the correct reassembly to add a + * segment to cannot be determined without processing previous segments + * in sequence order, including handing them to subdissectors. + * + * Note that pinfo is still used to set reassembled_in if we have all the + * fragments, so that results on subsequent passes can be the same as the + * first pass. + */ +WS_DLL_PUBLIC fragment_head * +fragment_add_out_of_order(reassembly_table *table, tvbuff_t *tvb, + const int offset, const packet_info *pinfo, + const guint32 id, const void *data, + const guint32 frag_offset, + const guint32 frag_data_len, + const gboolean more_frags, const guint32 frag_frame); +/* * Like fragment_add, but maintains a table for completed reassemblies. * * If the packet was seen before, return the head of the fully reassembled diff --git a/packaging/debian/libwireshark0.symbols b/packaging/debian/libwireshark0.symbols index bd07423221..10628c6741 100644 --- a/packaging/debian/libwireshark0.symbols +++ b/packaging/debian/libwireshark0.symbols @@ -695,6 +695,7 @@ libwireshark.so.0 libwireshark0 #MINVER# fragment_add@Base 1.9.1 fragment_add_check@Base 1.9.1 fragment_add_multiple_ok@Base 1.9.1 + fragment_add_out_of_order@Base 3.7.0 fragment_add_seq@Base 1.9.1 fragment_add_seq_802_11@Base 1.9.1 fragment_add_seq_check@Base 1.9.1 |