Backport r29665 to template file so that the change is not overwritten when we regene...
[obnox/wireshark/wip.git] / file.c
diff --git a/file.c b/file.c
index baf82c407c2703a8c2e3cb3bef977829985dd1c8..18275993f51ab24fde502f42f1227dd208c7126f 100644 (file)
--- a/file.c
+++ b/file.c
@@ -51,6 +51,7 @@
 #include "cfile.h"
 #include <epan/column.h>
 #include <epan/packet.h>
+#include <epan/column-utils.h>
 #include "packet-range.h"
 #include "print.h"
 #include "file.h"
 #include <epan/timestamp.h>
 #include <epan/dfilter/dfilter-macro.h>
 #include <wsutil/file_util.h>
-#include <epan/column-utils.h>
 #include <epan/strutil.h>
 
 #ifdef HAVE_LIBPCAP
 gboolean auto_scroll_live;
 #endif
 
+static guint32 cum_bytes;
 static nstime_t first_ts;
 static nstime_t prev_dis_ts;
-static guint32 cum_bytes = 0;
+static nstime_t prev_cap_ts;
+
+static gulong computed_elapsed;
 
 static void cf_reset_state(capture_file *cf);
 
-static int read_packet(capture_file *cf, dfilter_t *dfcode, gint64 offset);
+static int read_packet(capture_file *cf, dfilter_t *dfcode,
+    gboolean filtering_tap_listeners, guint tap_flags, gint64 offset);
 
 static void rescan_packets(capture_file *cf, const char *action, const char *action_item,
-       gboolean refilter, gboolean redissect);
+    gboolean refilter, gboolean redissect);
 
 static gboolean match_protocol_tree(capture_file *cf, frame_data *fdata,
-       void *criterion);
+    void *criterion);
 static void match_subtree_text(proto_node *node, gpointer data);
 static gboolean match_summary_line(capture_file *cf, frame_data *fdata,
-       void *criterion);
+    void *criterion);
 static gboolean match_ascii_and_unicode(capture_file *cf, frame_data *fdata,
-       void *criterion);
+    void *criterion);
 static gboolean match_ascii(capture_file *cf, frame_data *fdata,
-       void *criterion);
+    void *criterion);
 static gboolean match_unicode(capture_file *cf, frame_data *fdata,
-       void *criterion);
+    void *criterion);
 static gboolean match_binary(capture_file *cf, frame_data *fdata,
-       void *criterion);
+    void *criterion);
 static gboolean match_dfilter(capture_file *cf, frame_data *fdata,
-       void *criterion);
+    void *criterion);
 static gboolean find_packet(capture_file *cf,
-       gboolean (*match_function)(capture_file *, frame_data *, void *),
-       void *criterion);
+    gboolean (*match_function)(capture_file *, frame_data *, void *),
+    void *criterion);
 
 static void cf_open_failure_alert_box(const char *filename, int err,
-                                     gchar *err_info, gboolean for_writing,
-                                     int file_type);
+                      gchar *err_info, gboolean for_writing,
+                      int file_type);
 static const char *file_rename_error_message(int err);
 static void cf_write_failure_alert_box(const char *filename, int err);
 static void cf_close_failure_alert_box(const char *filename, int err);
-
+#ifdef NEW_PACKET_LIST
+static void ref_time_packets(capture_file *cf);
+#endif
 /* Update the progress bar this many times when reading a file. */
-#define N_PROGBAR_UPDATES      100
+#define N_PROGBAR_UPDATES   100
+/* We read around 200k/100ms domt update the progress bar more often than that */
+#define MIN_QUANTUM         200000
+#define MIN_NUMBER_OF_PACKET 1500
 
 /* Number of "frame_data" structures per memory chunk.
    XXX - is this the right number? */
-#define        FRAME_DATA_CHUNK_SIZE   1024
+#define FRAME_DATA_CHUNK_SIZE   1024
 
 
 /* this callback mechanism should possibly be replaced by the g_signal_...() stuff (if I only would know how :-) */
@@ -181,48 +190,83 @@ cf_callback_remove(cf_callback_t func)
 void
 cf_timestamp_auto_precision(capture_file *cf)
 {
-       int prec = timestamp_get_precision();
-
-
-       /* don't try to get the file's precision if none is opened */
-       if(cf->state == FILE_CLOSED) {
-               return;
-       }
-
-       /* if we are in auto mode, set precision of current file */
-       if(prec == TS_PREC_AUTO ||
-         prec == TS_PREC_AUTO_SEC ||
-         prec == TS_PREC_AUTO_DSEC ||
-         prec == TS_PREC_AUTO_CSEC ||
-         prec == TS_PREC_AUTO_MSEC ||
-         prec == TS_PREC_AUTO_USEC ||
-         prec == TS_PREC_AUTO_NSEC)
-       {
-               switch(wtap_file_tsprecision(cf->wth)) {
-               case(WTAP_FILE_TSPREC_SEC):
-                       timestamp_set_precision(TS_PREC_AUTO_SEC);
-                       break;
-               case(WTAP_FILE_TSPREC_DSEC):
-                       timestamp_set_precision(TS_PREC_AUTO_DSEC);
-                       break;
-               case(WTAP_FILE_TSPREC_CSEC):
-                       timestamp_set_precision(TS_PREC_AUTO_CSEC);
-                       break;
-               case(WTAP_FILE_TSPREC_MSEC):
-                       timestamp_set_precision(TS_PREC_AUTO_MSEC);
-                       break;
-               case(WTAP_FILE_TSPREC_USEC):
-                       timestamp_set_precision(TS_PREC_AUTO_USEC);
-                       break;
-               case(WTAP_FILE_TSPREC_NSEC):
-                       timestamp_set_precision(TS_PREC_AUTO_NSEC);
-                       break;
-               default:
-                       g_assert_not_reached();
-               }
-       }
+#ifdef NEW_PACKET_LIST
+    int i;
+#endif
+    int prec = timestamp_get_precision();
+
+
+    /* don't try to get the file's precision if none is opened */
+    if(cf->state == FILE_CLOSED) {
+        return;
+    }
+
+    /* if we are in auto mode, set precision of current file */
+    if(prec == TS_PREC_AUTO ||
+      prec == TS_PREC_AUTO_SEC ||
+      prec == TS_PREC_AUTO_DSEC ||
+      prec == TS_PREC_AUTO_CSEC ||
+      prec == TS_PREC_AUTO_MSEC ||
+      prec == TS_PREC_AUTO_USEC ||
+      prec == TS_PREC_AUTO_NSEC)
+    {
+        switch(wtap_file_tsprecision(cf->wth)) {
+        case(WTAP_FILE_TSPREC_SEC):
+            timestamp_set_precision(TS_PREC_AUTO_SEC);
+            break;
+        case(WTAP_FILE_TSPREC_DSEC):
+            timestamp_set_precision(TS_PREC_AUTO_DSEC);
+            break;
+        case(WTAP_FILE_TSPREC_CSEC):
+            timestamp_set_precision(TS_PREC_AUTO_CSEC);
+            break;
+        case(WTAP_FILE_TSPREC_MSEC):
+            timestamp_set_precision(TS_PREC_AUTO_MSEC);
+            break;
+        case(WTAP_FILE_TSPREC_USEC):
+            timestamp_set_precision(TS_PREC_AUTO_USEC);
+            break;
+        case(WTAP_FILE_TSPREC_NSEC):
+            timestamp_set_precision(TS_PREC_AUTO_NSEC);
+            break;
+        default:
+            g_assert_not_reached();
+        }
+    }
+#ifdef NEW_PACKET_LIST
+  /* Set the column widths of those columns that show the time in
+     "command-line-specified" format. */
+  for (i = 0; i < cf->cinfo.num_cols; i++) {
+    if (col_has_time_fmt(&cf->cinfo, i)) {
+      new_packet_list_resize_column(i);
+    }
+  }
+#endif
+}
+
+gulong
+cf_get_computed_elapsed(void)
+{
+    return computed_elapsed;
 }
 
+static void reset_elapsed(void)
+{
+    computed_elapsed = 0;
+}
+
+static void compute_elapsed(GTimeVal *start_time)
+{
+    gdouble    delta_time;
+    GTimeVal   time_now;
+
+    g_get_current_time(&time_now);
+
+    delta_time = (time_now.tv_sec - start_time->tv_sec) * 1e6 +
+    time_now.tv_usec - start_time->tv_usec;
+
+    computed_elapsed = (gulong) (delta_time / 1000); /* ms*/
+}
 
 cf_status_t
 cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
@@ -238,6 +282,8 @@ cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
      and fill in the information for this file. */
   cf_reset_state(cf);
 
+  /* Cleanup all data structures used for dissection. */
+  cleanup_dissection();
   /* Initialize all data structures used for dissection. */
   init_dissection();
 
@@ -258,6 +304,8 @@ cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
   /* If it's a temporary capture buffer file, mark it as not saved. */
   cf->user_saved = !is_tempfile;
 
+  reset_elapsed();
+
   cf->cd_t        = wtap_file_type(cf->wth);
   cf->count     = 0;
   cf->displayed_count = 0;
@@ -271,19 +319,34 @@ cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
     cf->snap = WTAP_MAX_PACKET_SIZE;
   } else
     cf->has_snap = TRUE;
+
   nstime_set_zero(&cf->elapsed_time);
   nstime_set_unset(&first_ts);
   nstime_set_unset(&prev_dis_ts);
+  nstime_set_unset(&prev_cap_ts);
+  cum_bytes = 0;
 
+#if GLIB_CHECK_VERSION(2,10,0)
+#else
+  /* memory chunks have been deprecated in favor of the slice allocator,
+   * which has been added in 2.10
+   */
   cf->plist_chunk = g_mem_chunk_new("frame_data_chunk",
-       sizeof(frame_data),
-       FRAME_DATA_CHUNK_SIZE * sizeof(frame_data),
-       G_ALLOC_AND_FREE);
+    sizeof(frame_data),
+    FRAME_DATA_CHUNK_SIZE * sizeof(frame_data),
+    G_ALLOC_AND_FREE);
   g_assert(cf->plist_chunk);
+#endif
 
+#ifdef NEW_PACKET_LIST
+  /* Adjust timestamp precision if auto is selected, col width will be adjusted */
+  cf_timestamp_auto_precision(cf);
+  /* XXX needed ? */
+  new_packet_list_queue_draw();
+#else
   /* change the time formats now, as we might have a new precision */
   cf_change_time_formats(cf);
-
+#endif
   fileset_file_opened(fname);
 
   if(cf->cd_t == WTAP_FILE_BER) {
@@ -327,23 +390,23 @@ cf_reset_state(capture_file *cf)
   /* ...which means we have nothing to save. */
   cf->user_saved = FALSE;
 
+#if GLIB_CHECK_VERSION(2,10,0)
+  if (cf->plist_start != NULL)
+    g_slice_free_chain(frame_data, cf->plist_start, next);
+#else
+  /* memory chunks have been deprecated in favor of the slice allocator,
+   * which has been added in 2.10
+   */
   if (cf->plist_chunk != NULL) {
-    frame_data *fdata = cf->plist;
-    while (fdata) {
-      g_strfreev(fdata->col_expr.col_expr);
-      g_strfreev(fdata->col_expr.col_expr_val);
-      fdata = fdata->next;
-    }
     g_mem_chunk_destroy(cf->plist_chunk);
     cf->plist_chunk = NULL;
   }
-  if (cf->rfcode != NULL) {
-    dfilter_free(cf->rfcode);
-    cf->rfcode = NULL;
-  }
-  cf->plist = NULL;
+#endif
+  dfilter_free(cf->rfcode);
+  cf->rfcode = NULL;
+  cf->plist_start = NULL;
   cf->plist_end = NULL;
-  cf_unselect_packet(cf);      /* nothing to select */
+  cf_unselect_packet(cf);   /* nothing to select */
   cf->first_displayed = NULL;
   cf->last_displayed = NULL;
 
@@ -353,9 +416,15 @@ cf_reset_state(capture_file *cf)
   cf->finfo_selected = NULL;
 
   /* Clear the packet list. */
+#ifdef NEW_PACKET_LIST
+  new_packet_list_freeze();
+  new_packet_list_clear();
+  new_packet_list_thaw();
+#else
   packet_list_freeze();
   packet_list_clear();
   packet_list_thaw();
+#endif
 
   cf->f_datalen = 0;
   cf->count = 0;
@@ -379,12 +448,9 @@ cf_close(capture_file *cf)
 
   /* close things, if not already closed before */
   if(cf->state != FILE_CLOSED) {
-
-         color_filters_cleanup();
-
-         cf_reset_state(cf);
-
-         cleanup_dissection();
+    color_filters_cleanup();
+    cf_reset_state(cf);
+    cleanup_dissection();
   }
 
   cf_callback_invoke(cf_cb_file_closed, cf);
@@ -396,6 +462,27 @@ void outofmemory_cb(gpointer dialog _U_, gint btn _U_, gpointer data _U_)
     main_window_exit();
 }
 
