#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);
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 don't 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 :-) */
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)
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();
/* 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;
cf->marked_count = 0;
+ cf->ignored_count = 0;
cf->drops_known = FALSE;
cf->drops = 0;
cf->snap = wtap_snapshot_length(cf->wth);
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) {
/* ...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;
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;
/* 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);
}
/* an out of memory exception occured, wait for a user button press to exit */
-void outofmemory_cb(gpointer dialog _U_, gint btn _U_, gpointer data _U_)
+static 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)
+cf_read(capture_file *cf, gboolean from_save)
{
int err;
gchar *err_info;
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];
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));
/* 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();
- cf_callback_invoke(cf_cb_file_read_start, cf);
-
name_ptr = get_basename(cf->filename);
+ if (from_save == FALSE)
+ cf_callback_invoke(cf_cb_file_read_started, cf);
+ else
+ cf_callback_invoke(cf_cb_file_save_started, (gpointer)name_ptr);
+
/* Find the size of the file. */
size = wtap_file_size(cf->wth, NULL);
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) {
- progbar = delayed_create_progress_dlg("Loading", name_ptr,
- TRUE, &stop_flag, &start_time, progbar_val);
+ * 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);
+ if (from_save == FALSE)
+ progbar = delayed_create_progress_dlg("Loading", name_ptr,
+ TRUE, &stop_flag, &start_time, progbar_val);
+ else
+ progbar = delayed_create_progress_dlg("Saving", name_ptr,
+ TRUE, &stop_flag, &start_time, progbar_val);
}
/* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
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;
* 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
cf->current_frame = cf->first_displayed;
cf->current_row = 0;
+#ifdef NEW_PACKET_LIST
+ new_packet_list_thaw();
+#else
packet_list_thaw();
-
- cf_callback_invoke(cf_cb_file_read_finished, cf);
+#endif
+ if (from_save == FALSE)
+ cf_callback_invoke(cf_cb_file_read_finished, cf);
+ else
+ cf_callback_invoke(cf_cb_file_save_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;
}
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;
}
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();
*err = 0;
+#ifdef NEW_PACKET_LIST
+ new_packet_list_check_end();
+ /* Don't freeze/thaw the list when doing live capture */
+ /*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);*/
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, filtering_tap_listeners, tap_flags,
data_offset) != -1) {
+ visible = TRUE;
newly_displayed_packets++;
+ }else{
+ visible = FALSE;
}
}
CATCH(OutOfMemoryError) {
/* XXX - how to avoid a busy wait? */
/* Sleep(100); */
};
+#ifdef NEW_PACKET_LIST
+ /* Don't freeze/thaw the list when doing live capture */
+ /*new_packet_list_thaw();*/
+#else
packet_list_thaw();
+#endif
return CF_READ_ABORTED;
}
ENDTRY;
}
/*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
+ /* Don't freeze/thaw the list when doing live capture */
+ /*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
} 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
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();
return CF_READ_ERROR;
}
+#ifdef NEW_PACKET_LIST
+ new_packet_list_check_end();
+ /* Don't freeze/thaw the list when doing live capture */
+ /*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, filtering_tap_listeners, tap_flags, data_offset);
dfilter_free(dfcode);
}
+#ifdef NEW_PACKET_LIST
+ /* Don't freeze/thaw the list when doing live capture */
+ /*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
}
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;
cf->rfcode = rfcode;
}
+#ifdef NEW_PACKET_LIST
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)
+ 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;
- /* just add some value here until we know if it is being displayed or not */
- fdata->cum_bytes = cum_bytes + fdata->pkt_len;
+ cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
- /* 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;
+ 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);
}
- /* 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;
+ 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);
}
- /* Get the time elapsed between the first packet and this packet. */
- nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
+ if(fdata->flags.passed_dfilter || fdata->flags.ref_time)
+ {
+ frame_data_set_after_dissect(fdata, &cum_bytes, &prev_dis_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;
+ /* 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++;
}
- /* Get the time elapsed between the previous displayed packet and
- this packet. */
- nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
+ 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;
+
+ 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 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 with filters;
+ we have tap listeners with filters;
- we have tap listeners that require a protocol tree;
+ we have tap listeners that require a protocol tree;
- we have custom columns;
+ 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() ||
- filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE) ||
- 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.
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) ){
- /* 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 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;
- }
+ if( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) )
+ {
+ frame_data_set_after_dissect(fdata, &cum_bytes, &prev_dis_ts);
- 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.
/* 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);
- }
-
- /* Set the time of the previous displayed frame to the time of this
- frame. */
- prev_dis_ts = fdata->abs_ts;
+ 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);
+ }
+ if (fdata->flags.ignored) {
+ packet_list_set_colors(row, &prefs.gui_ignored_fg, &prefs.gui_ignored_bg);
+ }
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 */
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;
+
+ cf->count++;
- /* Allocate the next list entry, and add it to the list. */
+ /* 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,
filtering_tap_listeners, tap_flags,
- pseudo_header, buf, TRUE);
+ 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
...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;
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;
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);
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);
*/
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);
}
}
/* 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);
+ dfilter_error_msg);
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"%s%s%s\n"
"\n"
return CF_ERROR;
}
- /* Was it empty? */
- if (dfcode == NULL) {
- /* Yes - free the filter text, and set it to null. */
- g_free(dftext);
- dftext = NULL;
+ /* 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;
+
+ /* 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;
}
- }
- /* We have a valid filter. Replace the current filter. */
- g_free(cf->dfilter);
- cf->dfilter = dftext;
+ /* 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);
- /* 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 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;
}
- /* Cleanup and release all dfilter resources */
- if (dfcode != NULL){
- dfilter_free(dfcode);
+ /* We are done redissecting the packet list. */
+ cf->redissecting = FALSE;
+
+ if (redissect) {
+ /* Clear out what remains of the visited flags and per-frame data
+ pointers.
+
+ XXX - that may cause various forms of bogosity when dissecting
+ these frames, as they won't have been seen by this sequential
+ pass, but the only alternative I see is to keep scanning them
+ even though the user requested that the scan stop, and that
+ would leave the user stuck with an Wireshark grinding on
+ until it finishes. Should we just stick them with that? */
+ for (; fdata != NULL; fdata = fdata->next) {
+ fdata->flags.visited = 0;
+ 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. */
+ /* Set to invalid to force update of packet list and packet details */
+ cf->current_row = -1;
+ 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;
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"
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,
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;
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;
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;
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
/* 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;
}
/* 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
}
row = add_packet_to_packet_list(fdata, cf, dfcode, filtering_tap_listeners,
tap_flags, &cf->pseudo_header, cf->pd,
- refilter);
+ 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 -
/* 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.
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);
}
}
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;
}
}
}
/* 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,
/* 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
void *argsp)
{
retap_callback_args_t *args = argsp;
- epan_dissect_t *edt;
+ epan_dissect_t edt;
- edt = epan_dissect_new(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_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;
}
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))
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;
/* 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;
}
/* 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). */
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). */
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) {
return TRUE;
fail:
- epan_dissect_free(edt);
+ epan_dissect_cleanup(&edt);
return FALSE;
}
/* 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;
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);
}
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)) {
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);
}
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)) {
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);
}
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;
/* 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:
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];
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"
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
/* 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;
}
(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) {
/* 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);
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. */
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;
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);
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)
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;
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;
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;
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;
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;
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;
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;
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;
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;
}
if (prefs.gui_find_wrap)
{
- simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
- "%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 */
+ simple_status("Search reached the beginning. Continuing at end.");
+ fdata = cf->plist_end; /* wrap around */
}
else
{
- simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
- "%sBeginning of capture exceeded!%s\n\n"
- "Try searching forwards.",
- simple_dialog_primary_start(), simple_dialog_primary_end());
+ simple_status("Search reached the beginning.");
fdata = start_fd; /* stay on previous packet */
}
}
if (fdata == NULL) {
if (prefs.gui_find_wrap)
{
- simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
- "%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 */
+ simple_status("Search reached the end. Continuing at beginning.");
+ fdata = cf->plist_start; /* wrap around */
}
else
{
- simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
- "%sEnd of capture exceeded!%s\n\n"
- "Try searching backwards.",
- simple_dialog_primary_start(), simple_dialog_primary_end());
+ simple_status("Search reached the end.");
fdata = start_fd; /* stay on previous packet */
}
}
/* 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;
}
}
}
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);
+#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
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
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 */
+ simple_status("There is no 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 */
+ simple_status("Packet number %u isn't 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);
/* 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;
/* 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;
}
/* 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 */
}
/*
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
/* 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;
}
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);
}
}
+/*
+ * Ignore a particular frame.
+ */
+void
+cf_ignore_frame(capture_file *cf, frame_data *frame)
+{
+ if (! frame->flags.ignored) {
+ frame->flags.ignored = TRUE;
+ if (cf->count > cf->ignored_count)
+ cf->ignored_count++;
+ }
+}
+
+/*
+ * Un-ignore a particular frame.
+ */
+void
+cf_unignore_frame(capture_file *cf, frame_data *frame)
+{
+ if (frame->flags.ignored) {
+ frame->flags.ignored = FALSE;
+ if (cf->ignored_count > 0)
+ cf->ignored_count--;
+ }
+}
+
typedef struct {
wtap_dumper *pdh;
const char *fname;
wtap_dumper *pdh;
save_callback_args_t callback_args;
- cf_callback_invoke(cf_cb_file_safe_started, (gpointer) fname);
+ cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
/* don't write over an existing file. */
/* this should've been already checked by our caller, just to be sure... */
packet_range_process_init(range);
-
if (packet_range_process_all(range) && save_format == cf->cd_t) {
/* We're not filtering packets, and we're saving it in the format
it's already in, so we can just move or copy the raw data. */
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;
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;
}
}
- cf_callback_invoke(cf_cb_file_safe_finished, NULL);
+ cf_callback_invoke(cf_cb_file_save_finished, NULL);
if (packet_range_process_all(range)) {
/* We saved the entire capture, not just some packets from it.
if ((cf_open(cf, fname, FALSE, &err)) == CF_OK) {
/* XXX - report errors if this fails?
What should we return if it fails or is aborted? */
- switch (cf_read(cf)) {
+
+ switch (cf_read(cf, TRUE)) {
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);
+ cf_callback_invoke(cf_cb_file_save_reload_finished, cf);
}
}
return CF_OK;
fail:
- cf_callback_invoke(cf_cb_file_safe_failed, NULL);
+ cf_callback_invoke(cf_cb_file_save_failed, NULL);
return CF_ERROR;
}
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 {
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;
}
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;
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);
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 {
is_tempfile = cf->is_tempfile;
cf->is_tempfile = FALSE;
if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
- switch (cf_read(cf)) {
+ switch (cf_read(cf, FALSE)) {
case CF_READ_OK:
case CF_READ_ERROR: