aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorJeff Morriss <jeff.morriss@ulticom.com>2012-02-28 03:19:49 +0000
committerJeff Morriss <jeff.morriss@ulticom.com>2012-02-28 03:19:49 +0000
commit89cfdc35590c515e19654cddde7a7c1018f9ccc2 (patch)
treec87777778582b85628c9b87d197fcc16d8f47eee /epan
parent76652d9d4a65646af45bbaffa818b775a519bff2 (diff)
Fix https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=3315 -
make Save-As/Displayed/All-Packets save not only the displayed packets but also any other packets needed (e.g., for reassembly) to fully dissect the displayed packets. This works only for the "All packets" case; choosing only the Selected packet, the Marked packets, or a range of packets would require actually storing which packets depend on which (too much memory) or going through the packet list many times (too slow). Also, this behavior is always the case: you can't save the displayed packets without their dependencies (I don't see why this would be desirable). So far this is done for SCTP and things using the reassembly routines (TCP has been tested). The Win32 dialog was modified but hasn't been tested yet. One confusing aspect of the UI is that the Displayed count in the Save-As dialog does not match the number of displayed packets. (I tried renaming the button "Displayed + Dependencies" but it looked too big.) The tooltip tries to explain this and the fact that this works only in the All-Packets case; suggestions for improvement are welcome. Implementation details: Dissectors (or the reassembly code) can list frames which were needed to build the current frame's tree. If the current frame passes the display filter then each listed frame is marked as "depended upon" (this takes up the last free frame_data flag). When performing a Save-As/Displayed/All-Packets then choose packets which passed the dfilter _or_ are depended upon. svn path=/trunk/; revision=41216
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-sctp.c6
-rw-r--r--epan/epan.c2
-rw-r--r--epan/frame_data.c1
-rw-r--r--epan/frame_data.h1
-rw-r--r--epan/libwireshark.def1
-rw-r--r--epan/packet.c9
-rw-r--r--epan/packet.h8
-rw-r--r--epan/packet_info.h5
-rw-r--r--epan/reassemble.c8
9 files changed, 35 insertions, 6 deletions
diff --git a/epan/dissectors/packet-sctp.c b/epan/dissectors/packet-sctp.c
index de0f986f02..18fdfbb562 100644
--- a/epan/dissectors/packet-sctp.c
+++ b/epan/dissectors/packet-sctp.c
@@ -2356,6 +2356,8 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment* fragment,
frag_i->frame_num, "Frame: %u, payload: %u-%u (%u bytes)",
frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len);
offset += frag_i->len;
+
+ mark_frame_as_depended_upon(pinfo, frag_i->frame_num);
}
for (frag_i = msg->fragments;
@@ -2366,6 +2368,8 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment* fragment,
frag_i->frame_num, "Frame: %u, payload: %u-%u (%u bytes)",
frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len);
offset += frag_i->len;
+
+ mark_frame_as_depended_upon(pinfo, frag_i->frame_num);
}
} else {
for (frag_i = find_fragment(message->begin, stream_id, stream_seq_num);
@@ -2376,6 +2380,8 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment* fragment,
frag_i->frame_num, "Frame: %u, payload: %u-%u (%u bytes)",
frag_i->frame_num, offset, offset + frag_i->len - 1, frag_i->len);
offset += frag_i->len;
+
+ mark_frame_as_depended_upon(pinfo, frag_i->frame_num);
}
}
diff --git a/epan/epan.c b/epan/epan.c
index a74ee9538e..c61260a65f 100644
--- a/epan/epan.c
+++ b/epan/epan.c
@@ -172,6 +172,8 @@ epan_dissect_init(epan_dissect_t *edt, const gboolean create_proto_tree, const g
edt->tree = NULL;
}
+ edt->pi.dependent_frames = NULL;
+
return edt;
}
diff --git a/epan/frame_data.c b/epan/frame_data.c
index c757f9b1a9..6a456b1c69 100644
--- a/epan/frame_data.c
+++ b/epan/frame_data.c
@@ -207,6 +207,7 @@ frame_data_init(frame_data *fdata, guint32 num,
fdata->shift_offset.secs = 0;
fdata->shift_offset.nsecs = 0;
fdata->flags.passed_dfilter = 0;
+ fdata->flags.dependent_of_displayed = 0;
fdata->flags.encoding = PACKET_CHAR_ENC_CHAR_ASCII;
fdata->flags.visited = 0;
fdata->flags.marked = 0;
diff --git a/epan/frame_data.h b/epan/frame_data.h
index 5b25275f35..1a2c258ec9 100644
--- a/epan/frame_data.h
+++ b/epan/frame_data.h
@@ -51,6 +51,7 @@ typedef struct _frame_data {
gint16 lnk_t; /**< Per-packet encapsulation/data-link type */
struct {
unsigned int passed_dfilter : 1; /**< 1 = display, 0 = no display */
+ unsigned int dependent_of_displayed : 1; /**< 1 if a displayed frame depends on this frame */
unsigned int encoding : 2; /**< Character encoding (ASCII, EBCDIC...) */
unsigned int visited : 1; /**< Has this packet been visited yet? 1=Yes,0=No*/
unsigned int marked : 1; /**< 1 = marked by user, 0 = normal */
diff --git a/epan/libwireshark.def b/epan/libwireshark.def
index 02a6e837a0..b250865846 100644
--- a/epan/libwireshark.def
+++ b/epan/libwireshark.def
@@ -646,6 +646,7 @@ list_stat_cmd_args
llc_add_oui
LocationRejectReason_vals DATA
make_printable_string
+mark_frame_as_depended_upon
match_strrval
match_strrval_idx
match_strval
diff --git a/epan/packet.c b/epan/packet.c
index 135c8958e0..9cd70efa6a 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -238,6 +238,15 @@ free_data_sources(packet_info *pinfo)
}
}
+void
+mark_frame_as_depended_upon(packet_info *pinfo, guint32 frame_num)
+{
+ /* Don't mark a frame as dependent on itself */
+ if (frame_num != PINFO_FD_NUM(pinfo)) {
+ pinfo->dependent_frames = g_slist_prepend(pinfo->dependent_frames, GUINT_TO_POINTER(frame_num));
+ }
+}
+
/* Allow dissectors to register a "final_registration" routine
* that is run like the proto_register_XXX() routine, but at the
* end of the epan_init() function; that is, *after* all other
diff --git a/epan/packet.h b/epan/packet.h
index 5db3020061..51465216d9 100644
--- a/epan/packet.h
+++ b/epan/packet.h
@@ -447,6 +447,14 @@ extern const char* get_data_source_name(data_source *src);
*/
extern void free_data_sources(packet_info *pinfo);
+/* Mark another frame as depended upon by the current frame.
+ *
+ * This information is used to ensure that the dependend-upon frame is saved
+ * if the user does a File->Save-As of only the Displayed packets and the
+ * current frame passed the display filter.
+ */
+extern void mark_frame_as_depended_upon(packet_info *pinfo, guint32 frame_num);
+
/*
* Dissectors should never modify the packet data.
*/
diff --git a/epan/packet_info.h b/epan/packet_info.h
index 95e1045f46..49f444e76f 100644
--- a/epan/packet_info.h
+++ b/epan/packet_info.h
@@ -200,9 +200,8 @@ typedef struct _packet_info {
guint8 zbee_stack_vers; /* ZigBee stack version number, present in the ZigBee network layer, but
* impacts the packet format at all layers of the ZigBee stack.
*/
- int link_dir; /* 3GPP messages are sometime different UP link(UL) or Downlink(DL)
- *
- */
+ int link_dir; /* 3GPP messages are sometime different UP link(UL) or Downlink(DL) */
+ GSList* dependent_frames; /* A list of frames which this one depends on */
} packet_info;
/* For old code that hasn't yet been changed. */
diff --git a/epan/reassemble.c b/epan/reassemble.c
index 7a82c8a631..074861db8c 100644
--- a/epan/reassemble.c
+++ b/epan/reassemble.c
@@ -1898,7 +1898,8 @@ process_reassembled_data(tvbuff_t *tvb, const int offset, packet_info *pinfo,
*/
static void
show_fragment(fragment_data *fd, const int offset, const fragment_items *fit,
- proto_tree *ft, proto_item *fi, const gboolean first_frag, const guint32 count, tvbuff_t *tvb)
+ proto_tree *ft, proto_item *fi, const gboolean first_frag,
+ const guint32 count, tvbuff_t *tvb, packet_info *pinfo)
{
proto_item *fei=NULL;
int hf;
@@ -1942,6 +1943,7 @@ show_fragment(fragment_data *fd, const int offset, const fragment_items *fit,
plurality(fd->len, "", "s"));
}
PROTO_ITEM_SET_GENERATED(fei);
+ mark_frame_as_depended_upon(pinfo, fd->frame);
if (fd->flags & (FD_OVERLAP|FD_OVERLAPCONFLICT
|FD_MULTIPLETAILS|FD_TOOLONGFRAGMENT) ) {
/* this fragment has some flags set, create a subtree
@@ -2023,7 +2025,7 @@ show_fragment_tree(fragment_data *fd_head, const fragment_items *fit,
count++;
}
for (fd = fd_head->next; fd != NULL; fd = fd->next) {
- show_fragment(fd, fd->offset, fit, ft, *fi, first_frag, count, tvb);
+ show_fragment(fd, fd->offset, fit, ft, *fi, first_frag, count, tvb, pinfo);
first_frag = FALSE;
}
@@ -2077,7 +2079,7 @@ show_fragment_seq_tree(fragment_data *fd_head, const fragment_items *fit,
next_offset += fd->len;
}
last_fd = fd;
- show_fragment(fd, offset, fit, ft, *fi, first_frag, count, tvb);
+ show_fragment(fd, offset, fit, ft, *fi, first_frag, count, tvb, pinfo);
first_frag = FALSE;
}