+static float calc_progbar_val(capture_file *cf, gint64 size, gint64 file_pos){
+
+    float   progbar_val;
+
+    progbar_val = (gfloat) file_pos / (gfloat) size;
+    if (progbar_val > 1.0) {
+    /* The file probably grew while we were reading it.
+       Update file size, and try again. */
+      size = wtap_file_size(cf->wth, NULL);
+      if (size >= 0)
+        progbar_val = (gfloat) file_pos / (gfloat) size;
+       /* If it's still > 1, either "wtap_file_size()" failed (in which
+          case there's not much we can do about it), or the file
+          *shrank* (in which case there's not much we can do about
+          it); just clip the progress value at 1.0. */
+      if (progbar_val > 1.0f)
+        progbar_val = 1.0f;
+    }
+    return progbar_val;
+}
+
 cf_read_status_t
 cf_read(capture_file *cf)
 {
@@ -408,27 +495,32 @@ cf_read(capture_file *cf)
   progdlg_t *volatile progbar = NULL;
   gboolean     stop_flag;
   volatile gint64 size;
-  gint64       file_pos;
   volatile float progbar_val;
   GTimeVal     start_time;
   gchar        status_str[100];
   volatile gint64 progbar_nextstep;
   volatile gint64 progbar_quantum;
   dfilter_t   *dfcode;
+  gboolean    filtering_tap_listeners;
+  guint       tap_flags;
+  volatile int count = 0;
 #ifdef HAVE_LIBPCAP
   volatile int displayed_once = 0;
 #endif
+  gboolean compiled;
 
   /* 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);
-  }
+  compiled = dfilter_compile(cf->dfilter, &dfcode);
+  g_assert(!cf->dfilter || (compiled && dfcode));
 
-  cum_bytes=0;
+  /* 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();
 
   reset_tap_listeners();
 
@@ -443,26 +535,32 @@ cf_read(capture_file *cf)
   progbar_nextstep = 0;
   /* When we reach the value that triggers a progress bar update,
      bump that value by this amount. */
-  if (size >= 0)
+  if (size >= 0){
     progbar_quantum = size/N_PROGBAR_UPDATES;
-  else
+    if (progbar_quantum < MIN_QUANTUM)
+        progbar_quantum = MIN_QUANTUM;
+  }else
     progbar_quantum = 0;
   /* Progress so far. */
   progbar_val = 0.0f;
 
+#ifdef NEW_PACKET_LIST
+  new_packet_list_freeze();
+#else
   packet_list_freeze();
+#endif
 
   stop_flag = FALSE;
   g_get_current_time(&start_time);
 
   while ((wtap_read(cf->wth, &err, &err_info, &data_offset))) {
     if (size >= 0) {
+        count++;
       /* 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) {
+       * Check wether it should be created or not every MIN_NUMBER_OF_PACKET
+       */
+      if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)){
+        progbar_val = calc_progbar_val( cf, size, data_offset);
         progbar = delayed_create_progress_dlg("Loading", name_ptr,
           TRUE, &stop_flag, &start_time, progbar_val);
       }
@@ -473,39 +571,31 @@ cf_read(capture_file *cf)
          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 (data_offset >= progbar_nextstep) {
-          file_pos = wtap_read_so_far(cf->wth, NULL);
-          progbar_val = (gfloat) file_pos / (gfloat) size;
-          if (progbar_val > 1.0) {
-            /* The file probably grew while we were reading it.
-               Update file size, and try again. */
-            size = wtap_file_size(cf->wth, NULL);
-            if (size >= 0)
-              progbar_val = (gfloat) file_pos / (gfloat) size;
-            /* If it's still > 1, either "wtap_file_size()" failed (in which
-               case there's not much we can do about it), or the file
-               *shrank* (in which case there's not much we can do about
-               it); just clip the progress value at 1.0. */
-            if (progbar_val > 1.0f)
-              progbar_val = 1.0f;
-          }
           if (progbar != NULL) {
+              progbar_val = calc_progbar_val( cf, size, data_offset);
               /* update the packet lists content on the first run or frequently on very large files */
               /* (on smaller files the display update takes longer than reading the file) */
 #ifdef HAVE_LIBPCAP
               if (progbar_quantum > 500000 || displayed_once == 0) {
                   if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->plist_end != NULL) {
                       displayed_once = 1;
-                      packet_list_thaw();
-                      if (auto_scroll_live)
-                          packet_list_moveto_end();
-                      packet_list_freeze();
+#ifdef NEW_PACKET_LIST
+                  new_packet_list_thaw();
+                  if (auto_scroll_live)
+                      new_packet_list_moveto_end();
+                  new_packet_list_freeze();
+#else
+                  packet_list_thaw();
+                  if (auto_scroll_live)
+                      packet_list_moveto_end();
+                  packet_list_freeze();
+#endif /* NEW_PACKET_LIST */
                   }
-              }
-#endif
-
+          }
+#endif /* HAVE_LIBPCAP */
             g_snprintf(status_str, sizeof(status_str),
                        "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
-                       file_pos / 1024, size / 1024);
+                       data_offset / 1024, size / 1024);
             update_progress_dlg(progbar, progbar_val, status_str);
           }
          progbar_nextstep += progbar_quantum;
@@ -522,7 +612,7 @@ cf_read(capture_file *cf)
       break;
     }
     TRY {
-        read_packet(cf, dfcode, data_offset);
+        read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
     }
     CATCH(OutOfMemoryError) {
         gpointer dialog;
@@ -566,6 +656,9 @@ cf_read(capture_file *cf)
    * don't need after the sequential run-through of the packets. */
   postseq_cleanup_all_protocols();
 
+  /* compute the time it took to load the file */
+  compute_elapsed(&start_time);
+
   /* Set the file encapsulation type now; we don't know what it is until
      we've looked at all the packets, as we don't know until then whether
      there's more than one type (and thus whether it's
@@ -575,23 +668,32 @@ cf_read(capture_file *cf)
   cf->current_frame = cf->first_displayed;
   cf->current_row = 0;
 
+#ifdef NEW_PACKET_LIST
+  new_packet_list_thaw();
+#else
   packet_list_thaw();
+#endif
 
   cf_callback_invoke(cf_cb_file_read_finished, cf);
 
   /* If we have any displayed packets to select, select the first of those
      packets by making the first row the selected row. */
-  if (cf->first_displayed != NULL)
+  if (cf->first_displayed != NULL){
+#ifdef NEW_PACKET_LIST
+    new_packet_list_select_first_row();
+#else
     packet_list_select_row(0);
+#endif /* NEW_PACKET_LIST */
+  }
 
   if(stop_flag) {
     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
           "%sFile loading was cancelled!%s\n"
           "\n"
-                 "The remaining packets in the file were discarded.\n"
+          "The remaining packets in the file were discarded.\n"
           "\n"
           "As a lot of packets from the original file will be missing,\n"
-                 "remember to be careful when saving the current content to a file.\n",
+          "remember to be careful when saving the current content to a file.\n",
           simple_dialog_primary_start(), simple_dialog_primary_end());
     return CF_READ_ERROR;
   }
@@ -630,8 +732,8 @@ cf_read(capture_file *cf)
 
     default:
       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
-              "An error occurred while reading the"
-              " capture file: %s.", wtap_strerror(err));
+           "An error occurred while reading the"
+           " capture file: %s.", wtap_strerror(err));
       errmsg = errmsg_errno;
       break;
     }
@@ -658,20 +760,33 @@ cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
   gchar *err_info;
   volatile int newly_displayed_packets = 0;
   dfilter_t   *dfcode;
+  gboolean filtering_tap_listeners;
+  guint tap_flags;
+  volatile gboolean visible = FALSE;
+  gboolean compiled;
 
   /* 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);
-  }
+  compiled = dfilter_compile(cf->dfilter, &dfcode);
+  g_assert(!cf->dfilter || (compiled && 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();
 
   *err = 0;
 
+#ifdef NEW_PACKET_LIST
+  new_packet_list_check_end();
+  new_packet_list_freeze();
+#else
   packet_list_check_end();
   packet_list_freeze();
+#endif
 
   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: %u new: %u", cf->count, to_read);*/
 
@@ -679,12 +794,16 @@ cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
     if (cf->state == FILE_READ_ABORTED) {
       /* Well, the user decided to exit Wireshark.  Break out of the
          loop, and let the code below (which is called even if there
-        aren't any packets left to read) exit. */
+     aren't any packets left to read) exit. */
       break;
     }
     TRY{
-        if (read_packet(cf, dfcode, data_offset) != -1) {
+        if (read_packet(cf, dfcode, filtering_tap_listeners, tap_flags,
+                        data_offset) != -1) {
+            visible = TRUE;
             newly_displayed_packets++;
+        }else{
+            visible = FALSE;
         }
     }
     CATCH(OutOfMemoryError) {
@@ -708,7 +827,11 @@ cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
             /* XXX - how to avoid a busy wait? */
             /* Sleep(100); */
         };
+#ifdef NEW_PACKET_LIST
+        new_packet_list_thaw();
+#else
         packet_list_thaw();
+#endif
         return CF_READ_ABORTED;
     }
     ENDTRY;
@@ -721,19 +844,33 @@ cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
   }
 
   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: count %u state: %u err: %u",
-         cf->count, cf->state, *err);*/
+      cf->count, cf->state, *err);*/
 
+#ifdef NEW_PACKET_LIST
+  new_packet_list_thaw();
+  /* With the new packet list the first packet
+   * isn't automatically selected.
+   */
+  if(!cf->current_frame)
+         new_packet_list_select_first_row();
+#else
   /* XXX - this causes "flickering" of the list */
   packet_list_thaw();
+#endif
 
   /* moving to the end of the packet list - if the user requested so and
-     we have some new packets.
-     this doesn't seem to work well with a frozen GTK_Clist, so do this after
-     packet_list_thaw() is done, see bugzilla 1188 */
-  /* XXX - this cheats and looks inside the packet list to find the final
-     row number. */
+     we have some new packets. */
   if (newly_displayed_packets && auto_scroll_live && cf->plist_end != NULL)
+#ifdef NEW_PACKET_LIST
+    if(visible)
+      new_packet_list_moveto_end();
+#else
+    /* this doesn't seem to work well with a frozen GTK_Clist, so do this after
+       packet_list_thaw() is done, see bugzilla 1188 */
+    /* XXX - this cheats and looks inside the packet list to find the final
+       row number. */
     packet_list_moveto_end();
+#endif /* NEW_PACKET_LIST */
 
   if (cf->state == FILE_READ_ABORTED) {
     /* Well, the user decided to exit Wireshark.  Return CF_READ_ABORTED
@@ -745,8 +882,8 @@ cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
   } else if (*err != 0) {
     /* We got an error reading the capture file.
        XXX - pop up a dialog box instead? */
-       g_warning("Error \"%s\" while reading: \"%s\"\n",
-               wtap_strerror(*err), cf->filename);
+    g_warning("Error \"%s\" while reading: \"%s\"\n",
+        wtap_strerror(*err), cf->filename);
 
     return CF_READ_ERROR;
   } else
@@ -759,32 +896,44 @@ cf_finish_tail(capture_file *cf, int *err)
   gchar *err_info;
   gint64 data_offset;
   dfilter_t   *dfcode;
+  gboolean filtering_tap_listeners;
+  guint tap_flags;
+  gboolean compiled;
 
   /* 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);
-  }
+  compiled = dfilter_compile(cf->dfilter, &dfcode);
+  g_assert(!cf->dfilter || (compiled && 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();
 
   if(cf->wth == NULL) {
     cf_close(cf);
     return CF_READ_ERROR;
   }
 
+#ifdef NEW_PACKET_LIST
+  new_packet_list_check_end();
+  new_packet_list_freeze();
+#else
   packet_list_check_end();
   packet_list_freeze();
+#endif
 
   while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
     if (cf->state == FILE_READ_ABORTED) {
       /* Well, the user decided to abort the read.  Break out of the
          loop, and let the code below (which is called even if there
-        aren't any packets left to read) exit. */
+     aren't any packets left to read) exit. */
       break;
     }
-        read_packet(cf, dfcode, data_offset);
+    read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
   }
 
   /* Cleanup and release all dfilter resources */
@@ -792,7 +941,11 @@ cf_finish_tail(capture_file *cf, int *err)
     dfilter_free(dfcode);
   }
 
