cap_file_init(capture_file *cf)
{
/* Initialize the capture file struct */
- cf->plist_start = NULL;
- cf->plist_end = NULL;
- cf->wth = NULL;
- cf->filename = NULL;
- cf->source = NULL;
- cf->user_saved = FALSE;
- cf->is_tempfile = FALSE;
- cf->rfcode = NULL;
- cf->dfilter = NULL;
- cf->has_snap = FALSE;
- cf->snap = WTAP_MAX_PACKET_SIZE;
- cf->count = 0;
- cf->redissecting = FALSE;
+ cf->plist_start = NULL;
+ cf->plist_end = NULL;
+ cf->wth = NULL;
+ cf->filename = NULL;
+ cf->source = NULL;
+ cf->user_saved = FALSE;
+ cf->is_tempfile = FALSE;
+ cf->rfcode = NULL;
+ cf->dfilter = NULL;
+ cf->has_snap = FALSE;
+ cf->snap = WTAP_MAX_PACKET_SIZE;
+ cf->count = 0;
+ cf->last_found_num = 0;
+ cf->last_found_fd = NULL;
+ cf->redissecting = FALSE;
}
void
cf->plist_end = fdata;
}
+/*
+ * Find the frame_data for the specified frame number.
+ * Do some caching to make this work reasonably fast for
+ * forward and backward sequential passes through the packets.
+ */
+frame_data *
+cap_file_find_fdata(capture_file *cf, guint32 num)
+{
+ frame_data *fdata;
+
+ if (num == 0) {
+ /* There is no frame number 0 */
+ return NULL;
+ }
+
+ /*
+ * Did we remember a frame number from a sequential pass through
+ * the frames?
+ */
+ if (cf->last_found_num != 0) {
+ /*
+ * Yes. Is this that frame?
+ */
+ if (num == cf->last_found_num) {
+ /* Yes - return it. */
+ return cf->last_found_fd;
+ }
+
+ /*
+ * No. Is it the frame just after that frame?
+ */
+ if (num == cf->last_found_num + 1) {
+ /*
+ * Yes - if there is such a frame, remember it and return it.
+ */
+ fdata = cf->last_found_fd->next;
+ if (fdata != NULL) {
+ cf->last_found_num = num;
+ cf->last_found_fd = fdata;
+ }
+ return fdata; /* could be null, if there is no such frame */
+ }
+
+ /*
+ * No. Is it the frame just before that frame?
+ */
+ if (num == cf->last_found_num - 1) {
+ /*
+ * Yes - if there is such a frame, remember it and return it.
+ */
+ fdata = cf->last_found_fd->prev;
+ if (fdata != NULL) {
+ cf->last_found_num = num;
+ cf->last_found_fd = fdata;
+ }
+ return fdata; /* could be null, if there is no such frame */
+ }
+ }
+
+ for (fdata = cf->plist_start; fdata != NULL && fdata->num < num;
+ fdata = fdata->next)
+ ;
+ if (fdata != NULL) {
+ cf->last_found_num = num;
+ cf->last_found_fd = fdata;
+ }
+ return fdata;
+}
gint64 f_datalen; /* Size of capture file data (uncompressed) */
guint16 cd_t; /* File type of capture file */
int lnk_t; /* Link-layer type with which to save capture */
- int count; /* Total number of frames */
- int displayed_count; /* Number of displayed frames */
- int marked_count; /* Number of marked frames */
- int ignored_count; /* Number of ignored frames */
- int ref_time_count; /* Number of time referenced frames */
+ guint32 count; /* Total number of frames */
+ guint32 displayed_count; /* Number of displayed frames */
+ guint32 marked_count; /* Number of marked frames */
+ guint32 ignored_count; /* Number of ignored frames */
+ guint32 ref_time_count; /* Number of time referenced frames */
gboolean drops_known; /* TRUE if we know how many packets were dropped */
guint32 drops; /* Dropped packets */
nstime_t elapsed_time; /* Elapsed time */
frame_data *plist_end; /* Last packet in list */
frame_data *first_displayed; /* First frame displayed */
frame_data *last_displayed; /* Last frame displayed */
+ /* The next two are used to speed up frame number -> frame data searches */
+ guint32 last_found_num; /* Frame number we last found */
+ frame_data *last_found_fd; /* The corresponding frame_data */
column_info cinfo; /* Column formatting information */
frame_data *current_frame; /* Frame data for current frame */
gint current_row; /* Row number for current frame */
void cap_file_add_fdata(capture_file *cf, frame_data *fdata);
+/*
+ * Find the frame_data for the specified frame number.
+ * Do some caching to make this work reasonably fast for
+ * forward and backward sequential passes through the packets.
+ */
+extern frame_data *cap_file_find_fdata(capture_file *cf, guint32 num);
+
#endif /* cfile.h */
rescan_packets(capture_file *cf, const char *action, const char *action_item,
gboolean refilter, gboolean redissect)
{
- /* Rescan packets new packet list */
+ /* Rescan packets new packet list */
+ guint32 framenum;
frame_data *fdata;
progdlg_t *progbar = NULL;
gboolean stop_flag;
selected_frame_seen = FALSE;
- for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
+ for (framenum = 1; framenum <= cf->count; framenum++) {
+ fdata = cap_file_find_fdata(cf, framenum);
+
/* 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
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) {
+ for (; framenum <= cf->count; framenum++) {
+ fdata = cap_file_find_fdata(cf, framenum);
fdata->flags.visited = 0;
frame_data_cleanup(fdata);
}
static void
ref_time_packets(capture_file *cf)
{
+ guint32 framenum;
frame_data *fdata;
nstime_set_unset(&first_ts);
nstime_set_unset(&prev_dis_ts);
cum_bytes = 0;
- for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
+ for (framenum = 1; framenum <= cf->count; framenum++) {
+ fdata = cap_file_find_fdata(cf, framenum);
+
/* just add some value here until we know if it is being displayed or not */
fdata->cum_bytes = cum_bytes + fdata->pkt_len;
union wtap_pseudo_header *, const guint8 *, void *),
void *callback_args)
{
+ guint32 framenum;
frame_data *fdata;
union wtap_pseudo_header pseudo_header;
guint8 pd[WTAP_MAX_PACKET_SIZE+1];
packet_range_process_init(range);
- /* Iterate through the list of packets, printing the packets that
+ /* Iterate through all the packets, printing the packets that
were selected by the current display filter. */
- for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
+ for (framenum = 1; framenum <= cf->count; framenum++) {
+ fdata = cap_file_find_fdata(cf, framenum);
+
/* 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 *criterion, search_direction dir)
{
frame_data *start_fd;
+ guint32 framenum;
frame_data *fdata;
frame_data *new_fd = NULL;
progdlg_t *progbar = NULL;
picked, calling a routine to run the filter on the packet, see if
it matches, and stop if so. */
count = 0;
- fdata = start_fd;
+ framenum = start_fd->num;
/* Update the progress bar when it gets to this value. */
progbar_nextstep = 0;
/* Go past the current frame. */
if (dir == SD_BACKWARD) {
/* Go on to the previous frame. */
- fdata = fdata->prev;
- if (fdata == NULL) {
+ if (framenum == 1) {
/*
* XXX - other apps have a bit more of a detailed message
* for this, and instead of offering "OK" and "Cancel",
if (prefs.gui_find_wrap)
{
statusbar_push_temporary_msg("Search reached the beginning. Continuing at end.");
- fdata = cf->plist_end; /* wrap around */
+ framenum = cf->count; /* wrap around */
}
else
{
statusbar_push_temporary_msg("Search reached the beginning.");
- fdata = start_fd; /* stay on previous packet */
+ framenum = start_fd->num; /* stay on previous packet */
}
- }
+ } else
+ framenum--;
} else {
/* Go on to the next frame. */
- fdata = fdata->next;
- if (fdata == NULL) {
+ if (framenum == cf->count) {
if (prefs.gui_find_wrap)
{
statusbar_push_temporary_msg("Search reached the end. Continuing at beginning.");
- fdata = cf->plist_start; /* wrap around */
+ framenum = 1; /* wrap around */
}
else
{
statusbar_push_temporary_msg("Search reached the end.");
- fdata = start_fd; /* stay on previous packet */
+ framenum = start_fd->num; /* stay on previous packet */
}
- }
+ } else
+ framenum++;
}
+ fdata = cap_file_find_fdata(cf, framenum);
count++;
{
frame_data *fdata;
- for (fdata = cf->plist_start; fdata != NULL && fdata->num < fnumber; fdata = fdata->next)
- ;
+ fdata = cap_file_find_fdata(cf, fnumber);
if (fdata == NULL) {
/* we didn't find a packet with that packet number */
mark_all_displayed_frames(gboolean set)
{
/* XXX: we might need a progressbar here */
+ guint32 framenum;
frame_data *fdata;
- for (fdata = cfile.plist_start; fdata != NULL; fdata = fdata->next) {
+ for (framenum = 1; framenum <= cfile.count; framenum++) {
+ fdata = cap_file_find_fdata(&cfile, framenum);
if( fdata->flags.passed_dfilter )
set_frame_mark(set, fdata);
}
toggle_mark_all_displayed_frames()
{
/* XXX: we might need a progressbar here */
+ guint32 framenum;
frame_data *fdata;
- for (fdata = cfile.plist_start; fdata != NULL; fdata = fdata->next) {
+ for (framenum = 1; framenum <= cfile.count; framenum++) {
+ fdata = cap_file_find_fdata(&cfile, framenum);
if( fdata->flags.passed_dfilter )
set_frame_mark(!fdata->flags.marked, fdata);
}
static void
ignore_all_displayed_frames(gboolean set)
{
+ guint32 framenum;
frame_data *fdata;
/* XXX: we might need a progressbar here */
- for (fdata = cfile.plist_start; fdata != NULL; fdata = fdata->next) {
+ for (framenum = 1; framenum <= cfile.count; framenum++) {
+ fdata = cap_file_find_fdata(&cfile, framenum);
if( fdata->flags.passed_dfilter )
- set_frame_ignore(set, fdata);
+ set_frame_ignore(set, fdata);
}
redissect_packets();
}
}
static void
-unignore_all_frames()
+unignore_all_frames(void)
{
+ guint32 framenum;
frame_data *fdata;
/* XXX: we might need a progressbar here */
- for (fdata = cfile.plist_start; fdata != NULL && cfile.ignored_count > 0; fdata = fdata->next) {
+ for (framenum = 1; framenum <= cfile.count; framenum++) {
+ fdata = cap_file_find_fdata(&cfile, framenum);
set_frame_ignore(FALSE, fdata);
}
redissect_packets();
untime_reference_all_frames()
{
/* XXX: we might need a progressbar here */
+ guint32 framenum;
frame_data *fdata;
- for (fdata = cfile.plist_start; fdata != NULL && cfile.ref_time_count > 0; fdata = fdata->next) {
+ for (framenum = 1; framenum <= cfile.count && cfile.ref_time_count > 0; framenum++) {
+ fdata = cap_file_find_fdata(&cfile, framenum);
if (fdata->flags.ref_time == 1) {
set_frame_reftime(FALSE, fdata, cfile.current_row);
}
{
frame_data *first_frame, *cur_frame;
- int i;
+ guint32 i;
frame_data *cur_glist;
st->start_time = 0;