aboutsummaryrefslogtreecommitdiffstats
path: root/file.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2009-09-11 11:58:00 +0000
committerAnders Broman <anders.broman@ericsson.com>2009-09-11 11:58:00 +0000
commit0772dd06b4f7395cceb3daee19de97f34e83b08f (patch)
tree170a3f0ffa7b3104bed415f2ff30fd8bbd2ba780 /file.c
parent72a86ea5c5ffa5b3f9539d85a41ef0678975995b (diff)
New_packet_list
Select the correct frame in packet details when filtering. svn path=/trunk/; revision=29857
Diffstat (limited to 'file.c')
-rw-r--r--file.c344
1 files changed, 316 insertions, 28 deletions
diff --git a/file.c b/file.c
index 3a2bd9d2c4..e206d564b5 100644
--- a/file.c
+++ b/file.c
@@ -1667,8 +1667,11 @@ cf_redissect_packets(capture_file *cf)
any state information they have (because a preference that affects
some dissector has changed, meaning some dissector might construct
its state differently from the way it was constructed the last time). */
+
+/* Rescan packets with "old" packet list */
+#ifndef NEW_PACKET_LIST
static void
-rescan_packets(capture_file *cf, const char *action, const char *action_item,
+rescan_packets_old(capture_file *cf, const char *action, const char *action_item,
gboolean refilter, gboolean redissect)
{
frame_data *fdata;
@@ -1689,11 +1692,7 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
dfilter_t *dfcode;
gboolean filtering_tap_listeners;
guint tap_flags;
-#ifdef NEW_PACKET_LIST
- gboolean add_to_packet_list = FALSE;
-#else
gboolean add_to_packet_list = TRUE;
-#endif
/* Compile the current display filter.
* We assume this will not fail since cf->dfilter is only set in
@@ -1724,14 +1723,10 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
/* Freeze the packet list while we redo it, so we don't get any
screen updates while it happens. */
-#ifdef NEW_PACKET_LIST
- new_packet_list_freeze();
-#else
packet_list_freeze();
/* Clear it out. */
packet_list_clear();
-#endif
if (redissect) {
/* We need to re-initialize all the state information that protocols
@@ -1748,12 +1743,6 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
/* Initialize all data structures used for dissection. */
init_dissection();
-#ifdef NEW_PACKET_LIST
- /* We need to redissect the packets so we have to discard our old
- * packet list store. */
- new_packet_list_clear();
- add_to_packet_list = TRUE;
-#endif
}
/* We don't yet know which will be the first and last frames displayed. */
@@ -1898,11 +1887,6 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
/* We are done redissecting the packet list. */
cf->redissecting = FALSE;
-#ifndef NEW_PACKET_LIST
- /* Re-sort the list using the previously selected order */
- packet_list_set_sort_column();
-#endif
-
if (redissect) {
/* Clear out what remains of the visited flags and per-frame data
pointers.
@@ -1928,13 +1912,7 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
destroy_progress_dlg(progbar);
/* Unfreeze the packet list. */
-#ifdef NEW_PACKET_LIST
- if (!add_to_packet_list)
- new_packet_list_recreate_visible_rows();
- new_packet_list_thaw();
-#else
packet_list_thaw();
-#endif
if (selected_row == -1) {
/* The selected frame didn't pass the filter. */
@@ -1973,7 +1951,6 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
/* There are no frames displayed at all. */
cf_unselect_packet(cf);
} else {
-#ifndef NEW_PACKET_LIST
/* Either the frame that was selected passed the filter, or we've
found the nearest displayed frame to that frame. Select it, make
it the focus row, and make it visible. */
@@ -1982,7 +1959,6 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
cf->current_row = -1;
}
packet_list_set_selected_row(selected_row);
-#endif /* NEW_PACKET_LIST */
}
/* Cleanup and release all dfilter resources */
@@ -1990,6 +1966,318 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
dfilter_free(dfcode);
}
}
+#endif /* NEW_PACKET_LIST rescan_packets_old*/
+
+static void
+rescan_packets(capture_file *cf, const char *action, const char *action_item,
+ gboolean refilter, gboolean redissect)
+{
+#ifndef NEW_PACKET_LIST
+ rescan_packets_old(cf, action, action_item, refilter, redissect);
+}
+#else
+ /* Rescan packets new packet list */
+ frame_data *fdata;
+ progdlg_t *progbar = NULL;
+ gboolean stop_flag;
+ int count;
+ int err;
+ gchar *err_info;
+ frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
+ int selected_frame_num, preceding_frame_num, following_frame_num, prev_frame_num;
+ gboolean selected_frame_seen;
+ int frame_num;
+ float progbar_val;
+ GTimeVal start_time;
+ gchar status_str[100];
+ int progbar_nextstep;
+ int progbar_quantum;
+ dfilter_t *dfcode;
+ gboolean filtering_tap_listeners;
+ guint tap_flags;
+ gboolean add_to_packet_list = FALSE;
+
+ /* Compile the current display filter.
+ * We assume this will not fail since cf->dfilter is only set in
+ * cf_filter IFF the filter was valid.
+ */
+ dfcode=NULL;
+ if(cf->dfilter){
+ dfilter_compile(cf->dfilter, &dfcode);
+ }
+
+ /* Do we have any tap listeners with filters? */
+ filtering_tap_listeners = have_filtering_tap_listeners();
+
+ /* Get the union of the flags for all tap listeners. */
+ tap_flags = union_of_tap_listener_flags();
+
+ cum_bytes=0;
+ reset_tap_listeners();
+ /* Which frame, if any, is the currently selected frame?
+ XXX - should the selected frame or the focus frame be the "current"
+ frame, that frame being the one from which "Find Frame" searches
+ start? */
+ selected_frame = cf->current_frame;
+
+ /* Mark frane num as not found */
+ selected_frame_num = -1;
+
+ /* Freeze the packet list while we redo it, so we don't get any
+ screen updates while it happens. */
+ new_packet_list_freeze();
+
+ if (redissect) {
+ /* We need to re-initialize all the state information that protocols
+ keep, because some preference that controls a dissector has changed,
+ which might cause the state information to be constructed differently
+ by that dissector. */
+
+ /* We might receive new packets while redissecting, and we don't
+ want to dissect those before their time. */
+ cf->redissecting = TRUE;
+
+ /* Cleanup all data structures used for dissection. */
+ cleanup_dissection();
+ /* Initialize all data structures used for dissection. */
+ init_dissection();
+
+ /* We need to redissect the packets so we have to discard our old
+ * packet list store. */
+ new_packet_list_clear();
+ add_to_packet_list = TRUE;
+ }
+
+ /* We don't yet know which will be the first and last frames displayed. */
+ cf->first_displayed = NULL;
+ cf->last_displayed = NULL;
+
+ reset_elapsed();
+
+ /* We currently don't display any packets */
+ cf->displayed_count = 0;
+
+ /* Iterate through the list of frames. Call a routine for each frame
+ to check whether it should be displayed and, if so, add it to
+ the display list. */
+ nstime_set_unset(&first_ts);
+ nstime_set_unset(&prev_dis_ts);
+
+ /* Update the progress bar when it gets to this value. */
+ progbar_nextstep = 0;
+ /* When we reach the value that triggers a progress bar update,
+ bump that value by this amount. */
+ progbar_quantum = cf->count/N_PROGBAR_UPDATES;
+ /* Count of packets at which we've looked. */
+ count = 0;
+ /* Progress so far. */
+ progbar_val = 0.0f;
+
+ stop_flag = FALSE;
+ g_get_current_time(&start_time);
+
+ /* no previous row yet */
+ frame_num = -1;
+ prev_frame_num = -1;
+ prev_frame = NULL;
+
+ preceding_frame_num = -1;
+ preceding_frame = NULL;
+ following_frame_num = -1;
+ following_frame = NULL;
+
+ selected_frame_seen = FALSE;
+
+ for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
+ /* Create the progress bar if necessary.
+ We check on every iteration of the loop, so that it takes no
+ longer than the standard time to create it (otherwise, for a
+ large file, we might take considerably longer than that standard
+ time in order to get to the next progress bar step). */
+ if (progbar == NULL)
+ progbar = delayed_create_progress_dlg(action, action_item, TRUE,
+ &stop_flag, &start_time,
+ progbar_val);
+
+ /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
+ when we update it, we have to run the GTK+ main loop to get it
+ to repaint what's pending, and doing so may involve an "ioctl()"
+ to see if there's any pending input from an X server, and doing
+ that for every packet can be costly, especially on a big file. */
+ if (count >= progbar_nextstep) {
+ /* let's not divide by zero. I should never be started
+ * with count == 0, so let's assert that
+ */
+ g_assert(cf->count > 0);
+ progbar_val = (gfloat) count / cf->count;
+
+ if (progbar != NULL) {
+ g_snprintf(status_str, sizeof(status_str),
+ "%4u of %u frames", count, cf->count);
+ update_progress_dlg(progbar, progbar_val, status_str);
+ }
+
+ progbar_nextstep += progbar_quantum;
+ }
+
+ if (stop_flag) {
+ /* Well, the user decided to abort the filtering. Just stop.
+
+ XXX - go back to the previous filter? Users probably just
+ want not to wait for a filtering operation to finish;
+ unless we cancel by having no filter, reverting to the
+ previous filter will probably be even more expensive than
+ continuing the filtering, as it involves going back to the
+ beginning and filtering, and even with no filter we currently
+ have to re-generate the entire clist, which is also expensive.
+
+ I'm not sure what Network Monitor does, but it doesn't appear
+ to give you an unfiltered display if you cancel. */
+ break;
+ }
+
+ count++;
+
+ if (redissect) {
+ /* Since all state for the frame was destroyed, mark the frame
+ * as not visited, free the GSList referring to the state
+ * data (the per-frame data itself was freed by
+ * "init_dissection()"), and null out the GSList pointer. */
+ fdata->flags.visited = 0;
+ if (fdata->pfd) {
+ g_slist_free(fdata->pfd);
+ fdata->pfd = NULL;
+ }
+ }
+
+ if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
+ cf->pd, fdata->cap_len, &err, &err_info)) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ cf_read_error_message(err, err_info), cf->filename);
+ break;
+ }
+
+ /* If the previous frame is displayed, and we haven't yet seen the
+ selected frame, remember that frame - it's the closest one we've
+ yet seen before the selected frame. */
+ if (prev_frame_num != -1 && !selected_frame_seen && prev_frame->flags.passed_dfilter) {
+ preceding_frame_num = prev_frame_num;
+ preceding_frame = prev_frame;
+ }
+ add_packet_to_packet_list(fdata, cf, dfcode, filtering_tap_listeners,
+ tap_flags, &cf->pseudo_header, cf->pd,
+ refilter,
+ add_to_packet_list);
+
+ /* If this frame is displayed, and this is the first frame we've
+ seen displayed after the selected frame, remember this frame -
+ it's the closest one we've yet seen at or after the selected
+ frame. */
+ if (fdata->flags.passed_dfilter && selected_frame_seen && following_frame_num == -1) {
+ following_frame_num = fdata->num;
+ following_frame = fdata;
+ }
+ if (fdata == selected_frame) {
+ selected_frame_seen = TRUE;
+ if (fdata->flags.passed_dfilter)
+ selected_frame_num = fdata->num;
+ }
+
+ /* Remember this frame - it'll be the previous frame
+ on the next pass through the loop. */
+ prev_frame_num = fdata->num;
+ prev_frame = fdata;
+ }
+
+ /* We are done redissecting the packet list. */
+ cf->redissecting = FALSE;
+
+ if (redissect) {
+ /* Clear out what remains of the visited flags and per-frame data
+ pointers.
+
+ XXX - that may cause various forms of bogosity when dissecting
+ these frames, as they won't have been seen by this sequential
+ pass, but the only alternative I see is to keep scanning them
+ even though the user requested that the scan stop, and that
+ would leave the user stuck with an Wireshark grinding on
+ until it finishes. Should we just stick them with that? */
+ for (; fdata != NULL; fdata = fdata->next) {
+ fdata->flags.visited = 0;
+ if (fdata->pfd) {
+ g_slist_free(fdata->pfd);
+ fdata->pfd = NULL;
+ }
+ }
+ }
+
+ /* We're done filtering the packets; destroy the progress bar if it
+ was created. */
+ if (progbar != NULL)
+ destroy_progress_dlg(progbar);
+
+ /* Unfreeze the packet list. */
+ if (!add_to_packet_list)
+ new_packet_list_recreate_visible_rows();
+
+ new_packet_list_thaw();
+
+ if (selected_frame_num == -1) {
+ /* The selected frame didn't pass the filter. */
+ if (selected_frame == NULL) {
+ /* That's because there *was* no selected frame. Make the first
+ displayed frame the current frame. */
+ selected_frame_num = 0;
+ } else {
+ /* Find the nearest displayed frame to the selected frame (whether
+ it's before or after that frame) and make that the current frame.
+ If the next and previous displayed frames are equidistant from the
+ selected frame, choose the next one. */
+ g_assert(following_frame == NULL ||
+ following_frame->num >= selected_frame->num);
+ g_assert(preceding_frame == NULL ||
+ preceding_frame->num <= selected_frame->num);
+ if (following_frame == NULL) {
+ /* No frame after the selected frame passed the filter, so we
+ have to select the last displayed frame before the selected
+ frame. */
+ selected_frame_num = preceding_frame_num;
+ selected_frame = preceding_frame;
+ } else if (preceding_frame == NULL) {
+ /* No frame before the selected frame passed the filter, so we
+ have to select the first displayed frame after the selected
+ frame. */
+ selected_frame_num = following_frame_num;
+ selected_frame = following_frame;
+ } else {
+ /* Frames before and after the selected frame passed the filter, so
+ we'll select the previous frame */
+ selected_frame_num = preceding_frame_num;
+ selected_frame = preceding_frame;
+ }
+ }
+ }
+
+ if (selected_frame_num == -1) {
+ /* There are no frames displayed at all. */
+ cf_unselect_packet(cf);
+ } else {
+ /* Either the frame that was selected passed the filter, or we've
+ found the nearest displayed frame to that frame. Select it, make
+ it the focus row, and make it visible. */
+ if (selected_frame_num == 0) {
+ new_packet_list_select_first_row();
+ }else{
+ new_packet_list_find_row_from_data(selected_frame, TRUE);
+ }
+ }
+
+ /* Cleanup and release all dfilter resources */
+ if (dfcode != NULL){
+ dfilter_free(dfcode);
+ }
+}
+#endif /* NEW_PACKET_LIST */
/*
* Scan trough all frame data and recalculate the ref time
* without rereading the file.