+#ifdef NEW_PACKET_LIST
+  new_packet_list_thaw();
+#else
   packet_list_thaw();
+#endif
 
   if (cf->state == FILE_READ_ABORTED) {
     /* Well, the user decided to abort the read.  We're only called
@@ -805,9 +958,13 @@ cf_finish_tail(capture_file *cf, int *err)
   }
 
   if (auto_scroll_live && cf->plist_end != NULL)
+#ifdef NEW_PACKET_LIST
+    new_packet_list_moveto_end();
+#else
     /* XXX - this cheats and looks inside the packet list to find the final
        row number. */
     packet_list_moveto_end();
+#endif
 
   /* We're done reading sequentially through the file. */
   cf->state = FILE_READ_DONE;
@@ -913,15 +1070,110 @@ void cf_set_rfcode(capture_file *cf, dfilter_t *rfcode)
     cf->rfcode = rfcode;
 }
 
+#ifdef NEW_PACKET_LIST
 static int
 add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
-       dfilter_t *dfcode,
-       union wtap_pseudo_header *pseudo_header, const guchar *buf,
-       gboolean refilter)
+    dfilter_t *dfcode, gboolean filtering_tap_listeners,
+    guint tap_flags,
+    union wtap_pseudo_header *pseudo_header, const guchar *buf,
+    gboolean refilter,
+    gboolean add_to_packet_list)
 {
-  gint          row;
-  gboolean     create_proto_tree = FALSE;
-  epan_dissect_t *edt;
+  gboolean  create_proto_tree = FALSE;
+  epan_dissect_t edt;
+  column_info *cinfo;
+  gint row = -1;
+
+  cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
+
+  frame_data_set_before_dissect(fdata, &cf->elapsed_time,
+                                &first_ts, &prev_dis_ts, &prev_cap_ts);
+
+  /* If either
+    + we have a display filter and are re-applying it;
+    + we have tap listeners with filters;
+    + we have tap listeners that require a protocol tree;
+
+     allocate a protocol tree root node, so that we'll construct
+     a protocol tree against which a filter expression can be
+     evaluated. */
+  if ((dfcode != NULL && refilter) ||
+      filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE))
+      create_proto_tree = TRUE;
+
+  /* Dissect the frame. */
+  epan_dissect_init(&edt, create_proto_tree, FALSE);
+
+  if (dfcode != NULL && refilter) {
+      epan_dissect_prime_dfilter(&edt, dfcode);
+  }
+
+  tap_queue_init(&edt);
+  epan_dissect_run(&edt, pseudo_header, buf, fdata, cinfo);
+  tap_push_tapped_queue(&edt);
+
+  /* If we have a display filter, apply it if we're refiltering, otherwise
+     leave the "passed_dfilter" flag alone.
+
+     If we don't have a display filter, set "passed_dfilter" to 1. */
+  if (dfcode != NULL) {
+    if (refilter) {
+      fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, &edt) ? 1 : 0;
+    }
+  } else
+    fdata->flags.passed_dfilter = 1;
+
+  if (add_to_packet_list) {
+    /* We fill the needed columns from new_packet_list */
+      row = new_packet_list_append(cinfo, fdata, &edt.pi);
+  }
+
+  if(fdata->flags.passed_dfilter || fdata->flags.ref_time)
+  {
+    frame_data_set_after_dissect(fdata, &cum_bytes, &prev_dis_ts);
+
+    /* If we haven't yet seen the first frame, this is it.
+
+       XXX - we must do this before we add the row to the display,
+       as, if the display's GtkCList's selection mode is
+       GTK_SELECTION_BROWSE, when the first entry is added to it,
+       "cf_select_packet()" will be called, and it will fetch the row
+       data for the 0th row, and will get a null pointer rather than
+       "fdata", as "gtk_clist_append()" won't yet have returned and
+       thus "gtk_clist_set_row_data()" won't yet have been called.
+
+       We thus need to leave behind bread crumbs so that
+       "cf_select_packet()" can find this frame.  See the comment
+       in "cf_select_packet()". */
+    if (cf->first_displayed == NULL)
+      cf->first_displayed = fdata;
+
+    /* This is the last frame we've seen so far. */
+    cf->last_displayed = fdata;
+
+    cf->displayed_count++;
+  }
+
+  epan_dissect_cleanup(&edt);
+  return row;
+}
+
+#else
+
+static int
+add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
+    dfilter_t *dfcode, gboolean filtering_tap_listeners,
+    guint tap_flags,
+    union wtap_pseudo_header *pseudo_header, const guchar *buf,
+    gboolean refilter,
+    gboolean add_to_packet_list _U_)
+{
+  gboolean  create_proto_tree = FALSE;
+  epan_dissect_t edt;
+  column_info *cinfo;
+  gint row = -1;
+
+  cinfo = &cf->cinfo;
 
   /* just add some value here until we know if it is being displayed or not */
   fdata->cum_bytes  = cum_bytes + fdata->pkt_len;
@@ -963,37 +1215,39 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
 
   /* If either
 
-       we have a display filter and are re-applying it;
+    we have a display filter and are re-applying it;
 
-       we have a list of color filters;
+    we have a list of color filters;
 
-       we have tap listeners;
+    we have tap listeners with filters;
 
-       we have custom columns;
+    we have tap listeners that require a protocol tree;
+
+    we have custom columns;
 
      allocate a protocol tree root node, so that we'll construct
      a protocol tree against which a filter expression can be
      evaluated. */
-  if ((dfcode != NULL && refilter) || color_filters_used()
-      || num_tap_filters != 0 || have_custom_cols(&cf->cinfo))
-         create_proto_tree = TRUE;
+  if ((dfcode != NULL && refilter) ||
+      color_filters_used() ||
+      have_custom_cols(cinfo) ||
+      filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE))
+      create_proto_tree = TRUE;
 
   /* Dissect the frame. */
-  edt = epan_dissect_new(create_proto_tree, FALSE);
+  epan_dissect_init(&edt, create_proto_tree, FALSE);
 
   if (dfcode != NULL && refilter) {
-      epan_dissect_prime_dfilter(edt, dfcode);
-  }
-  /* prepare color filters */
-  if (color_filters_used()) {
-      color_filters_prime_edt(edt);
+      epan_dissect_prime_dfilter(&edt, dfcode);
   }
 
-  col_custom_prime_edt(edt, &cf->cinfo);
+  /* prepare color filters */
+  color_filters_prime_edt(&edt);
+  col_custom_prime_edt(&edt, cinfo);
 
-  tap_queue_init(edt);
-  epan_dissect_run(edt, pseudo_header, buf, fdata, &cf->cinfo);
-  tap_push_tapped_queue(edt);
+  tap_queue_init(&edt);
+  epan_dissect_run(&edt, pseudo_header, buf, fdata, cinfo);
+  tap_push_tapped_queue(&edt);
 
   /* If we have a display filter, apply it if we're refiltering, otherwise
      leave the "passed_dfilter" flag alone.
@@ -1001,17 +1255,17 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
      If we don't have a display filter, set "passed_dfilter" to 1. */
   if (dfcode != NULL) {
     if (refilter) {
-      fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, edt) ? 1 : 0;
+      fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, &edt) ? 1 : 0;
     }
   } else
     fdata->flags.passed_dfilter = 1;
 
-  if( (fdata->flags.passed_dfilter)
-   || (edt->pi.fd->flags.ref_time) ){
+  if( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) )
+  {
     /* This frame either passed the display filter list or is marked as
        a time reference frame.  All time reference frames are displayed
        even if they dont pass the display filter */
-    if(edt->pi.fd->flags.ref_time){
+    if(fdata->flags.ref_time){
       /* if this was a TIME REF frame we should reset the cul bytes field */
       cum_bytes = fdata->pkt_len;
       fdata->cum_bytes =  cum_bytes;
@@ -1020,7 +1274,7 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
       cum_bytes += fdata->pkt_len;
     }
 
-    epan_dissect_fill_in_columns(edt);
+    epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
 
     /* If we haven't yet seen the first frame, this is it.
 
@@ -1041,115 +1295,86 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
     /* This is the last frame we've seen so far. */
     cf->last_displayed = fdata;
 
-    /* XXX - GLIB1 implementation provided to support backport of this feature. */
-#if (GLIB_MAJOR_VERSION >= 2)
-    fdata->col_expr.col_expr = g_strdupv(cf->cinfo.col_expr.col_expr);
-    fdata->col_expr.col_expr_val = g_strdupv(cf->cinfo.col_expr.col_expr_val);
-#else
-    {
-      gint i;
-
-      fdata->col_expr.col_expr = (gchar **) g_malloc(sizeof(gchar *) * (cf->cinfo.num_cols + 1));
-      fdata->col_expr.col_expr_val = (gchar **) g_malloc(sizeof(gchar *) * (cf->cinfo.num_cols + 1));
-
-      for (i=0; i <= cf->cinfo.num_cols; i++)
-      {
-        fdata->col_expr.col_expr[i] = g_strdup(cf->cinfo.col_expr.col_expr[i]);
-        fdata->col_expr.col_expr_val[i] = g_strdup(cf->cinfo.col_expr.col_expr_val[i]);
-      }
-    }
-#endif
-    row = packet_list_append(cf->cinfo.col_data, fdata);
+    row = packet_list_append(cinfo->col_data, fdata);
 
     /* colorize packet: first apply color filters
      * then if packet is marked, use preferences to overwrite color
      * we do both to make sure that when a packet gets un-marked, the
      * color will be correctly set (fixes bug 2038)
      */
-      fdata->color_filter = color_filters_colorize_packet(row, edt);
-      if (fdata->flags.marked) {
-          packet_list_set_colors(row, &prefs.gui_marked_fg, &prefs.gui_marked_bg);
-      }
+     fdata->color_filter = color_filters_colorize_packet(row, &edt);
+     if (fdata->flags.marked) {
+       packet_list_set_colors(row, &prefs.gui_marked_fg, &prefs.gui_marked_bg);
+     }
 
     /* Set the time of the previous displayed frame to the time of this
        frame. */
     prev_dis_ts = fdata->abs_ts;
 
     cf->displayed_count++;
-  } else {
-    /* This frame didn't pass the display filter, so it's not being added
-       to the clist, and thus has no row. */
-    row = -1;
   }
-  epan_dissect_free(edt);
+
+  epan_dissect_cleanup(&edt);
   return row;
 }
+#endif
 
 /* read in a new packet */
 /* returns the row of the new packet in the packet list or -1 if not displayed */
 static int
-read_packet(capture_file *cf, dfilter_t *dfcode, gint64 offset)
+read_packet(capture_file *cf, dfilter_t *dfcode,
+            gboolean filtering_tap_listeners, guint tap_flags, gint64 offset)
 {
   const struct wtap_pkthdr *phdr = wtap_phdr(cf->wth);
   union wtap_pseudo_header *pseudo_header = wtap_pseudoheader(cf->wth);
   const guchar *buf = wtap_buf_ptr(cf->wth);
   frame_data   *fdata;
   int           passed;
-  frame_data   *plist_end;
-  epan_dissect_t *edt;
-  int row = -1;
+  int           row = -1;
 
-  /* Allocate the next list entry, and add it to the list. */
+  cf->count++;
+
+  /* Allocate the next list entry, and add it to the list.
+   * memory chunks have been deprecated in favor of the slice allocator,
+   * which has been added in 2.10
+   */
+#if GLIB_CHECK_VERSION(2,10,0)
+  fdata = g_slice_new(frame_data);
+#else
   fdata = g_mem_chunk_alloc(cf->plist_chunk);
+#endif
 
-  fdata->num = 0;
-  fdata->next = NULL;
-  fdata->prev = NULL;
-  fdata->pfd  = NULL;
-  fdata->pkt_len  = phdr->len;
-  fdata->cap_len  = phdr->caplen;
-  fdata->file_off = offset;
-  fdata->lnk_t = phdr->pkt_encap;
-  fdata->flags.encoding = CHAR_ASCII;
-  fdata->flags.visited = 0;
-  fdata->flags.marked = 0;
-  fdata->flags.ref_time = 0;
-  fdata->color_filter = NULL;
-  fdata->col_expr.col_expr = NULL;
-  fdata->col_expr.col_expr_val = NULL;
-
-  fdata->abs_ts.secs = phdr->ts.secs;
-  fdata->abs_ts.nsecs = phdr->ts.nsecs;
-
-  if (cf->plist_end != NULL)
-    nstime_delta(&fdata->del_cap_ts, &fdata->abs_ts, &cf->plist_end->abs_ts);
-  else
-    nstime_set_zero(&fdata->del_cap_ts);
+  frame_data_init(fdata, cf->count, phdr, offset, cum_bytes);
+
+#ifdef NEW_PACKET_LIST
+  fdata->col_text_len = se_alloc0(sizeof(fdata->col_text_len) * (cf->cinfo.num_cols));
+  fdata->col_text = se_alloc0(sizeof(fdata->col_text) * (cf->cinfo.num_cols));
+#endif
 
   passed = TRUE;
   if (cf->rfcode) {
-    edt = epan_dissect_new(TRUE, FALSE);
-    epan_dissect_prime_dfilter(edt, cf->rfcode);
-    epan_dissect_run(edt, pseudo_header, buf, fdata, NULL);
-    passed = dfilter_apply_edt(cf->rfcode, edt);
-    epan_dissect_free(edt);
+    epan_dissect_t edt;
+    epan_dissect_init(&edt, TRUE, FALSE);
+    epan_dissect_prime_dfilter(&edt, cf->rfcode);
+    epan_dissect_run(&edt, pseudo_header, buf, fdata, NULL);
+    passed = dfilter_apply_edt(cf->rfcode, &edt);
+    epan_dissect_cleanup(&edt);
   }
+
   if (passed) {
-    plist_end = cf->plist_end;
-    fdata->prev = plist_end;
-    if (plist_end != NULL)
-      plist_end->next = fdata;
-    else
-      cf->plist = fdata;
-    cf->plist_end = fdata;
+    cap_file_add_fdata(cf, fdata);
+
+    cf->f_datalen = offset + fdata->cap_len;
 
-    cf->count++;
-    cf->f_datalen = offset + phdr->caplen;
-    fdata->num = cf->count;
     if (!cf->redissecting) {
-      row = add_packet_to_packet_list(fdata, cf, dfcode, pseudo_header, buf, TRUE);
+      row = add_packet_to_packet_list(fdata, cf, dfcode,
+                                      filtering_tap_listeners, tap_flags,
+                                      pseudo_header, buf, TRUE, TRUE);
     }
   } else {
+    /* We didn't pass read filter so roll back count */
+    cf->count--;
+
     /* XXX - if we didn't have read filters, or if we could avoid
        allocating the "frame_data" structure until we knew whether
        the frame passed the read filter, we could use a G_ALLOC_ONLY
@@ -1158,9 +1383,14 @@ read_packet(capture_file *cf, dfilter_t *dfcode, gint64 offset)
        ...but, at least in one test I did, where I just made the chunk
        a G_ALLOC_ONLY chunk and read in a huge capture file, it didn't
        seem to save a noticeable amount of time or space. */
-    g_strfreev(fdata->col_expr.col_expr);
-    g_strfreev(fdata->col_expr.col_expr_val);
+#if GLIB_CHECK_VERSION(2,10,0)
+  /* memory chunks have been deprecated in favor of the slice allocator,
+   * which has been added in 2.10
+   */
+    g_slice_free(frame_data,fdata);
+#else
     g_mem_chunk_free(cf->plist_chunk, fdata);
+#endif
   }
 
   return row;
@@ -1173,7 +1403,7 @@ cf_merge_files(char **out_filenamep, int in_file_count,
   merge_in_file_t  *in_files;
   wtap             *wth;
   char             *out_filename;
-  char              tmpname[128+1];
+  char             *tmpname;
   int               out_fd;
   wtap_dumper      *pdh;
   int               open_err, read_err, write_err, close_err;
@@ -1208,7 +1438,7 @@ cf_merge_files(char **out_filenamep, int in_file_count,
     if (out_fd == -1)
       open_err = errno;
   } else {
-    out_fd = create_tempfile(tmpname, sizeof tmpname, "wireshark");
+    out_fd = create_tempfile(&tmpname, "wireshark");
     if (out_fd == -1)
       open_err = errno;
     out_filename = g_strdup(tmpname);
@@ -1225,7 +1455,7 @@ cf_merge_files(char **out_filenamep, int in_file_count,
   pdh = wtap_dump_fdopen(out_fd, file_type,
       merge_select_frame_type(in_file_count, in_files),
       merge_max_snapshot_length(in_file_count, in_files),
-         FALSE /* compressed */, &open_err);
+      FALSE /* compressed */, &open_err);
   if (pdh == NULL) {
     ws_close(out_fd);
     merge_close_in_files(in_file_count, in_files);
@@ -1335,43 +1565,43 @@ cf_merge_files(char **out_filenamep, int in_file_count,
      */
     for (i = 0; i < in_file_count; i++) {
       if (in_files[i].state == GOT_ERROR) {
-       /* Put up a message box noting that a read failed somewhere along
-          the line. */
-       switch (read_err) {
-
-       case WTAP_ERR_UNSUPPORTED_ENCAP:
-         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
-                  "The capture file %%s has a packet with a network type that Wireshark doesn't support.\n(%s)",
-                  err_info);
-         g_free(err_info);
-         errmsg = errmsg_errno;
-         break;
-
-       case WTAP_ERR_CANT_READ:
-         errmsg = "An attempt to read from the capture file %s failed for"
-                  " some unknown reason.";
-         break;
-
-       case WTAP_ERR_SHORT_READ:
-         errmsg = "The capture file %s appears to have been cut short"
-                  " in the middle of a packet.";
-         break;
-
-       case WTAP_ERR_BAD_RECORD:
-         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
-                  "The capture file %%s appears to be damaged or corrupt.\n(%s)",
-                  err_info);
-         g_free(err_info);
-         errmsg = errmsg_errno;
-         break;
-
-       default:
-         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
-                  "An error occurred while reading the"
-                  " capture file %%s: %s.", wtap_strerror(read_err));
-         errmsg = errmsg_errno;
-         break;
-       }
+    /* Put up a message box noting that a read failed somewhere along
+       the line. */
+    switch (read_err) {
+
+    case WTAP_ERR_UNSUPPORTED_ENCAP:
+      g_snprintf(errmsg_errno, sizeof(errmsg_errno),
+           "The capture file %%s has a packet with a network type that Wireshark doesn't support.\n(%s)",
+           err_info);
+      g_free(err_info);
+      errmsg = errmsg_errno;
+      break;
+
+    case WTAP_ERR_CANT_READ:
+      errmsg = "An attempt to read from the capture file %s failed for"
+           " some unknown reason.";
+      break;
+
+    case WTAP_ERR_SHORT_READ:
+      errmsg = "The capture file %s appears to have been cut short"
+           " in the middle of a packet.";
+      break;
+
+    case WTAP_ERR_BAD_RECORD:
+      g_snprintf(errmsg_errno, sizeof(errmsg_errno),
+           "The capture file %%s appears to be damaged or corrupt.\n(%s)",
+           err_info);
+      g_free(err_info);
+      errmsg = errmsg_errno;
+      break;
+
+    default:
+      g_snprintf(errmsg_errno, sizeof(errmsg_errno),
+           "An error occurred while reading the"
+           " capture file %%s: %s.", wtap_strerror(read_err));
+      errmsg = errmsg_errno;
+      break;
+    }
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, errmsg, in_files[i].filename);
       }
     }
@@ -1405,96 +1635,408 @@ cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force)
 
   dfcode=NULL;
 
-  if (dftext == NULL) {
-    /* The new filter is an empty filter (i.e., display all packets).
-     * so leave dfcode==NULL
-     */
-  } else {
-    /*
-     * We have a filter; make a copy of it (as we'll be saving it),
-     * and try to compile it.
-     */
-    dftext = g_strdup(dftext);
-    if (!dfilter_compile(dftext, &dfcode)) {
-      /* The attempt failed; report an error. */
-      gchar *safe_dftext = simple_dialog_format_message(dftext);
-      gchar *safe_dfilter_error_msg = simple_dialog_format_message(
-         dfilter_error_msg);
-      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-          "%s%s%s\n"
-          "\n"
-          "The following display filter isn't a valid display filter:\n%s\n"
-          "See the help for a description of the display filter syntax.",
-          simple_dialog_primary_start(), safe_dfilter_error_msg,
-          simple_dialog_primary_end(), safe_dftext);
-      g_free(safe_dfilter_error_msg);
-      g_free(safe_dftext);
-      g_free(dftext);
-      return CF_ERROR;
+  if (dftext == NULL) {
+    /* The new filter is an empty filter (i.e., display all packets).
+     * so leave dfcode==NULL
+     */
+  } else {
+    /*
+     * We have a filter; make a copy of it (as we'll be saving it),
+     * and try to compile it.
+     */
+    dftext = g_strdup(dftext);
+    if (!dfilter_compile(dftext, &dfcode)) {
+      /* The attempt failed; report an error. */
+      gchar *safe_dftext = simple_dialog_format_message(dftext);
+      gchar *safe_dfilter_error_msg = simple_dialog_format_message(
+      dfilter_error_msg);
+      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+          "%s%s%s\n"
+          "\n"
+          "The following display filter isn't a valid display filter:\n%s\n"
+          "See the help for a description of the display filter syntax.",
+          simple_dialog_primary_start(), safe_dfilter_error_msg,
+          simple_dialog_primary_end(), safe_dftext);
+      g_free(safe_dfilter_error_msg);
+      g_free(safe_dftext);
+      g_free(dftext);
+      return CF_ERROR;
+    }
+
+    /* Was it empty? */
+    if (dfcode == NULL) {
+      /* Yes - free the filter text, and set it to null. */
+      g_free(dftext);
+      dftext = NULL;
+    }
+  }
+
+  /* We have a valid filter.  Replace the current filter. */
+  g_free(cf->dfilter);
+  cf->dfilter = dftext;
+
+  /* Now rescan the packet list, applying the new filter, but not
+     throwing away information constructed on a previous pass. */
+  if (dftext == NULL) {
+    rescan_packets(cf, "Resetting", "Filter", TRUE, FALSE);
+  } else {
+    rescan_packets(cf, "Filtering", dftext, TRUE, FALSE);
+  }
+
+  /* Cleanup and release all dfilter resources */
+  dfilter_free(dfcode);
+
+  return CF_OK;
+}
+
+void
+cf_colorize_packets(capture_file *cf)
+{
+  rescan_packets(cf, "Colorizing", "all packets", FALSE, FALSE);
+}
+
+void
+cf_reftime_packets(capture_file *cf)
+{
+
+#ifdef NEW_PACKET_LIST
+  ref_time_packets(cf);
+#else
+  rescan_packets(cf, "Reprocessing", "all packets", TRUE, TRUE);
+#endif
+}
+
+void
+cf_redissect_packets(capture_file *cf)
+{
+  rescan_packets(cf, "Reprocessing", "all packets", TRUE, TRUE);
+}
+
+/* Rescan the list of packets, reconstructing the CList.
+
+   "action" describes why we're doing this; it's used in the progress
+   dialog box.
+
+   "action_item" describes what we're doing; it's used in the progress
+   dialog box.
+
+   "refilter" is TRUE if we need to re-evaluate the filter expression.
+
+   "redissect" is TRUE if we need to make the dissectors reconstruct
+   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). */
+#ifdef NEW_PACKET_LIST
+static void
+rescan_packets(capture_file *cf, const char *action, const char *action_item,
+        gboolean refilter, gboolean redissect)
+{
+    /* 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;
+  gboolean compiled;
+
+  /* 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.
+   */
+  compiled = dfilter_compile(cf->dfilter, &dfcode);
+  g_assert(!cf->dfilter || (compiled && 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();
+
+  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);
+  nstime_set_unset(&prev_cap_ts);
+  cum_bytes = 0;
+
+  /* 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_start; 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;
+      frame_data_cleanup(fdata);
+
+      /* cleanup_dissection() calls se_free_all();
+       * And after that fdata->col_text (which is allocated using se_alloc0())
+       * no longer points to valid memory.
+       */
+        fdata->col_text_len = se_alloc0(sizeof(fdata->col_text_len) * (cf->cinfo.num_cols));
+        fdata->col_text = se_alloc0(sizeof(fdata->col_text) * (cf->cinfo.num_cols));
+    }
+
+    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);
 
-    /* Was it empty? */
-    if (dfcode == NULL) {
-      /* Yes - free the filter text, and set it to null. */
-      g_free(dftext);
-      dftext = NULL;
+    /* 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 have a valid filter.  Replace the current filter. */
-  g_free(cf->dfilter);
-  cf->dfilter = dftext;
+  /* We are done redissecting the packet list. */
+  cf->redissecting = FALSE;
 
-  /* Now rescan the packet list, applying the new filter, but not
-     throwing away information constructed on a previous pass. */
-  if (dftext == NULL) {
-    rescan_packets(cf, "Resetting", "Filter", TRUE, FALSE);
-  } else {
-    rescan_packets(cf, "Filtering", dftext, TRUE, FALSE);
-  }
+  if (redissect) {
+    /* Clear out what remains of the visited flags and per-frame data
+       pointers.
 
-  /* Cleanup and release all dfilter resources */
-  if (dfcode != NULL){
-    dfilter_free(dfcode);
+       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;
+      frame_data_cleanup(fdata);
+    }
   }
-  return CF_OK;
-}
 
-void
-cf_colorize_packets(capture_file *cf)
-{
-  rescan_packets(cf, "Colorizing", "all packets", FALSE, FALSE);
-}
+  /* We're done filtering the packets; destroy the progress bar if it
+     was created. */
+  if (progbar != NULL)
+    destroy_progress_dlg(progbar);
 
-void
-cf_reftime_packets(capture_file *cf)
-{
-  rescan_packets(cf, "Updating Reftime", "all packets", FALSE, FALSE);
-}
+  /* Unfreeze the packet list. */
+  if (!add_to_packet_list)
+    new_packet_list_recreate_visible_rows();
 
-void
-cf_redissect_packets(capture_file *cf)
-{
-  rescan_packets(cf, "Reprocessing", "all packets", TRUE, TRUE);
-}
+  new_packet_list_thaw();
 
-/* Rescan the list of packets, reconstructing the CList.
+  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;
+      }
+    }
+  }
 
-   "action" describes why we're doing this; it's used in the progress
-   dialog box.
+  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);
+    }
+  }
 
-   "action_item" describes what we're doing; it's used in the progress
-   dialog box.
+  /* Cleanup and release all dfilter resources */
+  dfilter_free(dfcode);
+}
 
-   "refilter" is TRUE if we need to re-evaluate the filter expression.
+#else
 
-   "redissect" is TRUE if we need to make the dissectors reconstruct
-   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). */
 static void
 rescan_packets(capture_file *cf, const char *action, const char *action_item,
-               gboolean refilter, gboolean redissect)
+        gboolean refilter, gboolean redissect)
 {
   frame_data *fdata;
   progdlg_t  *progbar = NULL;
@@ -1512,17 +2054,24 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
   int         progbar_nextstep;
   int         progbar_quantum;
   dfilter_t   *dfcode;
+  gboolean    filtering_tap_listeners;
+  guint       tap_flags;
+  gboolean    add_to_packet_list = TRUE;
+  gboolean compiled;
 
   /* 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);
-  }
+  compiled = dfilter_compile(cf->dfilter, &dfcode);
+  g_assert(!cf->dfilter || (compiled && 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"
@@ -1534,6 +2083,13 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
      rebuild the clist, however. */
   selected_row = -1;
 
+  /* Freeze the packet list while we redo it, so we don't get any
+     screen updates while it happens. */
+  packet_list_freeze();
+
+  /* Clear it out. */
+  packet_list_clear();
+
   if (redissect) {
     /* We need to re-initialize all the state information that protocols
        keep, because some preference that controls a dissector has changed,
@@ -1544,21 +2100,19 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
        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();
-  }
-
-  /* Freeze the packet list while we redo it, so we don't get any
-     screen updates while it happens. */
-  packet_list_freeze();
 
-  /* Clear it out. */
-  packet_list_clear();
+  }
 
   /* 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;
 
@@ -1567,6 +2121,7 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
      the display list. */
   nstime_set_unset(&first_ts);
   nstime_set_unset(&prev_dis_ts);
+  cum_bytes = 0;
 
   /* Update the progress bar when it gets to this value. */
   progbar_nextstep = 0;
@@ -1581,7 +2136,7 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
   stop_flag = FALSE;
   g_get_current_time(&start_time);
 
-  row = -1;            /* no previous row yet */
+  row = -1;     /* no previous row yet */
   prev_row = -1;
   prev_frame = NULL;
 
@@ -1592,7 +2147,7 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
 
   selected_frame_seen = FALSE;
 
-  for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
+  for (fdata = cf->plist_start; 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
@@ -1628,15 +2183,15 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
       /* 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. */
+     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;
     }
 
@@ -1646,19 +2201,17 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
       /* 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. */
+       * "init_dissection()"), and null out the GSList pointer.
+       */
       fdata->flags.visited = 0;
-      if (fdata->pfd) {
-       g_slist_free(fdata->pfd);
-        fdata->pfd = NULL;
-      }
+      frame_data_cleanup(fdata);
     }
 
     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;
+        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
@@ -1668,8 +2221,10 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
       preceding_row = prev_row;
       preceding_frame = prev_frame;
     }
-    row = add_packet_to_packet_list(fdata, cf, dfcode, &cf->pseudo_header, cf->pd,
-                                       refilter);
+    row = 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 -
@@ -1693,9 +2248,6 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
   /* We are done redissecting the packet list. */
   cf->redissecting = FALSE;
 
-  /* Re-sort the list using the previously selected order */
-  packet_list_set_sort_column();
-
   if (redissect) {
     /* Clear out what remains of the visited flags and per-frame data
        pointers.
@@ -1708,10 +2260,7 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
        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;
-      }
+      frame_data_cleanup(fdata);
     }
   }
 
@@ -1750,7 +2299,7 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
         selected_row = following_row;
       } else {
         /* Frames before and after the selected frame passed the filter, so
-          we'll select the previous frame */
+           we'll select the previous frame */
         selected_row = preceding_row;
       }
     }
@@ -1771,10 +2320,81 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item,
   }
 
   /* Cleanup and release all dfilter resources */
-  if (dfcode != NULL){
-    dfilter_free(dfcode);
+  dfilter_free(dfcode);
+}
+#endif /* NEW_PACKET_LIST */
+
+/*
+ * Scan trough all frame data and recalculate the ref time
+ * without rereading the file.
+ * XXX - do we need a progres bar or is this fast enough?
+ */
+#ifdef NEW_PACKET_LIST
+static void
+ref_time_packets(capture_file *cf)
+{
+  frame_data *fdata;
+
+  nstime_set_unset(&first_ts);
+  nstime_set_unset(&prev_dis_ts);
+  nstime_set_unset(&prev_cap_ts);
+  cum_bytes = 0;
+
+  for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
+    /* just add some value here until we know if it is being displayed or not */
+    fdata->cum_bytes = cum_bytes + fdata->pkt_len;
+
+    /* If we don't have the time stamp of the first packet in the
+     capture, it's because this is the first packet.  Save the time
+     stamp of this packet as the time stamp of the first packet. */
+    if (nstime_is_unset(&first_ts)) {
+        first_ts  = fdata->abs_ts;
+    }
+      /* if this frames is marked as a reference time frame, reset
+        firstsec and firstusec to this frame */
+    if(fdata->flags.ref_time){
+    first_ts = fdata->abs_ts;
+    }
+
+    /* If we don't have the time stamp of the previous displayed packet,
+     it's because this is the first displayed packet.  Save the time
+     stamp of this packet as the time stamp of the previous displayed
+     packet. */
+    if (nstime_is_unset(&prev_dis_ts)) {
+        prev_dis_ts = fdata->abs_ts;
+    }
+
+    /* Get the time elapsed between the first packet and this packet. */
+    nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
+
+    /* If it's greater than the current elapsed time, set the elapsed time
+     to it (we check for "greater than" so as not to be confused by
+     time moving backwards). */
+    if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
+        || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
+        cf->elapsed_time = fdata->rel_ts;
+    }
+
+    /* Get the time elapsed between the previous displayed packet and
+     this packet. */
+    nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
+
+    if( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) ){
+        /* This frame either passed the display filter list or is marked as
+        a time reference frame.  All time reference frames are displayed
+        even if they dont pass the display filter */
+        if(fdata->flags.ref_time){
+            /* if this was a TIME REF frame we should reset the cul bytes field */
+            cum_bytes = fdata->pkt_len;
+            fdata->cum_bytes =  cum_bytes;
+        } else {
+            /* increase cum_bytes with this packets length */
+            cum_bytes += fdata->pkt_len;
+        }
+    }
   }
 }
+#endif
 
 typedef enum {
   PSP_FINISHED,
@@ -1823,7 +2443,7 @@ process_specified_packets(capture_file *cf, packet_range_t *range,
 
   /* Iterate through the list of packets, printing the packets that
      were selected by the current display filter.  */
-  for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
+  for (fdata = cf->plist_start; 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
@@ -1902,30 +2522,48 @@ process_specified_packets(capture_file *cf, packet_range_t *range,
   return ret;
 }
 
+typedef struct {
+  gboolean construct_protocol_tree;
+  column_info *cinfo;
+} retap_callback_args_t;
+
 static gboolean
 retap_packet(capture_file *cf _U_, frame_data *fdata,
              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
              void *argsp)
 {
-  column_info *cinfo = argsp;
-  epan_dissect_t *edt;
+  retap_callback_args_t *args = argsp;
+  epan_dissect_t edt;
 
-  /* If we have tap listeners, allocate a protocol tree root node, so that
-     we'll construct a protocol tree against which a filter expression can
-     be evaluated. */
-  edt = epan_dissect_new(num_tap_filters != 0, FALSE);
-  tap_queue_init(edt);
-  epan_dissect_run(edt, pseudo_header, pd, fdata, cinfo);
-  tap_push_tapped_queue(edt);
-  epan_dissect_free(edt);
+  epan_dissect_init(&edt, args->construct_protocol_tree, FALSE);
+  tap_queue_init(&edt);
+  epan_dissect_run(&edt, pseudo_header, pd, fdata, args->cinfo);
+  tap_push_tapped_queue(&edt);
+  epan_dissect_cleanup(&edt);
 
   return TRUE;
 }
 
 cf_read_status_t
-cf_retap_packets(capture_file *cf, gboolean do_columns)
+cf_retap_packets(capture_file *cf)
 {
   packet_range_t range;
+  retap_callback_args_t callback_args;
+  gboolean filtering_tap_listeners;
+  guint tap_flags;
+
+  /* Do we have any tap listeners with filters? */
+  filtering_tap_listeners = have_filtering_tap_listeners();
+
+  tap_flags = union_of_tap_listener_flags();
+
+  /* If any tap listeners have filters, or require the protocol tree,
+     construct the protocol tree. */
+  callback_args.construct_protocol_tree = filtering_tap_listeners ||
+                                          (tap_flags & TL_REQUIRES_PROTO_TREE);
+
+  /* If any tap listeners require the columns, construct them. */
+  callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
 
   /* Reset the tap listeners. */
   reset_tap_listeners();
@@ -1934,9 +2572,9 @@ cf_retap_packets(capture_file *cf, gboolean do_columns)
      re-running the taps. */
   packet_range_init(&range);
   packet_range_process_init(&range);
-  switch (process_specified_packets(cf, &range, "Refiltering statistics on",
+  switch (process_specified_packets(cf, &range, "Recalculating statistics on",
                                     "all packets", TRUE, retap_packet,
-                                    do_columns ? &cf->cinfo : NULL)) {
+                                    &callback_args)) {
   case PSP_FINISHED:
     /* Completed successfully. */
     return CF_READ_OK;
@@ -1973,30 +2611,30 @@ print_packet(capture_file *cf, frame_data *fdata,
              void *argsp)
 {
   print_callback_args_t *args = argsp;
-  epan_dissect_t *edt;
+  epan_dissect_t edt;
   int             i;
   char           *cp;
   int             line_len;
   int             column_len;
   int             cp_off;
   gboolean        proto_tree_needed;
-  char            bookmark_name[9+10+1];       /* "__frameNNNNNNNNNN__\0" */
-  char            bookmark_title[6+10+1];      /* "Frame NNNNNNNNNN__\0" */
+  char            bookmark_name[9+10+1];    /* "__frameNNNNNNNNNN__\0" */
+  char            bookmark_title[6+10+1];   /* "Frame NNNNNNNNNN__\0" */
 
   /* Create the protocol tree, and make it visible, if we're printing
      the dissection or the hex data.
      XXX - do we need it if we're just printing the hex data? */
   proto_tree_needed =
       args->print_args->print_dissections != print_dissections_none || args->print_args->print_hex || have_custom_cols(&cf->cinfo);
-  edt = epan_dissect_new(proto_tree_needed, proto_tree_needed);
+  epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
 
   /* Fill in the column information if we're printing the summary
      information. */
   if (args->print_args->print_summary) {
-    epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
-    epan_dissect_fill_in_columns(edt);
+    epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
+    epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
   } else
-    epan_dissect_run(edt, pseudo_header, pd, fdata, NULL);
+    epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
 
   if (args->print_formfeed) {
     if (!new_page(args->print_args->stream))
@@ -2018,7 +2656,7 @@ print_packet(capture_file *cf, frame_data *fdata,
     if (args->print_header_line) {
       if (!print_line(args->print_args->stream, 0, args->header_line_buf))
         goto fail;
-      args->print_header_line = FALSE; /* we might not need to print any more */
+      args->print_header_line = FALSE;  /* we might not need to print any more */
     }
     cp = &args->line_buf[0];
     line_len = 0;
@@ -2030,7 +2668,7 @@ print_packet(capture_file *cf, frame_data *fdata,
 
       /* Make sure there's room in the line buffer for the column; if not,
          double its length. */
-      line_len += column_len + 1;      /* "+1" for space */
+      line_len += column_len + 1;   /* "+1" for space */
       if (line_len > args->line_buf_len) {
         cp_off = (int) (cp - args->line_buf);
         args->line_buf_len = 2 * line_len;
@@ -2077,7 +2715,7 @@ print_packet(capture_file *cf, frame_data *fdata,
     }
 
     /* Print the information in that tree. */
-    if (!proto_tree_print(args->print_args, edt, args->print_args->stream))
+    if (!proto_tree_print(args->print_args, &edt, args->print_args->stream))
       goto fail;
 
     /* Print a blank line if we print anything after this (aka more than one packet). */
@@ -2089,7 +2727,7 @@ print_packet(capture_file *cf, frame_data *fdata,
 
   if (args->print_args->print_hex) {
     /* Print the full packet data as hex. */
-    if (!print_hex_data(args->print_args->stream, edt))
+    if (!print_hex_data(args->print_args->stream, &edt))
       goto fail;
 
     /* Print a blank line if we print anything after this (aka more than one packet). */
@@ -2099,7 +2737,7 @@ print_packet(capture_file *cf, frame_data *fdata,
     args->print_header_line = TRUE;
   } /* if (args->print_args->print_dissections != print_dissections_none) */
 
-  epan_dissect_free(edt);
+  epan_dissect_cleanup(&edt);
 
   /* do we want to have a formfeed between each packet from now on? */
   if(args->print_args->print_formfeed) {
@@ -2109,7 +2747,7 @@ print_packet(capture_file *cf, frame_data *fdata,
   return TRUE;
 
 fail:
-  epan_dissect_free(edt);
+  epan_dissect_cleanup(&edt);
   return FALSE;
 }
 
@@ -2169,7 +2807,7 @@ cf_print_packets(capture_file *cf, print_args_t *print_args)
 
       /* Make sure there's room in the line buffer for the column; if not,
          double its length. */
-      line_len += column_len + 1;      /* "+1" for space */
+      line_len += column_len + 1;   /* "+1" for space */
       if (line_len > callback_args.header_line_buf_len) {
         cp_off = (int) (cp - callback_args.header_line_buf);
         callback_args.header_line_buf_len = 2 * line_len;
@@ -2245,19 +2883,19 @@ cf_print_packets(capture_file *cf, print_args_t *print_args)
 static gboolean
 write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
-                 void *argsp)
+          void *argsp)
 {
   FILE *fh = argsp;
-  epan_dissect_t *edt;
+  epan_dissect_t edt;
 
   /* Create the protocol tree, but don't fill in the column information. */
-  edt = epan_dissect_new(TRUE, TRUE);
-  epan_dissect_run(edt, pseudo_header, pd, fdata, NULL);
+  epan_dissect_init(&edt, TRUE, TRUE);
+  epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
 
   /* Write out the information in that tree. */
-  proto_tree_write_pdml(edt, fh);
+  proto_tree_write_pdml(&edt, fh);
 
-  epan_dissect_free(edt);
+  epan_dissect_cleanup(&edt);
 
   return !ferror(fh);
 }
@@ -2270,7 +2908,7 @@ cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
 
   fh = ws_fopen(print_args->file, "w");
   if (fh == NULL)
-    return CF_PRINT_OPEN_ERROR;        /* attempt to open destination failed */
+    return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
 
   write_pdml_preamble(fh);
   if (ferror(fh)) {
@@ -2315,23 +2953,23 @@ cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
 static gboolean
 write_psml_packet(capture_file *cf, frame_data *fdata,
                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
-                 void *argsp)
+          void *argsp)
 {
   FILE *fh = argsp;
-  epan_dissect_t *edt;
+  epan_dissect_t edt;
   gboolean proto_tree_needed;
 
   /* Fill in the column information, only create the protocol tree
      if having custom columns. */
   proto_tree_needed = have_custom_cols(&cf->cinfo);
-  edt = epan_dissect_new(proto_tree_needed, proto_tree_needed);
-  epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
-  epan_dissect_fill_in_columns(edt);
+  epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
+  epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
+  epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
 
   /* Write out the information in that tree. */
-  proto_tree_write_psml(edt, fh);
+  proto_tree_write_psml(&edt, fh);
 
-  epan_dissect_free(edt);
+  epan_dissect_cleanup(&edt);
 
   return !ferror(fh);
 }
@@ -2344,7 +2982,7 @@ cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
 
   fh = ws_fopen(print_args->file, "w");
   if (fh == NULL)
-    return CF_PRINT_OPEN_ERROR;        /* attempt to open destination failed */
+    return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
 
   write_psml_preamble(fh);
   if (ferror(fh)) {
@@ -2392,20 +3030,20 @@ write_csv_packet(capture_file *cf, frame_data *fdata,
                  void *argsp)
 {
   FILE *fh = argsp;
-  epan_dissect_t *edt;
+  epan_dissect_t edt;
   gboolean proto_tree_needed;
 
   /* Fill in the column information, only create the protocol tree
      if having custom columns. */
   proto_tree_needed = have_custom_cols(&cf->cinfo);
-  edt = epan_dissect_new(proto_tree_needed, proto_tree_needed);
-  epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
-  epan_dissect_fill_in_columns(edt);
+  epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
+  epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
+  epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
 
   /* Write out the information in that tree. */
-  proto_tree_write_csv(edt, fh);
+  proto_tree_write_csv(&edt, fh);
 
-  epan_dissect_free(edt);
+  epan_dissect_cleanup(&edt);
 
   return !ferror(fh);
 }
@@ -2462,8 +3100,8 @@ cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
 
 static gboolean
 write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
-                    union wtap_pseudo_header *pseudo_header _U_,
-                    const guint8 *pd, void *argsp)
+             union wtap_pseudo_header *pseudo_header _U_,
+             const guint8 *pd, void *argsp)
 {
   FILE *fh = argsp;
 
@@ -2492,8 +3130,8 @@ cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
   /* Iterate through the list of packets, printing the packets we were
      told to print. */
   ret = process_specified_packets(cf, &print_args->range,
-                                 "Writing C Arrays",
-                                 "selected packets", TRUE,
+                  "Writing C Arrays",
+                  "selected packets", TRUE,
                                   write_carrays_packet, fh);
   switch (ret) {
   case PSP_FINISHED:
@@ -2519,18 +3157,20 @@ cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
   return CF_PRINT_OK;
 }
 
+#ifndef NEW_PACKET_LIST /* This function is not needed with the new packet list */
+
 /* Scan through the packet list and change all columns that use the
    "command-line-specified" time stamp format to use the current
    value of that format. */
 void
 cf_change_time_formats(capture_file *cf)
 {
+  int         i;
   frame_data *fdata;
   progdlg_t  *progbar = NULL;
   gboolean    stop_flag;
   int         count;
   int         row;
-  int         i;
   float       progbar_val;
   GTimeVal    start_time;
   gchar       status_str[100];
@@ -2538,8 +3178,7 @@ cf_change_time_formats(capture_file *cf)
   int         progbar_quantum;
   gboolean    sorted_by_frame_column;
 
-
-  /* adjust timestamp precision if auto is selected */
+  /* Adjust timestamp precision if auto is selected */
   cf_timestamp_auto_precision(cf);
 
   /* Are there any columns with time stamps in the "command-line-specified"
@@ -2601,7 +3240,7 @@ cf_change_time_formats(capture_file *cf)
      is in a row of the summary list and, if so, whether there are
      any columns that show the time in the "command-line-specified"
      format and, if so, update that row. */
-  for (fdata = cf->plist, row = -1; fdata != NULL; fdata = fdata->next) {
+  for (fdata = cf->plist_start, row = -1; 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
@@ -2637,8 +3276,8 @@ cf_change_time_formats(capture_file *cf)
       /* Well, the user decided to abort the redisplay.  Just stop.
 
          XXX - this leaves the time field in the old format in
-        frames we haven't yet processed.  So it goes; should we
-        simply not offer them the option of stopping? */
+     frames we haven't yet processed.  So it goes; should we
+     simply not offer them the option of stopping? */
       break;
     }
 
@@ -2655,9 +3294,9 @@ cf_change_time_formats(capture_file *cf)
          (which is why we can only do it when the display is sorted
          by the frame number). */
       if (fdata->flags.passed_dfilter)
-       row++;
+        row++;
       else
-       continue;
+        continue;
     }
 
     if (row != -1) {
@@ -2691,18 +3330,20 @@ cf_change_time_formats(capture_file *cf)
   /* Unfreeze the packet list. */
   packet_list_thaw();
 }
+#endif /* NEW_PACKET_LIST */
+
 
 typedef struct {
-       const char      *string;
-       size_t          string_len;
-       capture_file    *cf;
-       gboolean        frame_matched;
+    const char  *string;
+    size_t      string_len;
+    capture_file    *cf;
+    gboolean    frame_matched;
 } match_data;
 
 gboolean
 cf_find_packet_protocol_tree(capture_file *cf, const char *string)
 {
-  match_data           mdata;
+  match_data        mdata;
 
   mdata.string = string;
   mdata.string_len = strlen(string);
@@ -2712,36 +3353,38 @@ cf_find_packet_protocol_tree(capture_file *cf, const char *string)
 static gboolean
 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
 {
-  match_data           *mdata = criterion;
-  epan_dissect_t       *edt;
+  match_data        *mdata = criterion;
+  epan_dissect_t    edt;
 
   /* Construct the protocol tree, including the displayed text */
-  edt = epan_dissect_new(TRUE, TRUE);
+  epan_dissect_init(&edt, TRUE, TRUE);
   /* We don't need the column information */
-  epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, NULL);
+  epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
 
   /* Iterate through all the nodes, seeing if they have text that matches. */
   mdata->cf = cf;
   mdata->frame_matched = FALSE;
-  proto_tree_children_foreach(edt->tree, match_subtree_text, mdata);
-  epan_dissect_free(edt);
+  proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
+  epan_dissect_cleanup(&edt);
   return mdata->frame_matched;
 }
 
 static void
 match_subtree_text(proto_node *node, gpointer data)
 {
-  match_data   *mdata = (match_data*) data;
-  const gchar  *string = mdata->string;
-  size_t       string_len = mdata->string_len;
-  capture_file *cf = mdata->cf;
-  field_info   *fi = PITEM_FINFO(node);
-  gchar                label_str[ITEM_LABEL_LENGTH];
-  gchar                *label_ptr;
-  size_t       label_len;
-  guint32      i;
-  guint8       c_char;
-  size_t       c_match = 0;
+  match_data    *mdata = (match_data*) data;
+  const gchar   *string = mdata->string;
+  size_t    string_len = mdata->string_len;
+  capture_file  *cf = mdata->cf;
+  field_info    *fi = PNODE_FINFO(node);
+  gchar     label_str[ITEM_LABEL_LENGTH];
+  gchar     *label_ptr;
+  size_t    label_len;
+  guint32   i;
+  guint8    c_char;
+  size_t    c_match = 0;
+
+  g_assert(fi && "dissection with an invisible proto tree?");
 
   if (mdata->frame_matched) {
     /* We already had a match; don't bother doing any more work. */
@@ -2770,9 +3413,9 @@ match_subtree_text(proto_node *node, gpointer data)
     if (c_char == string[c_match]) {
       c_match++;
       if (c_match == string_len) {
-       /* No need to look further; we have a match */
-       mdata->frame_matched = TRUE;
-       return;
+    /* No need to look further; we have a match */
+    mdata->frame_matched = TRUE;
+    return;
       }
     } else
       c_match = 0;
@@ -2786,7 +3429,7 @@ match_subtree_text(proto_node *node, gpointer data)
 gboolean
 cf_find_packet_summary_line(capture_file *cf, const char *string)
 {
-  match_data           mdata;
+  match_data        mdata;
 
   mdata.string = string;
   mdata.string_len = strlen(string);
@@ -2796,53 +3439,53 @@ cf_find_packet_summary_line(capture_file *cf, const char *string)
 static gboolean
 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
 {
-  match_data           *mdata = criterion;
-  const gchar          *string = mdata->string;
-  size_t               string_len = mdata->string_len;
-  epan_dissect_t       *edt;
-  const char           *info_column;
-  size_t               info_column_len;
-  gboolean             frame_matched = FALSE;
-  gint                 colx;
-  guint32              i;
-  guint8               c_char;
-  size_t               c_match = 0;
+  match_data        *mdata = criterion;
+  const gchar       *string = mdata->string;
+  size_t        string_len = mdata->string_len;
+  epan_dissect_t    edt;
+  const char        *info_column;
+  size_t        info_column_len;
+  gboolean      frame_matched = FALSE;
+  gint          colx;
+  guint32       i;
+  guint8        c_char;
+  size_t        c_match = 0;
 
   /* Don't bother constructing the protocol tree */
-  edt = epan_dissect_new(FALSE, FALSE);
+  epan_dissect_init(&edt, FALSE, FALSE);
   /* Get the column information */
-  epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, &cf->cinfo);
+  epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, &cf->cinfo);
 
   /* Find the Info column */
   for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
     if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
       /* Found it.  See if we match. */
-      info_column = edt->pi.cinfo->col_data[colx];
+      info_column = edt.pi.cinfo->col_data[colx];
       info_column_len = strlen(info_column);
       for (i = 0; i < info_column_len; i++) {
-       c_char = info_column[i];
-       if (cf->case_type)
-         c_char = toupper(c_char);
-       if (c_char == string[c_match]) {
-         c_match++;
-         if (c_match == string_len) {
-           frame_matched = TRUE;
-           break;
-         }
-       } else
-         c_match = 0;
+    c_char = info_column[i];
+    if (cf->case_type)
+      c_char = toupper(c_char);
+    if (c_char == string[c_match]) {
+      c_match++;
+      if (c_match == string_len) {
+        frame_matched = TRUE;
+        break;
+      }
+    } else
+      c_match = 0;
       }
       break;
     }
   }
-  epan_dissect_free(edt);
+  epan_dissect_cleanup(&edt);
   return frame_matched;
 }
 
 typedef struct {
-       const guint8 *data;
-       size_t data_len;
-} cbs_t;       /* "Counted byte string" */
+    const guint8 *data;
+    size_t data_len;
+} cbs_t;    /* "Counted byte string" */
 
 gboolean
 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size)
@@ -2877,14 +3520,14 @@ cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size)
 static gboolean
 match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
 {
-  cbs_t                *info = criterion;
-  const guint8 *ascii_text = info->data;
-  size_t       textlen = info->data_len;
-  gboolean     frame_matched;
-  guint32      buf_len;
-  guint32      i;
-  guint8       c_char;
-  size_t       c_match = 0;
+  cbs_t     *info = criterion;
+  const guint8  *ascii_text = info->data;
+  size_t    textlen = info->data_len;
+  gboolean  frame_matched;
+  guint32   buf_len;
+  guint32   i;
+  guint8    c_char;
+  size_t    c_match = 0;
 
   frame_matched = FALSE;
   buf_len = fdata->pkt_len;
@@ -2894,15 +3537,15 @@ match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
       c_char = toupper(c_char);
     if (c_char != 0) {
       if (c_char == ascii_text[c_match]) {
-       c_match++;
-       if (c_match == textlen) {
-         frame_matched = TRUE;
-         cf->search_pos = i; /* Save the position of the last character
-                              for highlighting the field. */
-         break;
-       }
+    c_match++;
+    if (c_match == textlen) {
+      frame_matched = TRUE;
+      cf->search_pos = i; /* Save the position of the last character
+                   for highlighting the field. */
+      break;
+    }
       } else
-       c_match = 0;
+    c_match = 0;
     }
   }
   return frame_matched;
@@ -2911,14 +3554,14 @@ match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
 static gboolean
 match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
 {
-  cbs_t                *info = criterion;
-  const guint8 *ascii_text = info->data;
-  size_t       textlen = info->data_len;
-  gboolean     frame_matched;
-  guint32      buf_len;
-  guint32      i;
-  guint8       c_char;
-  size_t       c_match = 0;
+  cbs_t     *info = criterion;
+  const guint8  *ascii_text = info->data;
+  size_t    textlen = info->data_len;
+  gboolean  frame_matched;
+  guint32   buf_len;
+  guint32   i;
+  guint8    c_char;
+  size_t    c_match = 0;
 
   frame_matched = FALSE;
   buf_len = fdata->pkt_len;
@@ -2929,10 +3572,10 @@ match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
     if (c_char == ascii_text[c_match]) {
       c_match++;
       if (c_match == textlen) {
-       frame_matched = TRUE;
-       cf->search_pos = i; /* Save the position of the last character
-                              for highlighting the field. */
-       break;
+    frame_matched = TRUE;
+    cf->search_pos = i; /* Save the position of the last character
+                   for highlighting the field. */
+    break;
       }
     } else
       c_match = 0;
@@ -2943,14 +3586,14 @@ match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
 static gboolean
 match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
 {
-  cbs_t                *info = criterion;
-  const guint8 *ascii_text = info->data;
-  size_t       textlen = info->data_len;
-  gboolean     frame_matched;
-  guint32      buf_len;
-  guint32      i;
-  guint8       c_char;
-  size_t       c_match = 0;
+  cbs_t     *info = criterion;
+  const guint8  *ascii_text = info->data;
+  size_t    textlen = info->data_len;
+  gboolean  frame_matched;
+  guint32   buf_len;
+  guint32   i;
+  guint8    c_char;
+  size_t    c_match = 0;
 
   frame_matched = FALSE;
   buf_len = fdata->pkt_len;
@@ -2962,10 +3605,10 @@ match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
       c_match++;
       i++;
       if (c_match == textlen) {
-       frame_matched = TRUE;
-       cf->search_pos = i; /* Save the position of the last character
-                              for highlighting the field. */
-       break;
+    frame_matched = TRUE;
+    cf->search_pos = i; /* Save the position of the last character
+                   for highlighting the field. */
+    break;
       }
     } else
       c_match = 0;
@@ -2976,13 +3619,13 @@ match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
 static gboolean
 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
 {
-  cbs_t                *info = criterion;
-  const guint8 *binary_data = info->data;
-  size_t       datalen = info->data_len;
-  gboolean     frame_matched;
-  guint32      buf_len;
-  guint32      i;
-  size_t       c_match = 0;
+  cbs_t     *info = criterion;
+  const guint8  *binary_data = info->data;
+  size_t    datalen = info->data_len;
+  gboolean  frame_matched;
+  guint32   buf_len;
+  guint32   i;
+  size_t    c_match = 0;
 
   frame_matched = FALSE;
   buf_len = fdata->pkt_len;
@@ -2990,10 +3633,10 @@ match_binary(capture_file *cf, frame_data *fdata, void *criterion)
     if (cf->pd[i] == binary_data[c_match]) {
       c_match++;
       if (c_match == datalen) {
-       frame_matched = TRUE;
-       cf->search_pos = i; /* Save the position of the last character
-                              for highlighting the field. */
-       break;
+    frame_matched = TRUE;
+    cf->search_pos = i; /* Save the position of the last character
+                   for highlighting the field. */
+    break;
       }
     } else
       c_match = 0;
@@ -3010,15 +3653,15 @@ cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode)
 static gboolean
 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
 {
-  dfilter_t            *sfcode = criterion;
-  epan_dissect_t       *edt;
-  gboolean             frame_matched;
-
-  edt = epan_dissect_new(TRUE, FALSE);
-  epan_dissect_prime_dfilter(edt, sfcode);
-  epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, NULL);
-  frame_matched = dfilter_apply_edt(sfcode, edt);
-  epan_dissect_free(edt);
+  dfilter_t     *sfcode = criterion;
+  epan_dissect_t    edt;
+  gboolean      frame_matched;
+
+  epan_dissect_init(&edt, TRUE, FALSE);
+  epan_dissect_prime_dfilter(&edt, sfcode);
+  epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
+  frame_matched = dfilter_apply_edt(sfcode, &edt);
+  epan_dissect_cleanup(&edt);
   return frame_matched;
 }
 
@@ -3122,7 +3765,7 @@ find_packet(capture_file *cf,
                             "%sBeginning of capture exceeded!%s\n\n"
                             "Search is continued from the end of the capture.",
                             simple_dialog_primary_start(), simple_dialog_primary_end());
-              fdata = cf->plist_end;   /* wrap around */
+              fdata = cf->plist_end;    /* wrap around */
           }
           else
           {
@@ -3143,7 +3786,7 @@ find_packet(capture_file *cf,
                             "%sEnd of capture exceeded!%s\n\n"
                             "Search is continued from the start of the capture.",
                             simple_dialog_primary_start(), simple_dialog_primary_end());
-              fdata = cf->plist;       /* wrap around */
+              fdata = cf->plist_start;    /* wrap around */
           }
           else
           {
@@ -3160,27 +3803,27 @@ find_packet(capture_file *cf,
 
       /* Is this packet in the display? */
       if (fdata->flags.passed_dfilter) {
-       /* Yes.  Load its data. */
+        /* Yes.  Load its data. */
         if (!wtap_seek_read(cf->wth, fdata->file_off, &cf->pseudo_header,
-                       cf->pd, fdata->cap_len, &err, &err_info)) {
+                cf->pd, fdata->cap_len, &err, &err_info)) {
           /* Read error.  Report the error, and go back to the frame
              where we started. */
           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                       cf_read_error_message(err, err_info), cf->filename);
+            cf_read_error_message(err, err_info), cf->filename);
           new_fd = start_fd;
           break;
         }
 
-       /* Does it match the search criterion? */
-       if ((*match_function)(cf, fdata, criterion)) {
+    /* Does it match the search criterion? */
+    if ((*match_function)(cf, fdata, criterion)) {
           new_fd = fdata;
-          break;       /* found it! */
+          break;    /* found it! */
         }
       }
 
       if (fdata == start_fd) {
         /* We're back to the frame we were on originally, and that frame
-          doesn't match the search filter.  The search failed. */
+       doesn't match the search filter.  The search failed. */
         break;
       }
     }
@@ -3192,19 +3835,31 @@ find_packet(capture_file *cf,
   }
 
   if (new_fd != NULL) {
+#ifdef NEW_PACKET_LIST
+      /* Find and select */
+      row = new_packet_list_find_row_from_data(fdata, TRUE);
+#else
     /* We found a frame.  Find what row it's in. */
     row = packet_list_find_row_from_data(new_fd);
-    if (row == -1)
+#endif /* NEW_PACKET_LIST */
+    if (row == -1) {
         /* We didn't find a row even though we know that a frame
          * exists that satifies the search criteria. This means that the
          * frame isn't being displayed currently so we can't select it. */
+        simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
+                      "%sEnd of capture exceeded!%s\n\n"
+                      "The capture file is probably not fully loaded.",
+                      simple_dialog_primary_start(), simple_dialog_primary_end());
         return FALSE;
+    }
 
+#ifndef NEW_PACKET_LIST
     /* Select that row, make it the focus row, and make it visible. */
     packet_list_set_selected_row(row);
-    return TRUE;       /* success */
+#endif /* NEW_PACKET_LIST */
+    return TRUE;    /* success */
   } else
-    return FALSE;      /* failure */
+    return FALSE;   /* failure */
 }
 
 gboolean
@@ -3213,23 +3868,26 @@ cf_goto_frame(capture_file *cf, guint fnumber)
   frame_data *fdata;
   int row;
 
-  for (fdata = cf->plist; fdata != NULL && fdata->num < fnumber; fdata = fdata->next)
+  for (fdata = cf->plist_start; fdata != NULL && fdata->num < fnumber; fdata = fdata->next)
     ;
 
   if (fdata == NULL) {
     /* we didn't find a packet with that packet number */
     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                 "There is no packet with the packet number %u.", fnumber);
-    return FALSE;      /* we failed to go to that packet */
+          "There is no packet with the packet number %u.", fnumber);
+    return FALSE;   /* we failed to go to that packet */
   }
   if (!fdata->flags.passed_dfilter) {
     /* that packet currently isn't displayed */
     /* XXX - add it to the set of displayed packets? */
     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                 "The packet number %u isn't currently being displayed.", fnumber);
-    return FALSE;      /* we failed to go to that packet */
+          "The packet number %u isn't currently being displayed.", fnumber);
+    return FALSE;   /* we failed to go to that packet */
   }
 
+#ifdef NEW_PACKET_LIST
+  row = new_packet_list_find_row_from_data(fdata, TRUE);
+#else
   /* We found that packet, and it's currently being displayed.
      Find what row it's in. */
   row = packet_list_find_row_from_data(fdata);
@@ -3237,17 +3895,22 @@ cf_goto_frame(capture_file *cf, guint fnumber)
 
   /* Select that row, make it the focus row, and make it visible. */
   packet_list_set_selected_row(row);
-  return TRUE; /* we got to that packet */
+#endif /* NEW_PACKET_LIST */
+  return TRUE;  /* we got to that packet */
 }
 
 gboolean
-cf_goto_top_frame(capture_file *cf)
+cf_goto_top_frame(capture_file *cf _U_)
 {
+#ifdef NEW_PACKET_LIST
+  /* Find and select */
+  new_packet_list_select_first_row();
+#else
   frame_data *fdata;
   int row;
   frame_data *lowest_fdata = NULL;
 
-  for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
+  for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
     if (fdata->flags.passed_dfilter) {
         lowest_fdata = fdata;
         break;
@@ -3265,17 +3928,22 @@ cf_goto_top_frame(capture_file *cf)
 
   /* Select that row, make it the focus row, and make it visible. */
   packet_list_set_selected_row(row);
-  return TRUE; /* we got to that packet */
+#endif /* NEW_PACKET_LIST */
+  return TRUE;  /* we got to that packet */
 }
 
 gboolean
-cf_goto_bottom_frame(capture_file *cf)
+cf_goto_bottom_frame(capture_file *cf _U_) /* cf is unused w/ NEW_PACKET_LIST */
 {
+#ifdef NEW_PACKET_LIST
+  /* Find and select */
+  new_packet_list_select_last_row();
+#else
   frame_data *fdata;
   int row;
   frame_data *highest_fdata = NULL;
 
-  for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
+  for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
     if (fdata->flags.passed_dfilter) {
         highest_fdata = fdata;
     }
@@ -3292,7 +3960,8 @@ cf_goto_bottom_frame(capture_file *cf)
 
   /* Select that row, make it the focus row, and make it visible. */
   packet_list_set_selected_row(row);
-  return TRUE; /* we got to that packet */
+#endif /* NEW_PACKET_LIST */
+  return TRUE;  /* we got to that packet */
 }
 
 /*
@@ -3326,7 +3995,11 @@ cf_select_packet(capture_file *cf, int row)
   gchar *err_info;
 
   /* Get the frame data struct pointer for this frame */
+#ifdef NEW_PACKET_LIST
+  fdata = new_packet_list_get_row_data(row);
+#else
   fdata = (frame_data *)packet_list_get_row_data(row);
+#endif
 
   if (fdata == NULL) {
     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
@@ -3366,9 +4039,9 @@ cf_select_packet(capture_file *cf, int row)
 
   /* Get the data in that frame. */
   if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
-                      cf->pd, fdata->cap_len, &err, &err_info)) {
+               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);
+          cf_read_error_message(err, err_info), cf->filename);
     return;
   }
 
@@ -3377,13 +4050,13 @@ cf_select_packet(capture_file *cf, int row)
   cf->current_row = row;
 
   /* Create the logical protocol tree. */
-  if (cf->edt != NULL) {
+  if (cf->edt != NULL)
     epan_dissect_free(cf->edt);
-    cf->edt = NULL;
-  }
+
   /* We don't need the columns here. */
   cf->edt = epan_dissect_new(TRUE, TRUE);
 
+  tap_build_interesting(cf->edt);
   epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
           NULL);
 
@@ -3536,30 +4209,30 @@ cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_f
     if (cf->is_tempfile) {
       /* The file being saved is a temporary file from a live
          capture, so it doesn't need to stay around under that name;
-        first, try renaming the capture buffer file to the new name. */
+     first, try renaming the capture buffer file to the new name. */
 #ifndef _WIN32
       if (ws_rename(cf->filename, fname) == 0) {
-       /* That succeeded - there's no need to copy the source file. */
-       from_filename = NULL;
-       do_copy = FALSE;
+        /* That succeeded - there's no need to copy the source file. */
+        from_filename = NULL;
+    do_copy = FALSE;
       } else {
-       if (errno == EXDEV) {
-         /* They're on different file systems, so we have to copy the
-            file. */
-         do_copy = TRUE;
+        if (errno == EXDEV) {
+      /* They're on different file systems, so we have to copy the
+         file. */
+      do_copy = TRUE;
           from_filename = cf->filename;
-       } else {
-         /* The rename failed, but not because they're on different
-            file systems - put up an error message.  (Or should we
-            just punt and try to copy?  The only reason why I'd
-            expect the rename to fail and the copy to succeed would
-            be if we didn't have permission to remove the file from
-            the temporary directory, and that might be fixable - but
-            is it worth requiring the user to go off and fix it?) */
-         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                               file_rename_error_message(errno), fname);
-         goto fail;
-       }
+    } else {
+      /* The rename failed, but not because they're on different
+         file systems - put up an error message.  (Or should we
+         just punt and try to copy?  The only reason why I'd
+         expect the rename to fail and the copy to succeed would
+         be if we didn't have permission to remove the file from
+         the temporary directory, and that might be fixable - but
+         is it worth requiring the user to go off and fix it?) */
+      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                file_rename_error_message(errno), fname);
+      goto fail;
+    }
       }
 #else
       do_copy = TRUE;
@@ -3575,14 +4248,14 @@ cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_f
     if (do_copy) {
       /* Copy the file, if we haven't moved it. */
       if (!copy_file_binary_mode(from_filename, fname))
-       goto fail;
+    goto fail;
     }
   } else {
     /* Either we're filtering packets, or we're saving in a different
        format; we can't do that by copying or moving the capture file,
        we have to do it by writing the packets out in Wiretap. */
     pdh = wtap_dump_open(fname, save_format, cf->lnk_t, cf->snap,
-               compressed, &err);
+        compressed, &err);
     if (pdh == NULL) {
       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
       goto fail;
@@ -3649,17 +4322,17 @@ cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_f
 
       case CF_READ_OK:
       case CF_READ_ERROR:
-       /* Just because we got an error, that doesn't mean we were unable
-          to read any of the file; we handle what we could get from the
-          file. */
-       break;
+    /* Just because we got an error, that doesn't mean we were unable
+       to read any of the file; we handle what we could get from the
+       file. */
+    break;
 
       case CF_READ_ABORTED:
-       /* The user bailed out of re-reading the capture file; the
-          capture file has been closed - just return (without
-          changing any menu settings; "cf_close()" set them
-          correctly for the "no capture file open" state). */
-       break;
+    /* The user bailed out of re-reading the capture file; the
+       capture file has been closed - just return (without
+       changing any menu settings; "cf_close()" set them
+       correctly for the "no capture file open" state). */
+    break;
       }
       cf_callback_invoke(cf_cb_file_safe_reload_finished, NULL);
     }
@@ -3681,116 +4354,116 @@ cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
 
     case WTAP_ERR_NOT_REGULAR_FILE:
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
-                   filename);
+            "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
+            filename);
       break;
 
     case WTAP_ERR_RANDOM_OPEN_PIPE:
       /* Seen only when opening a capture file for reading. */
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.",
-                   filename);
+            "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.",
+            filename);
       break;
 
     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
       /* Seen only when opening a capture file for reading. */
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "The file \"%s\" isn't a capture file in a format Wireshark understands.",
-                   filename);
+            "The file \"%s\" isn't a capture file in a format Wireshark understands.",
+            filename);
       break;
 
     case WTAP_ERR_UNSUPPORTED:
       /* Seen only when opening a capture file for reading. */
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
-                   "(%s)",
-                   filename, err_info);
+            "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
+            "(%s)",
+            filename, err_info);
       g_free(err_info);
       break;
 
     case WTAP_ERR_CANT_WRITE_TO_PIPE:
       /* Seen only when opening a capture file for writing. */
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "The file \"%s\" is a pipe, and %s capture files can't be "
-                   "written to a pipe.",
-                   filename, wtap_file_type_string(file_type));
+            "The file \"%s\" is a pipe, and %s capture files can't be "
+            "written to a pipe.",
+            filename, wtap_file_type_string(file_type));
       break;
 
     case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
       /* Seen only when opening a capture file for writing. */
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "Wireshark doesn't support writing capture files in that format.");
+            "Wireshark doesn't support writing capture files in that format.");
       break;
 
     case WTAP_ERR_UNSUPPORTED_ENCAP:
       if (for_writing) {
-       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                     "Wireshark can't save this capture in that format.");
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+              "Wireshark can't save this capture in that format.");
       } else {
-       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                     "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
-                     "(%s)",
-                     filename, err_info);
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+              "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
+              "(%s)",
+              filename, err_info);
         g_free(err_info);
       }
       break;
 
     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
       if (for_writing) {
-       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                     "Wireshark can't save this capture in that format.");
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+              "Wireshark can't save this capture in that format.");
       } else {
-       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                     "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
-                     filename);
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+              "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
+              filename);
       }
       break;
 
     case WTAP_ERR_BAD_RECORD:
       /* Seen only when opening a capture file for reading. */
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "The file \"%s\" appears to be damaged or corrupt.\n"
-                   "(%s)",
-                   filename, err_info);
+            "The file \"%s\" appears to be damaged or corrupt.\n"
+            "(%s)",
+            filename, err_info);
       g_free(err_info);
       break;
 
     case WTAP_ERR_CANT_OPEN:
       if (for_writing) {
-       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                     "The file \"%s\" could not be created for some unknown reason.",
-                     filename);
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+              "The file \"%s\" could not be created for some unknown reason.",
+              filename);
       } else {
-       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                     "The file \"%s\" could not be opened for some unknown reason.",
-                     filename);
+    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+              "The file \"%s\" could not be opened for some unknown reason.",
+              filename);
       }
       break;
 
     case WTAP_ERR_SHORT_READ:
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "The file \"%s\" appears to have been cut short"
-                   " in the middle of a packet or other data.",
-                   filename);
+            "The file \"%s\" appears to have been cut short"
+            " in the middle of a packet or other data.",
+            filename);
       break;
 
     case WTAP_ERR_SHORT_WRITE:
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "A full header couldn't be written to the file \"%s\".",
-                   filename);
+            "A full header couldn't be written to the file \"%s\".",
+            filename);
       break;
 
     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "Gzip compression not supported by this file type.");
+            "Gzip compression not supported by this file type.");
       break;
 
     default:
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "The file \"%s\" could not be %s: %s.",
-                   filename,
-                   for_writing ? "created" : "opened",
-                   wtap_strerror(err));
+            "The file \"%s\" could not be %s: %s.",
+            filename,
+            for_writing ? "created" : "opened",
+            wtap_strerror(err));
       break;
     }
   } else {
@@ -3817,8 +4490,8 @@ file_rename_error_message(int err)
 
   default:
     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
-                   "The file \"%%s\" could not be moved: %s.",
-                               wtap_strerror(err));
+            "The file \"%%s\" could not be moved: %s.",
+                wtap_strerror(err));
     errmsg = errmsg_errno;
     break;
   }
@@ -3841,15 +4514,15 @@ cf_read_error_message(int err, gchar *err_info)
 
   case WTAP_ERR_BAD_RECORD:
     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
-            "An error occurred while reading from the file \"%%s\": %s.\n(%s)",
-            wtap_strerror(err), err_info);
+         "An error occurred while reading from the file \"%%s\": %s.\n(%s)",
+         wtap_strerror(err), err_info);
     g_free(err_info);
     break;
 
   default:
     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
-            "An error occurred while reading from the file \"%%s\": %s.",
-            wtap_strerror(err));
+         "An error occurred while reading from the file \"%%s\": %s.",
+         wtap_strerror(err));
     break;
   }
   return errmsg_errno;
@@ -3861,8 +4534,8 @@ cf_write_failure_alert_box(const char *filename, int err)
   if (err < 0) {
     /* Wiretap error. */
     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                 "An error occurred while writing to the file \"%s\": %s.",
-                 filename, wtap_strerror(err));
+          "An error occurred while writing to the file \"%s\": %s.",
+          filename, wtap_strerror(err));
   } else {
     /* OS error. */
     write_failure_alert_box(filename, err);
@@ -3882,20 +4555,20 @@ cf_close_failure_alert_box(const char *filename, int err)
 
     case WTAP_ERR_CANT_CLOSE:
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "The file \"%s\" couldn't be closed for some unknown reason.",
-                   filename);
+            "The file \"%s\" couldn't be closed for some unknown reason.",
+            filename);
       break;
 
     case WTAP_ERR_SHORT_WRITE:
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "Not all the packets could be written to the file \"%s\".",
+            "Not all the packets could be written to the file \"%s\".",
                     filename);
       break;
 
     default:
       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
-                   "An error occurred while closing the file \"%s\": %s.",
-                   filename, wtap_strerror(err));
+            "An error occurred while closing the file \"%s\": %s.",
+            filename, wtap_strerror(err));
       break;
     }
   } else {