Bring frame_data_init() and add_packet_to_packet_list() more in sync by adding 'ref_t...
[metze/wireshark/wip.git] / file.c
1 /* file.c
2  * File I/O routines
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32
33 #include <time.h>
34
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <ctype.h>
39 #include <errno.h>
40 #include <signal.h>
41
42 #ifdef HAVE_FCNTL_H
43 #include <fcntl.h>
44 #endif
45
46 #include <epan/epan.h>
47 #include <epan/filesystem.h>
48
49 #include "color.h"
50 #include "color_filters.h"
51 #include "cfile.h"
52 #include <epan/column.h>
53 #include <epan/packet.h>
54 #include <epan/column-utils.h>
55 #include "packet-range.h"
56 #include "print.h"
57 #include "file.h"
58 #include "fileset.h"
59 #include "tempfile.h"
60 #include "merge.h"
61 #include "alert_box.h"
62 #include "simple_dialog.h"
63 #include "progress_dlg.h"
64 #include "ui_util.h"
65 #include <epan/prefs.h>
66 #include <epan/dfilter/dfilter.h>
67 #include <epan/epan_dissect.h>
68 #include <epan/tap.h>
69 #include <epan/dissectors/packet-data.h>
70 #include <epan/dissectors/packet-ber.h>
71 #include <epan/timestamp.h>
72 #include <epan/dfilter/dfilter-macro.h>
73 #include <wsutil/file_util.h>
74 #include <epan/strutil.h>
75
76 #ifdef HAVE_LIBPCAP
77 gboolean auto_scroll_live;
78 #endif
79
80 static guint32 cum_bytes;
81 static nstime_t first_ts;
82 static nstime_t prev_dis_ts;
83 static nstime_t prev_cap_ts;
84
85 static gulong computed_elapsed;
86
87 static void cf_reset_state(capture_file *cf);
88
89 static int read_packet(capture_file *cf, dfilter_t *dfcode,
90     gboolean filtering_tap_listeners, guint tap_flags, gint64 offset);
91
92 static void rescan_packets(capture_file *cf, const char *action, const char *action_item,
93     gboolean refilter, gboolean redissect);
94
95 static gboolean match_protocol_tree(capture_file *cf, frame_data *fdata,
96     void *criterion);
97 static void match_subtree_text(proto_node *node, gpointer data);
98 static gboolean match_summary_line(capture_file *cf, frame_data *fdata,
99     void *criterion);
100 static gboolean match_ascii_and_unicode(capture_file *cf, frame_data *fdata,
101     void *criterion);
102 static gboolean match_ascii(capture_file *cf, frame_data *fdata,
103     void *criterion);
104 static gboolean match_unicode(capture_file *cf, frame_data *fdata,
105     void *criterion);
106 static gboolean match_binary(capture_file *cf, frame_data *fdata,
107     void *criterion);
108 static gboolean match_dfilter(capture_file *cf, frame_data *fdata,
109     void *criterion);
110 static gboolean find_packet(capture_file *cf,
111     gboolean (*match_function)(capture_file *, frame_data *, void *),
112     void *criterion);
113
114 static void cf_open_failure_alert_box(const char *filename, int err,
115                       gchar *err_info, gboolean for_writing,
116                       int file_type);
117 static const char *file_rename_error_message(int err);
118 static void cf_write_failure_alert_box(const char *filename, int err);
119 static void cf_close_failure_alert_box(const char *filename, int err);
120 #ifdef NEW_PACKET_LIST
121 static void ref_time_packets(capture_file *cf);
122 #endif
123 /* Update the progress bar this many times when reading a file. */
124 #define N_PROGBAR_UPDATES   100
125 /* We read around 200k/100ms domt update the progress bar more often than that */
126 #define MIN_QUANTUM         200000
127 #define MIN_NUMBER_OF_PACKET 1500
128
129 /* Number of "frame_data" structures per memory chunk.
130    XXX - is this the right number? */
131 #define FRAME_DATA_CHUNK_SIZE   1024
132
133
134 /* this callback mechanism should possibly be replaced by the g_signal_...() stuff (if I only would know how :-) */
135 typedef struct {
136     cf_callback_t cb_fct;
137     gpointer user_data;
138 } cf_callback_data_t;
139
140 static GList *cf_callbacks = NULL;
141
142 static void
143 cf_callback_invoke(int event, gpointer data)
144 {
145     cf_callback_data_t *cb;
146     GList *cb_item = cf_callbacks;
147
148     /* there should be at least one interested */
149     g_assert(cb_item != NULL);
150
151     while(cb_item != NULL) {
152         cb = cb_item->data;
153         cb->cb_fct(event, data, cb->user_data);
154         cb_item = g_list_next(cb_item);
155     }
156 }
157
158
159 void
160 cf_callback_add(cf_callback_t func, gpointer user_data)
161 {
162     cf_callback_data_t *cb;
163
164     cb = g_malloc(sizeof(cf_callback_data_t));
165     cb->cb_fct = func;
166     cb->user_data = user_data;
167
168     cf_callbacks = g_list_append(cf_callbacks, cb);
169 }
170
171 void
172 cf_callback_remove(cf_callback_t func)
173 {
174     cf_callback_data_t *cb;
175     GList *cb_item = cf_callbacks;
176
177     while(cb_item != NULL) {
178         cb = cb_item->data;
179         if(cb->cb_fct == func) {
180             cf_callbacks = g_list_remove(cf_callbacks, cb);
181             g_free(cb);
182             return;
183         }
184         cb_item = g_list_next(cb_item);
185     }
186
187     g_assert_not_reached();
188 }
189
190 void
191 cf_timestamp_auto_precision(capture_file *cf)
192 {
193 #ifdef NEW_PACKET_LIST
194     int i;
195 #endif
196     int prec = timestamp_get_precision();
197
198
199     /* don't try to get the file's precision if none is opened */
200     if(cf->state == FILE_CLOSED) {
201         return;
202     }
203
204     /* if we are in auto mode, set precision of current file */
205     if(prec == TS_PREC_AUTO ||
206       prec == TS_PREC_AUTO_SEC ||
207       prec == TS_PREC_AUTO_DSEC ||
208       prec == TS_PREC_AUTO_CSEC ||
209       prec == TS_PREC_AUTO_MSEC ||
210       prec == TS_PREC_AUTO_USEC ||
211       prec == TS_PREC_AUTO_NSEC)
212     {
213         switch(wtap_file_tsprecision(cf->wth)) {
214         case(WTAP_FILE_TSPREC_SEC):
215             timestamp_set_precision(TS_PREC_AUTO_SEC);
216             break;
217         case(WTAP_FILE_TSPREC_DSEC):
218             timestamp_set_precision(TS_PREC_AUTO_DSEC);
219             break;
220         case(WTAP_FILE_TSPREC_CSEC):
221             timestamp_set_precision(TS_PREC_AUTO_CSEC);
222             break;
223         case(WTAP_FILE_TSPREC_MSEC):
224             timestamp_set_precision(TS_PREC_AUTO_MSEC);
225             break;
226         case(WTAP_FILE_TSPREC_USEC):
227             timestamp_set_precision(TS_PREC_AUTO_USEC);
228             break;
229         case(WTAP_FILE_TSPREC_NSEC):
230             timestamp_set_precision(TS_PREC_AUTO_NSEC);
231             break;
232         default:
233             g_assert_not_reached();
234         }
235     }
236 #ifdef NEW_PACKET_LIST
237   /* Set the column widths of those columns that show the time in
238      "command-line-specified" format. */
239   for (i = 0; i < cf->cinfo.num_cols; i++) {
240     if (col_has_time_fmt(&cf->cinfo, i)) {
241       new_packet_list_resize_column(i);
242     }
243   }
244 #endif
245 }
246
247 gulong
248 cf_get_computed_elapsed(void)
249 {
250     return computed_elapsed;
251 }
252
253 static void reset_elapsed(void)
254 {
255     computed_elapsed = 0;
256 }
257
258 static void compute_elapsed(GTimeVal *start_time)
259 {
260     gdouble    delta_time;
261     GTimeVal   time_now;
262
263     g_get_current_time(&time_now);
264
265     delta_time = (time_now.tv_sec - start_time->tv_sec) * 1e6 +
266     time_now.tv_usec - start_time->tv_usec;
267
268     computed_elapsed = (gulong) (delta_time / 1000); /* ms*/
269 }
270
271 cf_status_t
272 cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
273 {
274   wtap       *wth;
275   gchar       *err_info;
276
277   wth = wtap_open_offline(fname, err, &err_info, TRUE);
278   if (wth == NULL)
279     goto fail;
280
281   /* The open succeeded.  Close whatever capture file we had open,
282      and fill in the information for this file. */
283   cf_reset_state(cf);
284
285   /* Cleanup all data structures used for dissection. */
286   cleanup_dissection();
287   /* Initialize all data structures used for dissection. */
288   init_dissection();
289
290   /* We're about to start reading the file. */
291   cf->state = FILE_READ_IN_PROGRESS;
292
293   cf->wth = wth;
294   cf->f_datalen = 0;
295
296   /* Set the file name because we need it to set the follow stream filter.
297      XXX - is that still true?  We need it for other reasons, though,
298      in any case. */
299   cf->filename = g_strdup(fname);
300
301   /* Indicate whether it's a permanent or temporary file. */
302   cf->is_tempfile = is_tempfile;
303
304   /* If it's a temporary capture buffer file, mark it as not saved. */
305   cf->user_saved = !is_tempfile;
306
307   reset_elapsed();
308
309   cf->cd_t        = wtap_file_type(cf->wth);
310   cf->count     = 0;
311   cf->displayed_count = 0;
312   cf->marked_count = 0;
313   cf->drops_known = FALSE;
314   cf->drops     = 0;
315   cf->snap      = wtap_snapshot_length(cf->wth);
316   if (cf->snap == 0) {
317     /* Snapshot length not known. */
318     cf->has_snap = FALSE;
319     cf->snap = WTAP_MAX_PACKET_SIZE;
320   } else
321     cf->has_snap = TRUE;
322
323   nstime_set_zero(&cf->elapsed_time);
324   nstime_set_unset(&first_ts);
325   nstime_set_unset(&prev_dis_ts);
326   nstime_set_unset(&prev_cap_ts);
327   cum_bytes = 0;
328
329 #if GLIB_CHECK_VERSION(2,10,0)
330 #else
331   /* memory chunks have been deprecated in favor of the slice allocator,
332    * which has been added in 2.10
333    */
334   cf->plist_chunk = g_mem_chunk_new("frame_data_chunk",
335     sizeof(frame_data),
336     FRAME_DATA_CHUNK_SIZE * sizeof(frame_data),
337     G_ALLOC_AND_FREE);
338   g_assert(cf->plist_chunk);
339 #endif
340
341 #ifdef NEW_PACKET_LIST
342   /* Adjust timestamp precision if auto is selected, col width will be adjusted */
343   cf_timestamp_auto_precision(cf);
344   /* XXX needed ? */
345   new_packet_list_queue_draw();
346 #else
347   /* change the time formats now, as we might have a new precision */
348   cf_change_time_formats(cf);
349 #endif
350   fileset_file_opened(fname);
351
352   if(cf->cd_t == WTAP_FILE_BER) {
353     /* tell the BER dissector the file name */
354     ber_set_filename(cf->filename);
355   }
356
357   return CF_OK;
358
359 fail:
360   cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
361   return CF_ERROR;
362 }
363
364
365 /*
366  * Reset the state for the currently closed file, but don't do the
367  * UI callbacks; this is for use in "cf_open()", where we don't
368  * want the UI to go from "file open" to "file closed" back to
369  * "file open", we want it to go from "old file open" to "new file
370  * open and being read".
371  */
372 static void
373 cf_reset_state(capture_file *cf)
374 {
375   /* Die if we're in the middle of reading a file. */
376   g_assert(cf->state != FILE_READ_IN_PROGRESS);
377
378   if (cf->wth) {
379     wtap_close(cf->wth);
380     cf->wth = NULL;
381   }
382   /* We have no file open... */
383   if (cf->filename != NULL) {
384     /* If it's a temporary file, remove it. */
385     if (cf->is_tempfile)
386       ws_unlink(cf->filename);
387     g_free(cf->filename);
388     cf->filename = NULL;
389   }
390   /* ...which means we have nothing to save. */
391   cf->user_saved = FALSE;
392
393 #if GLIB_CHECK_VERSION(2,10,0)
394   if (cf->plist_start != NULL)
395     g_slice_free_chain(frame_data, cf->plist_start, next);
396 #else
397   /* memory chunks have been deprecated in favor of the slice allocator,
398    * which has been added in 2.10
399    */
400   if (cf->plist_chunk != NULL) {
401     g_mem_chunk_destroy(cf->plist_chunk);
402     cf->plist_chunk = NULL;
403   }
404 #endif
405   if (cf->rfcode != NULL) {
406     dfilter_free(cf->rfcode);
407     cf->rfcode = NULL;
408   }
409   cf->plist_start = NULL;
410   cf->plist_end = NULL;
411   cf_unselect_packet(cf);   /* nothing to select */
412   cf->first_displayed = NULL;
413   cf->last_displayed = NULL;
414
415   /* No frame selected, no field in that frame selected. */
416   cf->current_frame = NULL;
417   cf->current_row = 0;
418   cf->finfo_selected = NULL;
419
420   /* Clear the packet list. */
421 #ifdef NEW_PACKET_LIST
422   new_packet_list_freeze();
423   new_packet_list_clear();
424   new_packet_list_thaw();
425 #else
426   packet_list_freeze();
427   packet_list_clear();
428   packet_list_thaw();
429 #endif
430
431   cf->f_datalen = 0;
432   cf->count = 0;
433   nstime_set_zero(&cf->elapsed_time);
434
435   reset_tap_listeners();
436
437   /* We have no file open. */
438   cf->state = FILE_CLOSED;
439
440   fileset_file_closed();
441 }
442
443 /* Reset everything to a pristine state */
444 void
445 cf_close(capture_file *cf)
446 {
447   /* do GUI things even if file is already closed,
448    * e.g. to cleanup things if a capture couldn't be started */
449   cf_callback_invoke(cf_cb_file_closing, cf);
450
451   /* close things, if not already closed before */
452   if(cf->state != FILE_CLOSED) {
453     color_filters_cleanup();
454     cf_reset_state(cf);
455     cleanup_dissection();
456   }
457
458   cf_callback_invoke(cf_cb_file_closed, cf);
459 }
460
461 /* an out of memory exception occured, wait for a user button press to exit */
462 void outofmemory_cb(gpointer dialog _U_, gint btn _U_, gpointer data _U_)
463 {
464     main_window_exit();
465 }
466
467 static float calc_progbar_val(capture_file *cf, gint64 size, gint64 file_pos){
468
469     float   progbar_val;
470
471     progbar_val = (gfloat) file_pos / (gfloat) size;
472     if (progbar_val > 1.0) {
473     /* The file probably grew while we were reading it.
474        Update file size, and try again. */
475       size = wtap_file_size(cf->wth, NULL);
476       if (size >= 0)
477         progbar_val = (gfloat) file_pos / (gfloat) size;
478        /* If it's still > 1, either "wtap_file_size()" failed (in which
479           case there's not much we can do about it), or the file
480           *shrank* (in which case there's not much we can do about
481           it); just clip the progress value at 1.0. */
482       if (progbar_val > 1.0f)
483         progbar_val = 1.0f;
484     }
485     return progbar_val;
486 }
487
488 cf_read_status_t
489 cf_read(capture_file *cf)
490 {
491   int         err;
492   gchar       *err_info;
493   const gchar *name_ptr;
494   const char  *errmsg;
495   char         errmsg_errno[1024+1];
496   gint64       data_offset;
497   progdlg_t *volatile progbar = NULL;
498   gboolean     stop_flag;
499   volatile gint64 size;
500   volatile float progbar_val;
501   GTimeVal     start_time;
502   gchar        status_str[100];
503   volatile gint64 progbar_nextstep;
504   volatile gint64 progbar_quantum;
505   dfilter_t   *dfcode;
506   gboolean    filtering_tap_listeners;
507   guint       tap_flags;
508   volatile int count = 0;
509 #ifdef HAVE_LIBPCAP
510   volatile int displayed_once = 0;
511 #endif
512   gboolean compiled;
513
514   /* Compile the current display filter.
515    * We assume this will not fail since cf->dfilter is only set in
516    * cf_filter IFF the filter was valid.
517    */
518   compiled = dfilter_compile(cf->dfilter, &dfcode);
519   g_assert(!cf->dfilter || (compiled && dfcode));
520
521   /* Do we have any tap listeners with filters? */
522   filtering_tap_listeners = have_filtering_tap_listeners();
523
524   /* Get the union of the flags for all tap listeners. */
525   tap_flags = union_of_tap_listener_flags();
526
527   reset_tap_listeners();
528
529   cf_callback_invoke(cf_cb_file_read_start, cf);
530
531   name_ptr = get_basename(cf->filename);
532
533   /* Find the size of the file. */
534   size = wtap_file_size(cf->wth, NULL);
535
536   /* Update the progress bar when it gets to this value. */
537   progbar_nextstep = 0;
538   /* When we reach the value that triggers a progress bar update,
539      bump that value by this amount. */
540   if (size >= 0){
541     progbar_quantum = size/N_PROGBAR_UPDATES;
542     if (progbar_quantum < MIN_QUANTUM)
543         progbar_quantum = MIN_QUANTUM;
544   }else
545     progbar_quantum = 0;
546   /* Progress so far. */
547   progbar_val = 0.0f;
548
549 #ifdef NEW_PACKET_LIST
550   new_packet_list_freeze();
551 #else
552   packet_list_freeze();
553 #endif
554
555   stop_flag = FALSE;
556   g_get_current_time(&start_time);
557
558   while ((wtap_read(cf->wth, &err, &err_info, &data_offset))) {
559     if (size >= 0) {
560         count++;
561       /* Create the progress bar if necessary.
562        * Check wether it should be created or not every MIN_NUMBER_OF_PACKET
563        */
564       if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)){
565         progbar_val = calc_progbar_val( cf, size, data_offset);
566         progbar = delayed_create_progress_dlg("Loading", name_ptr,
567           TRUE, &stop_flag, &start_time, progbar_val);
568       }
569
570       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
571          when we update it, we have to run the GTK+ main loop to get it
572          to repaint what's pending, and doing so may involve an "ioctl()"
573          to see if there's any pending input from an X server, and doing
574          that for every packet can be costly, especially on a big file. */
575       if (data_offset >= progbar_nextstep) {
576           if (progbar != NULL) {
577               progbar_val = calc_progbar_val( cf, size, data_offset);
578               /* update the packet lists content on the first run or frequently on very large files */
579               /* (on smaller files the display update takes longer than reading the file) */
580 #ifdef HAVE_LIBPCAP
581               if (progbar_quantum > 500000 || displayed_once == 0) {
582                   if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->plist_end != NULL) {
583                       displayed_once = 1;
584 #ifdef NEW_PACKET_LIST
585                   new_packet_list_thaw();
586                   if (auto_scroll_live)
587                       new_packet_list_moveto_end();
588                   new_packet_list_freeze();
589 #else
590                   packet_list_thaw();
591                   if (auto_scroll_live)
592                       packet_list_moveto_end();
593                   packet_list_freeze();
594 #endif /* NEW_PACKET_LIST */
595                   }
596           }
597 #endif /* HAVE_LIBPCAP */
598             g_snprintf(status_str, sizeof(status_str),
599                        "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
600                        data_offset / 1024, size / 1024);
601             update_progress_dlg(progbar, progbar_val, status_str);
602           }
603          progbar_nextstep += progbar_quantum;
604       }
605     }
606
607     if (stop_flag) {
608       /* Well, the user decided to abort the read. He/She will be warned and
609          it might be enough for him/her to work with the already loaded
610          packets.
611          This is especially true for very large capture files, where you don't
612          want to wait loading the whole file (which may last minutes or even
613          hours even on fast machines) just to see that it was the wrong file. */
614       break;
615     }
616     TRY {
617         read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
618     }
619     CATCH(OutOfMemoryError) {
620         gpointer dialog;
621
622         dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
623               "%sOut Of Memory!%s\n"
624               "\n"
625               "Sorry, but Wireshark has to terminate now!\n"
626               "\n"
627               "Some infos / workarounds can be found at:\n"
628               "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
629               simple_dialog_primary_start(), simple_dialog_primary_end());
630         /* we have to terminate, as we cannot recover from the memory error */
631         simple_dialog_set_cb(dialog, outofmemory_cb, NULL);
632         while(1) {
633             main_window_update();
634             /* XXX - how to avoid a busy wait? */
635             /* Sleep(100); */
636         };
637         break;
638     }
639     ENDTRY;
640   }
641
642   /* Cleanup and release all dfilter resources */
643   if (dfcode != NULL){
644     dfilter_free(dfcode);
645   }
646
647   /* We're done reading the file; destroy the progress bar if it was created. */
648   if (progbar != NULL)
649     destroy_progress_dlg(progbar);
650
651   /* We're done reading sequentially through the file. */
652   cf->state = FILE_READ_DONE;
653
654   /* Close the sequential I/O side, to free up memory it requires. */
655   wtap_sequential_close(cf->wth);
656
657   /* Allow the protocol dissectors to free up memory that they
658    * don't need after the sequential run-through of the packets. */
659   postseq_cleanup_all_protocols();
660
661   /* compute the time it took to load the file */
662   compute_elapsed(&start_time);
663
664   /* Set the file encapsulation type now; we don't know what it is until
665      we've looked at all the packets, as we don't know until then whether
666      there's more than one type (and thus whether it's
667      WTAP_ENCAP_PER_PACKET). */
668   cf->lnk_t = wtap_file_encap(cf->wth);
669
670   cf->current_frame = cf->first_displayed;
671   cf->current_row = 0;
672
673 #ifdef NEW_PACKET_LIST
674   new_packet_list_thaw();
675 #else
676   packet_list_thaw();
677 #endif
678
679   cf_callback_invoke(cf_cb_file_read_finished, cf);
680
681   /* If we have any displayed packets to select, select the first of those
682      packets by making the first row the selected row. */
683   if (cf->first_displayed != NULL){
684 #ifdef NEW_PACKET_LIST
685     new_packet_list_select_first_row();
686 #else
687     packet_list_select_row(0);
688 #endif /* NEW_PACKET_LIST */
689   }
690
691   if(stop_flag) {
692     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
693           "%sFile loading was cancelled!%s\n"
694           "\n"
695           "The remaining packets in the file were discarded.\n"
696           "\n"
697           "As a lot of packets from the original file will be missing,\n"
698           "remember to be careful when saving the current content to a file.\n",
699           simple_dialog_primary_start(), simple_dialog_primary_end());
700     return CF_READ_ERROR;
701   }
702
703   if (err != 0) {
704     /* Put up a message box noting that the read failed somewhere along
705        the line.  Don't throw out the stuff we managed to read, though,
706        if any. */
707     switch (err) {
708
709     case WTAP_ERR_UNSUPPORTED_ENCAP:
710       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
711                "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
712                err_info);
713       g_free(err_info);
714       errmsg = errmsg_errno;
715       break;
716
717     case WTAP_ERR_CANT_READ:
718       errmsg = "An attempt to read from the capture file failed for"
719                " some unknown reason.";
720       break;
721
722     case WTAP_ERR_SHORT_READ:
723       errmsg = "The capture file appears to have been cut short"
724                " in the middle of a packet.";
725       break;
726
727     case WTAP_ERR_BAD_RECORD:
728       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
729                "The capture file appears to be damaged or corrupt.\n(%s)",
730                err_info);
731       g_free(err_info);
732       errmsg = errmsg_errno;
733       break;
734
735     default:
736       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
737            "An error occurred while reading the"
738            " capture file: %s.", wtap_strerror(err));
739       errmsg = errmsg_errno;
740       break;
741     }
742     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", errmsg);
743     return CF_READ_ERROR;
744   } else
745     return CF_READ_OK;
746 }
747
748 #ifdef HAVE_LIBPCAP
749 cf_status_t
750 cf_start_tail(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
751 {
752   cf_status_t cf_status;
753
754   cf_status = cf_open(cf, fname, is_tempfile, err);
755   return cf_status;
756 }
757
758 cf_read_status_t
759 cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
760 {
761   gint64 data_offset = 0;
762   gchar *err_info;
763   volatile int newly_displayed_packets = 0;
764   dfilter_t   *dfcode;
765   gboolean filtering_tap_listeners;
766   guint tap_flags;
767   volatile gboolean visible = FALSE;
768   gboolean compiled;
769
770   /* Compile the current display filter.
771    * We assume this will not fail since cf->dfilter is only set in
772    * cf_filter IFF the filter was valid.
773    */
774   compiled = dfilter_compile(cf->dfilter, &dfcode);
775   g_assert(!cf->dfilter || (compiled && dfcode));
776
777   /* Do we have any tap listeners with filters? */
778   filtering_tap_listeners = have_filtering_tap_listeners();
779
780   /* Get the union of the flags for all tap listeners. */
781   tap_flags = union_of_tap_listener_flags();
782
783   *err = 0;
784
785 #ifdef NEW_PACKET_LIST
786   new_packet_list_check_end();
787   new_packet_list_freeze();
788 #else
789   packet_list_check_end();
790   packet_list_freeze();
791 #endif
792
793   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: %u new: %u", cf->count, to_read);*/
794
795   while (to_read != 0 && (wtap_read(cf->wth, err, &err_info, &data_offset))) {
796     if (cf->state == FILE_READ_ABORTED) {
797       /* Well, the user decided to exit Wireshark.  Break out of the
798          loop, and let the code below (which is called even if there
799      aren't any packets left to read) exit. */
800       break;
801     }
802     TRY{
803         if (read_packet(cf, dfcode, filtering_tap_listeners, tap_flags,
804                         data_offset) != -1) {
805             visible = TRUE;
806             newly_displayed_packets++;
807         }else{
808             visible = FALSE;
809         }
810     }
811     CATCH(OutOfMemoryError) {
812         gpointer dialog;
813
814         dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
815               "%sOut Of Memory!%s\n"
816               "\n"
817               "Sorry, but Wireshark has to terminate now!\n"
818               "\n"
819               "The capture file is not lost, it can be found at:\n"
820               "%s\n"
821               "\n"
822               "Some infos / workarounds can be found at:\n"
823               "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
824               simple_dialog_primary_start(), simple_dialog_primary_end(), cf->filename);
825         /* we have to terminate, as we cannot recover from the memory error */
826         simple_dialog_set_cb(dialog, outofmemory_cb, NULL);
827         while(1) {
828             main_window_update();
829             /* XXX - how to avoid a busy wait? */
830             /* Sleep(100); */
831         };
832 #ifdef NEW_PACKET_LIST
833         new_packet_list_thaw();
834 #else
835         packet_list_thaw();
836 #endif
837         return CF_READ_ABORTED;
838     }
839     ENDTRY;
840     to_read--;
841   }
842
843   /* Cleanup and release all dfilter resources */
844   if (dfcode != NULL){
845     dfilter_free(dfcode);
846   }
847
848   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: count %u state: %u err: %u",
849       cf->count, cf->state, *err);*/
850
851 #ifdef NEW_PACKET_LIST
852   new_packet_list_thaw();
853 #else
854   /* XXX - this causes "flickering" of the list */
855   packet_list_thaw();
856 #endif
857
858   /* moving to the end of the packet list - if the user requested so and
859      we have some new packets. */
860   if (newly_displayed_packets && auto_scroll_live && cf->plist_end != NULL)
861 #ifdef NEW_PACKET_LIST
862     if(visible)
863       new_packet_list_moveto_end();
864 #else
865     /* this doesn't seem to work well with a frozen GTK_Clist, so do this after
866        packet_list_thaw() is done, see bugzilla 1188 */
867     /* XXX - this cheats and looks inside the packet list to find the final
868        row number. */
869     packet_list_moveto_end();
870 #endif /* NEW_PACKET_LIST */
871
872   if (cf->state == FILE_READ_ABORTED) {
873     /* Well, the user decided to exit Wireshark.  Return CF_READ_ABORTED
874        so that our caller can kill off the capture child process;
875        this will cause an EOF on the pipe from the child, so
876        "cf_finish_tail()" will be called, and it will clean up
877        and exit. */
878     return CF_READ_ABORTED;
879   } else if (*err != 0) {
880     /* We got an error reading the capture file.
881        XXX - pop up a dialog box instead? */
882     g_warning("Error \"%s\" while reading: \"%s\"\n",
883         wtap_strerror(*err), cf->filename);
884
885     return CF_READ_ERROR;
886   } else
887     return CF_READ_OK;
888 }
889
890 cf_read_status_t
891 cf_finish_tail(capture_file *cf, int *err)
892 {
893   gchar *err_info;
894   gint64 data_offset;
895   dfilter_t   *dfcode;
896   gboolean filtering_tap_listeners;
897   guint tap_flags;
898   gboolean compiled;
899
900   /* Compile the current display filter.
901    * We assume this will not fail since cf->dfilter is only set in
902    * cf_filter IFF the filter was valid.
903    */
904   compiled = dfilter_compile(cf->dfilter, &dfcode);
905   g_assert(!cf->dfilter || (compiled && dfcode));
906
907   /* Do we have any tap listeners with filters? */
908   filtering_tap_listeners = have_filtering_tap_listeners();
909
910   /* Get the union of the flags for all tap listeners. */
911   tap_flags = union_of_tap_listener_flags();
912
913   if(cf->wth == NULL) {
914     cf_close(cf);
915     return CF_READ_ERROR;
916   }
917
918 #ifdef NEW_PACKET_LIST
919   new_packet_list_check_end();
920   new_packet_list_freeze();
921 #else
922   packet_list_check_end();
923   packet_list_freeze();
924 #endif
925
926   while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
927     if (cf->state == FILE_READ_ABORTED) {
928       /* Well, the user decided to abort the read.  Break out of the
929          loop, and let the code below (which is called even if there
930      aren't any packets left to read) exit. */
931       break;
932     }
933     read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
934   }
935
936   /* Cleanup and release all dfilter resources */
937   if (dfcode != NULL){
938     dfilter_free(dfcode);
939   }
940
941 #ifdef NEW_PACKET_LIST
942   new_packet_list_thaw();
943 #else
944   packet_list_thaw();
945 #endif
946
947   if (cf->state == FILE_READ_ABORTED) {
948     /* Well, the user decided to abort the read.  We're only called
949        when the child capture process closes the pipe to us (meaning
950        it's probably exited), so we can just close the capture
951        file; we return CF_READ_ABORTED so our caller can do whatever
952        is appropriate when that happens. */
953     cf_close(cf);
954     return CF_READ_ABORTED;
955   }
956
957   if (auto_scroll_live && cf->plist_end != NULL)
958 #ifdef NEW_PACKET_LIST
959     new_packet_list_moveto_end();
960 #else
961     /* XXX - this cheats and looks inside the packet list to find the final
962        row number. */
963     packet_list_moveto_end();
964 #endif
965
966   /* We're done reading sequentially through the file. */
967   cf->state = FILE_READ_DONE;
968
969   /* We're done reading sequentially through the file; close the
970      sequential I/O side, to free up memory it requires. */
971   wtap_sequential_close(cf->wth);
972
973   /* Allow the protocol dissectors to free up memory that they
974    * don't need after the sequential run-through of the packets. */
975   postseq_cleanup_all_protocols();
976
977   /* Set the file encapsulation type now; we don't know what it is until
978      we've looked at all the packets, as we don't know until then whether
979      there's more than one type (and thus whether it's
980      WTAP_ENCAP_PER_PACKET). */
981   cf->lnk_t = wtap_file_encap(cf->wth);
982
983   if (*err != 0) {
984     /* We got an error reading the capture file.
985        XXX - pop up a dialog box? */
986     return CF_READ_ERROR;
987   } else {
988     return CF_READ_OK;
989   }
990 }
991 #endif /* HAVE_LIBPCAP */
992
993 const gchar *
994 cf_get_display_name(capture_file *cf)
995 {
996   const gchar *displayname;
997
998   /* Return a name to use in displays */
999   if (!cf->is_tempfile) {
1000     /* Get the last component of the file name, and use that. */
1001     if (cf->filename){
1002       displayname = get_basename(cf->filename);
1003     } else {
1004       displayname="(No file)";
1005     }
1006   } else {
1007     /* The file we read is a temporary file from a live capture;
1008        we don't mention its name. */
1009     displayname = "(Untitled)";
1010   }
1011   return displayname;
1012 }
1013
1014 /* XXX - use a macro instead? */
1015 int
1016 cf_get_packet_count(capture_file *cf)
1017 {
1018     return cf->count;
1019 }
1020
1021 /* XXX - use a macro instead? */
1022 void
1023 cf_set_packet_count(capture_file *cf, int packet_count)
1024 {
1025     cf->count = packet_count;
1026 }
1027
1028 /* XXX - use a macro instead? */
1029 gboolean
1030 cf_is_tempfile(capture_file *cf)
1031 {
1032     return cf->is_tempfile;
1033 }
1034
1035 void cf_set_tempfile(capture_file *cf, gboolean is_tempfile)
1036 {
1037     cf->is_tempfile = is_tempfile;
1038 }
1039
1040
1041 /* XXX - use a macro instead? */
1042 void cf_set_drops_known(capture_file *cf, gboolean drops_known)
1043 {
1044     cf->drops_known = drops_known;
1045 }
1046
1047 /* XXX - use a macro instead? */
1048 void cf_set_drops(capture_file *cf, guint32 drops)
1049 {
1050     cf->drops = drops;
1051 }
1052
1053 /* XXX - use a macro instead? */
1054 gboolean cf_get_drops_known(capture_file *cf)
1055 {
1056     return cf->drops_known;
1057 }
1058
1059 /* XXX - use a macro instead? */
1060 guint32 cf_get_drops(capture_file *cf)
1061 {
1062     return cf->drops;
1063 }
1064
1065 void cf_set_rfcode(capture_file *cf, dfilter_t *rfcode)
1066 {
1067     cf->rfcode = rfcode;
1068 }
1069
1070 #ifdef NEW_PACKET_LIST
1071 static int
1072 add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
1073     dfilter_t *dfcode, gboolean filtering_tap_listeners,
1074     guint tap_flags,
1075     union wtap_pseudo_header *pseudo_header, const guchar *buf,
1076     gboolean refilter,
1077     gboolean add_to_packet_list)
1078 {
1079   gboolean  create_proto_tree = FALSE;
1080   epan_dissect_t edt;
1081   column_info *cinfo;
1082   gint row = -1;
1083
1084   cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
1085
1086   /* If we don't have the time stamp of the first packet in the
1087      capture, it's because this is the first packet.  Save the time
1088      stamp of this packet as the time stamp of the first packet. */
1089   if (nstime_is_unset(&first_ts)) {
1090     first_ts  = fdata->abs_ts;
1091   }
1092
1093   /* if this frames is marked as a reference time frame, reset
1094      firstsec and firstusec to this frame */
1095   if(fdata->flags.ref_time){
1096     first_ts = fdata->abs_ts;
1097   }
1098
1099   /* If we don't have the time stamp of the previous displayed packet,
1100      it's because this is the first displayed packet.  Save the time
1101      stamp of this packet as the time stamp of the previous displayed
1102      packet. */
1103   if (nstime_is_unset(&prev_dis_ts)) {
1104     prev_dis_ts = fdata->abs_ts;
1105   }
1106
1107   /* If we don't have the time stamp of the previous captured packet,
1108      it's because this is the first packet.  Save the time
1109      stamp of this packet as the time stamp of the previous captured
1110      packet. */
1111   if (nstime_is_unset(&prev_cap_ts)) {
1112     prev_cap_ts = fdata->abs_ts;
1113   }
1114
1115   /* Get the time elapsed between the first packet and this packet. */
1116   nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
1117
1118   /* If it's greater than the current elapsed time, set the elapsed time
1119      to it (we check for "greater than" so as not to be confused by
1120      time moving backwards). */
1121   if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
1122   || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
1123     cf->elapsed_time = fdata->rel_ts;
1124   }
1125
1126   /* Get the time elapsed between the previous displayed packet and
1127      this packet. */
1128   nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
1129
1130   /* Get the time elapsed between the previous captured packet and
1131      this packet. */
1132   nstime_delta(&fdata->del_cap_ts, &fdata->abs_ts, &prev_cap_ts);
1133   prev_cap_ts = fdata->abs_ts;
1134
1135   /* If either
1136     + we have a display filter and are re-applying it;
1137     + we have tap listeners with filters;
1138     + we have tap listeners that require a protocol tree;
1139
1140      allocate a protocol tree root node, so that we'll construct
1141      a protocol tree against which a filter expression can be
1142      evaluated. */
1143   if ((dfcode != NULL && refilter) ||
1144       filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE))
1145       create_proto_tree = TRUE;
1146
1147   /* Dissect the frame. */
1148   epan_dissect_init(&edt, create_proto_tree, FALSE);
1149
1150   if (dfcode != NULL && refilter) {
1151       epan_dissect_prime_dfilter(&edt, dfcode);
1152   }
1153
1154   tap_queue_init(&edt);
1155   epan_dissect_run(&edt, pseudo_header, buf, fdata, cinfo);
1156   tap_push_tapped_queue(&edt);
1157
1158   /* If we have a display filter, apply it if we're refiltering, otherwise
1159      leave the "passed_dfilter" flag alone.
1160
1161      If we don't have a display filter, set "passed_dfilter" to 1. */
1162   if (dfcode != NULL) {
1163     if (refilter) {
1164       fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, &edt) ? 1 : 0;
1165     }
1166   } else
1167     fdata->flags.passed_dfilter = 1;
1168
1169   if (add_to_packet_list) {
1170     /* We fill the needed columns from new_packet_list */
1171       row = new_packet_list_append(cinfo, fdata, &edt.pi);
1172   }
1173
1174   if(fdata->flags.passed_dfilter || fdata->flags.ref_time)
1175   {
1176     /* This frame either passed the display filter list or is marked as
1177        a time reference frame.  All time reference frames are displayed
1178        even if they dont pass the display filter */
1179     if(fdata->flags.ref_time){
1180       /* if this was a TIME REF frame we should reset the cul bytes field */
1181       cum_bytes = fdata->pkt_len;
1182       fdata->cum_bytes = cum_bytes;
1183     } else {
1184       /* increase cum_bytes with this packets length */
1185       cum_bytes += fdata->pkt_len;
1186       fdata->cum_bytes = cum_bytes;
1187     }
1188
1189     /* Set the time of the previous displayed frame to the time of this
1190        frame. */
1191     prev_dis_ts = fdata->abs_ts;
1192
1193     /* If we haven't yet seen the first frame, this is it.
1194
1195        XXX - we must do this before we add the row to the display,
1196        as, if the display's GtkCList's selection mode is
1197        GTK_SELECTION_BROWSE, when the first entry is added to it,
1198        "cf_select_packet()" will be called, and it will fetch the row
1199        data for the 0th row, and will get a null pointer rather than
1200        "fdata", as "gtk_clist_append()" won't yet have returned and
1201        thus "gtk_clist_set_row_data()" won't yet have been called.
1202
1203        We thus need to leave behind bread crumbs so that
1204        "cf_select_packet()" can find this frame.  See the comment
1205        in "cf_select_packet()". */
1206     if (cf->first_displayed == NULL)
1207       cf->first_displayed = fdata;
1208
1209     /* This is the last frame we've seen so far. */
1210     cf->last_displayed = fdata;
1211
1212     cf->displayed_count++;
1213   }
1214
1215   epan_dissect_cleanup(&edt);
1216   return row;
1217 }
1218
1219 #else
1220
1221 static int
1222 add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
1223     dfilter_t *dfcode, gboolean filtering_tap_listeners,
1224     guint tap_flags,
1225     union wtap_pseudo_header *pseudo_header, const guchar *buf,
1226     gboolean refilter,
1227     gboolean add_to_packet_list _U_)
1228 {
1229   gboolean  create_proto_tree = FALSE;
1230   epan_dissect_t edt;
1231   column_info *cinfo;
1232   gint row = -1;
1233
1234   cinfo = &cf->cinfo;
1235
1236   /* just add some value here until we know if it is being displayed or not */
1237   fdata->cum_bytes  = cum_bytes + fdata->pkt_len;
1238
1239   /* If we don't have the time stamp of the first packet in the
1240      capture, it's because this is the first packet.  Save the time
1241      stamp of this packet as the time stamp of the first packet. */
1242   if (nstime_is_unset(&first_ts)) {
1243     first_ts  = fdata->abs_ts;
1244   }
1245   /* if this frames is marked as a reference time frame, reset
1246      firstsec and firstusec to this frame */
1247   if(fdata->flags.ref_time){
1248     first_ts = fdata->abs_ts;
1249   }
1250
1251   /* If we don't have the time stamp of the previous displayed packet,
1252      it's because this is the first displayed packet.  Save the time
1253      stamp of this packet as the time stamp of the previous displayed
1254      packet. */
1255   if (nstime_is_unset(&prev_dis_ts)) {
1256     prev_dis_ts = fdata->abs_ts;
1257   }
1258
1259   /* Get the time elapsed between the first packet and this packet. */
1260   nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
1261
1262   /* If it's greater than the current elapsed time, set the elapsed time
1263      to it (we check for "greater than" so as not to be confused by
1264      time moving backwards). */
1265   if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
1266   || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
1267     cf->elapsed_time = fdata->rel_ts;
1268   }
1269
1270   /* Get the time elapsed between the previous displayed packet and
1271      this packet. */
1272   nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
1273
1274   /* If either
1275
1276     we have a display filter and are re-applying it;
1277
1278     we have a list of color filters;
1279
1280     we have tap listeners with filters;
1281
1282     we have tap listeners that require a protocol tree;
1283
1284     we have custom columns;
1285
1286      allocate a protocol tree root node, so that we'll construct
1287      a protocol tree against which a filter expression can be
1288      evaluated. */
1289   if ((dfcode != NULL && refilter) ||
1290       color_filters_used() ||
1291       have_custom_cols(cinfo) ||
1292       filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE))
1293       create_proto_tree = TRUE;
1294
1295   /* Dissect the frame. */
1296   epan_dissect_init(&edt, create_proto_tree, FALSE);
1297
1298   if (dfcode != NULL && refilter) {
1299       epan_dissect_prime_dfilter(&edt, dfcode);
1300   }
1301
1302   /* prepare color filters */
1303   color_filters_prime_edt(&edt);
1304   col_custom_prime_edt(&edt, cinfo);
1305
1306   tap_queue_init(&edt);
1307   epan_dissect_run(&edt, pseudo_header, buf, fdata, cinfo);
1308   tap_push_tapped_queue(&edt);
1309
1310   /* If we have a display filter, apply it if we're refiltering, otherwise
1311      leave the "passed_dfilter" flag alone.
1312
1313      If we don't have a display filter, set "passed_dfilter" to 1. */
1314   if (dfcode != NULL) {
1315     if (refilter) {
1316       fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, &edt) ? 1 : 0;
1317     }
1318   } else
1319     fdata->flags.passed_dfilter = 1;
1320
1321   if( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) )
1322   {
1323     /* This frame either passed the display filter list or is marked as
1324        a time reference frame.  All time reference frames are displayed
1325        even if they dont pass the display filter */
1326     if(fdata->flags.ref_time){
1327       /* if this was a TIME REF frame we should reset the cul bytes field */
1328       cum_bytes = fdata->pkt_len;
1329       fdata->cum_bytes =  cum_bytes;
1330     } else {
1331       /* increase cum_bytes with this packets length */
1332       cum_bytes += fdata->pkt_len;
1333     }
1334
1335     epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
1336
1337     /* If we haven't yet seen the first frame, this is it.
1338
1339        XXX - we must do this before we add the row to the display,
1340        as, if the display's GtkCList's selection mode is
1341        GTK_SELECTION_BROWSE, when the first entry is added to it,
1342        "cf_select_packet()" will be called, and it will fetch the row
1343        data for the 0th row, and will get a null pointer rather than
1344        "fdata", as "gtk_clist_append()" won't yet have returned and
1345        thus "gtk_clist_set_row_data()" won't yet have been called.
1346
1347        We thus need to leave behind bread crumbs so that
1348        "cf_select_packet()" can find this frame.  See the comment
1349        in "cf_select_packet()". */
1350     if (cf->first_displayed == NULL)
1351       cf->first_displayed = fdata;
1352
1353     /* This is the last frame we've seen so far. */
1354     cf->last_displayed = fdata;
1355
1356     row = packet_list_append(cinfo->col_data, fdata);
1357
1358     /* colorize packet: first apply color filters
1359      * then if packet is marked, use preferences to overwrite color
1360      * we do both to make sure that when a packet gets un-marked, the
1361      * color will be correctly set (fixes bug 2038)
1362      */
1363      fdata->color_filter = color_filters_colorize_packet(row, &edt);
1364      if (fdata->flags.marked) {
1365        packet_list_set_colors(row, &prefs.gui_marked_fg, &prefs.gui_marked_bg);
1366      }
1367
1368     /* Set the time of the previous displayed frame to the time of this
1369        frame. */
1370     prev_dis_ts = fdata->abs_ts;
1371
1372     cf->displayed_count++;
1373   }
1374
1375   epan_dissect_cleanup(&edt);
1376   return row;
1377 }
1378 #endif
1379
1380 /* read in a new packet */
1381 /* returns the row of the new packet in the packet list or -1 if not displayed */
1382 static int
1383 read_packet(capture_file *cf, dfilter_t *dfcode,
1384             gboolean filtering_tap_listeners, guint tap_flags, gint64 offset)
1385 {
1386   const struct wtap_pkthdr *phdr = wtap_phdr(cf->wth);
1387   union wtap_pseudo_header *pseudo_header = wtap_pseudoheader(cf->wth);
1388   const guchar *buf = wtap_buf_ptr(cf->wth);
1389   frame_data   *fdata;
1390   int           passed;
1391   frame_data   *plist_end;
1392   int row = -1;
1393
1394   cf->count++;
1395
1396   /* Allocate the next list entry, and add it to the list.
1397    * memory chunks have been deprecated in favor of the slice allocator,
1398    * which has been added in 2.10
1399    */
1400 #if GLIB_CHECK_VERSION(2,10,0)
1401   fdata = g_slice_new(frame_data);
1402 #else
1403   fdata = g_mem_chunk_alloc(cf->plist_chunk);
1404 #endif
1405   fdata->num = cf->count;
1406   fdata->next = NULL;
1407   fdata->prev = NULL;
1408   fdata->pfd  = NULL;
1409   fdata->pkt_len  = phdr->len;
1410   fdata->cap_len  = phdr->caplen;
1411   fdata->file_off = offset;
1412   /* To save some memory, we coarcese it into a gint8 */
1413   g_assert(phdr->pkt_encap <= G_MAXINT8);
1414   fdata->lnk_t = (gint8) phdr->pkt_encap;
1415   fdata->abs_ts.secs = phdr->ts.secs;
1416   fdata->abs_ts.nsecs = phdr->ts.nsecs;
1417   fdata->flags.encoding = CHAR_ASCII;
1418   fdata->flags.visited = 0;
1419   fdata->flags.marked = 0;
1420   fdata->flags.ref_time = 0;
1421   fdata->color_filter = NULL;
1422 #ifdef NEW_PACKET_LIST
1423   fdata->col_text_len = se_alloc0(sizeof(fdata->col_text_len) * (cf->cinfo.num_cols));
1424   fdata->col_text = se_alloc0(sizeof(fdata->col_text) * (cf->cinfo.num_cols));
1425 #endif
1426
1427   passed = TRUE;
1428   if (cf->rfcode) {
1429     epan_dissect_t edt;
1430     epan_dissect_init(&edt, TRUE, FALSE);
1431     epan_dissect_prime_dfilter(&edt, cf->rfcode);
1432     epan_dissect_run(&edt, pseudo_header, buf, fdata, NULL);
1433     passed = dfilter_apply_edt(cf->rfcode, &edt);
1434     epan_dissect_cleanup(&edt);
1435   }
1436
1437   if (passed) {
1438     plist_end = cf->plist_end;
1439     fdata->prev = plist_end;
1440     if (plist_end != NULL)
1441       plist_end->next = fdata;
1442     else
1443       cf->plist_start = fdata;
1444     cf->plist_end = fdata;
1445
1446     cf->f_datalen = offset + phdr->caplen;
1447
1448     if (!cf->redissecting) {
1449       row = add_packet_to_packet_list(fdata, cf, dfcode,
1450                                       filtering_tap_listeners, tap_flags,
1451                                       pseudo_header, buf, TRUE, TRUE);
1452     }
1453   } else {
1454     /* We didn't pass read filter so roll back count */
1455     cf->count--;
1456
1457     /* XXX - if we didn't have read filters, or if we could avoid
1458        allocating the "frame_data" structure until we knew whether
1459        the frame passed the read filter, we could use a G_ALLOC_ONLY
1460        memory chunk...
1461
1462        ...but, at least in one test I did, where I just made the chunk
1463        a G_ALLOC_ONLY chunk and read in a huge capture file, it didn't
1464        seem to save a noticeable amount of time or space. */
1465 #if GLIB_CHECK_VERSION(2,10,0)
1466   /* memory chunks have been deprecated in favor of the slice allocator,
1467    * which has been added in 2.10
1468    */
1469     g_slice_free(frame_data,fdata);
1470 #else
1471     g_mem_chunk_free(cf->plist_chunk, fdata);
1472 #endif
1473   }
1474
1475   return row;
1476 }
1477
1478 cf_status_t
1479 cf_merge_files(char **out_filenamep, int in_file_count,
1480                char *const *in_filenames, int file_type, gboolean do_append)
1481 {
1482   merge_in_file_t  *in_files;
1483   wtap             *wth;
1484   char             *out_filename;
1485   char             *tmpname;
1486   int               out_fd;
1487   wtap_dumper      *pdh;
1488   int               open_err, read_err, write_err, close_err;
1489   gchar            *err_info;
1490   int               err_fileno;
1491   int               i;
1492   char              errmsg_errno[1024+1];
1493   const char       *errmsg;
1494   gboolean          got_read_error = FALSE, got_write_error = FALSE;
1495   gint64            data_offset;
1496   progdlg_t        *progbar = NULL;
1497   gboolean          stop_flag;
1498   gint64            f_len, file_pos;
1499   float             progbar_val;
1500   GTimeVal          start_time;
1501   gchar             status_str[100];
1502   gint64            progbar_nextstep;
1503   gint64            progbar_quantum;
1504
1505   /* open the input files */
1506   if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
1507                            &open_err, &err_info, &err_fileno)) {
1508     g_free(in_files);
1509     cf_open_failure_alert_box(in_filenames[err_fileno], open_err, err_info,
1510                               FALSE, 0);
1511     return CF_ERROR;
1512   }
1513
1514   if (*out_filenamep != NULL) {
1515     out_filename = *out_filenamep;
1516     out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
1517     if (out_fd == -1)
1518       open_err = errno;
1519   } else {
1520     out_fd = create_tempfile(&tmpname, "wireshark");
1521     if (out_fd == -1)
1522       open_err = errno;
1523     out_filename = g_strdup(tmpname);
1524     *out_filenamep = out_filename;
1525   }
1526   if (out_fd == -1) {
1527     err_info = NULL;
1528     merge_close_in_files(in_file_count, in_files);
1529     g_free(in_files);
1530     cf_open_failure_alert_box(out_filename, open_err, NULL, TRUE, file_type);
1531     return CF_ERROR;
1532   }
1533
1534   pdh = wtap_dump_fdopen(out_fd, file_type,
1535       merge_select_frame_type(in_file_count, in_files),
1536       merge_max_snapshot_length(in_file_count, in_files),
1537       FALSE /* compressed */, &open_err);
1538   if (pdh == NULL) {
1539     ws_close(out_fd);
1540     merge_close_in_files(in_file_count, in_files);
1541     g_free(in_files);
1542     cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
1543                               file_type);
1544     return CF_ERROR;
1545   }
1546
1547   /* Get the sum of the sizes of all the files. */
1548   f_len = 0;
1549   for (i = 0; i < in_file_count; i++)
1550     f_len += in_files[i].size;
1551
1552   /* Update the progress bar when it gets to this value. */
1553   progbar_nextstep = 0;
1554   /* When we reach the value that triggers a progress bar update,
1555      bump that value by this amount. */
1556   progbar_quantum = f_len/N_PROGBAR_UPDATES;
1557   /* Progress so far. */
1558   progbar_val = 0.0f;
1559
1560   stop_flag = FALSE;
1561   g_get_current_time(&start_time);
1562
1563   /* do the merge (or append) */
1564   for (;;) {
1565     if (do_append)
1566       wth = merge_append_read_packet(in_file_count, in_files, &read_err,
1567                                      &err_info);
1568     else
1569       wth = merge_read_packet(in_file_count, in_files, &read_err,
1570                               &err_info);
1571     if (wth == NULL) {
1572       if (read_err != 0)
1573         got_read_error = TRUE;
1574       break;
1575     }
1576
1577     /* Get the sum of the data offsets in all of the files. */
1578     data_offset = 0;
1579     for (i = 0; i < in_file_count; i++)
1580       data_offset += in_files[i].data_offset;
1581
1582     /* Create the progress bar if necessary.
1583        We check on every iteration of the loop, so that it takes no
1584        longer than the standard time to create it (otherwise, for a
1585        large file, we might take considerably longer than that standard
1586        time in order to get to the next progress bar step). */
1587     if (progbar == NULL) {
1588       progbar = delayed_create_progress_dlg("Merging", "files",
1589         FALSE, &stop_flag, &start_time, progbar_val);
1590     }
1591
1592     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1593        when we update it, we have to run the GTK+ main loop to get it
1594        to repaint what's pending, and doing so may involve an "ioctl()"
1595        to see if there's any pending input from an X server, and doing
1596        that for every packet can be costly, especially on a big file. */
1597     if (data_offset >= progbar_nextstep) {
1598         /* Get the sum of the seek positions in all of the files. */
1599         file_pos = 0;
1600         for (i = 0; i < in_file_count; i++)
1601           file_pos += wtap_read_so_far(in_files[i].wth, NULL);
1602         progbar_val = (gfloat) file_pos / (gfloat) f_len;
1603         if (progbar_val > 1.0f) {
1604           /* Some file probably grew while we were reading it.
1605              That "shouldn't happen", so we'll just clip the progress
1606              value at 1.0. */
1607           progbar_val = 1.0f;
1608         }
1609         if (progbar != NULL) {
1610           g_snprintf(status_str, sizeof(status_str),
1611                      "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
1612                      file_pos / 1024, f_len / 1024);
1613           update_progress_dlg(progbar, progbar_val, status_str);
1614         }
1615         progbar_nextstep += progbar_quantum;
1616     }
1617
1618     if (stop_flag) {
1619       /* Well, the user decided to abort the merge. */
1620       break;
1621     }
1622
1623     if (!wtap_dump(pdh, wtap_phdr(wth), wtap_pseudoheader(wth),
1624          wtap_buf_ptr(wth), &write_err)) {
1625       got_write_error = TRUE;
1626       break;
1627     }
1628   }
1629
1630   /* We're done merging the files; destroy the progress bar if it was created. */
1631   if (progbar != NULL)
1632     destroy_progress_dlg(progbar);
1633
1634   merge_close_in_files(in_file_count, in_files);
1635   if (!got_read_error && !got_write_error) {
1636     if (!wtap_dump_close(pdh, &write_err))
1637       got_write_error = TRUE;
1638   } else
1639     wtap_dump_close(pdh, &close_err);
1640
1641   if (got_read_error) {
1642     /*
1643      * Find the file on which we got the error, and report the error.
1644      */
1645     for (i = 0; i < in_file_count; i++) {
1646       if (in_files[i].state == GOT_ERROR) {
1647     /* Put up a message box noting that a read failed somewhere along
1648        the line. */
1649     switch (read_err) {
1650
1651     case WTAP_ERR_UNSUPPORTED_ENCAP:
1652       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1653            "The capture file %%s has a packet with a network type that Wireshark doesn't support.\n(%s)",
1654            err_info);
1655       g_free(err_info);
1656       errmsg = errmsg_errno;
1657       break;
1658
1659     case WTAP_ERR_CANT_READ:
1660       errmsg = "An attempt to read from the capture file %s failed for"
1661            " some unknown reason.";
1662       break;
1663
1664     case WTAP_ERR_SHORT_READ:
1665       errmsg = "The capture file %s appears to have been cut short"
1666            " in the middle of a packet.";
1667       break;
1668
1669     case WTAP_ERR_BAD_RECORD:
1670       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1671            "The capture file %%s appears to be damaged or corrupt.\n(%s)",
1672            err_info);
1673       g_free(err_info);
1674       errmsg = errmsg_errno;
1675       break;
1676
1677     default:
1678       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1679            "An error occurred while reading the"
1680            " capture file %%s: %s.", wtap_strerror(read_err));
1681       errmsg = errmsg_errno;
1682       break;
1683     }
1684         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, errmsg, in_files[i].filename);
1685       }
1686     }
1687   }
1688
1689   if (got_write_error) {
1690     /* Put up an alert box for the write error. */
1691     cf_write_failure_alert_box(out_filename, write_err);
1692   }
1693
1694   if (got_read_error || got_write_error || stop_flag) {
1695     /* Callers aren't expected to treat an error or an explicit abort
1696        differently - we put up error dialogs ourselves, so they don't
1697        have to. */
1698     return CF_ERROR;
1699   } else
1700     return CF_OK;
1701 }
1702
1703 cf_status_t
1704 cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force)
1705 {
1706   const char *filter_new = dftext ? dftext : "";
1707   const char *filter_old = cf->dfilter ? cf->dfilter : "";
1708   dfilter_t   *dfcode;
1709
1710   /* if new filter equals old one, do nothing unless told to do so */
1711   if (!force && strcmp(filter_new, filter_old) == 0) {
1712     return CF_OK;
1713   }
1714
1715   dfcode=NULL;
1716
1717   if (dftext == NULL) {
1718     /* The new filter is an empty filter (i.e., display all packets).
1719      * so leave dfcode==NULL
1720      */
1721   } else {
1722     /*
1723      * We have a filter; make a copy of it (as we'll be saving it),
1724      * and try to compile it.
1725      */
1726     dftext = g_strdup(dftext);
1727     if (!dfilter_compile(dftext, &dfcode)) {
1728       /* The attempt failed; report an error. */
1729       gchar *safe_dftext = simple_dialog_format_message(dftext);
1730       gchar *safe_dfilter_error_msg = simple_dialog_format_message(
1731       dfilter_error_msg);
1732       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1733           "%s%s%s\n"
1734           "\n"
1735           "The following display filter isn't a valid display filter:\n%s\n"
1736           "See the help for a description of the display filter syntax.",
1737           simple_dialog_primary_start(), safe_dfilter_error_msg,
1738           simple_dialog_primary_end(), safe_dftext);
1739       g_free(safe_dfilter_error_msg);
1740       g_free(safe_dftext);
1741       g_free(dftext);
1742       return CF_ERROR;
1743     }
1744
1745     /* Was it empty? */
1746     if (dfcode == NULL) {
1747       /* Yes - free the filter text, and set it to null. */
1748       g_free(dftext);
1749       dftext = NULL;
1750     }
1751   }
1752
1753   /* We have a valid filter.  Replace the current filter. */
1754   g_free(cf->dfilter);
1755   cf->dfilter = dftext;
1756
1757   /* Now rescan the packet list, applying the new filter, but not
1758      throwing away information constructed on a previous pass. */
1759   if (dftext == NULL) {
1760     rescan_packets(cf, "Resetting", "Filter", TRUE, FALSE);
1761   } else {
1762     rescan_packets(cf, "Filtering", dftext, TRUE, FALSE);
1763   }
1764
1765   /* Cleanup and release all dfilter resources */
1766   if (dfcode != NULL){
1767     dfilter_free(dfcode);
1768   }
1769   return CF_OK;
1770 }
1771
1772 void
1773 cf_colorize_packets(capture_file *cf)
1774 {
1775   rescan_packets(cf, "Colorizing", "all packets", FALSE, FALSE);
1776 }
1777
1778 void
1779 cf_reftime_packets(capture_file *cf)
1780 {
1781
1782 #ifdef NEW_PACKET_LIST
1783   ref_time_packets(cf);
1784 #else
1785   rescan_packets(cf, "Reprocessing", "all packets", TRUE, TRUE);
1786 #endif
1787 }
1788
1789 void
1790 cf_redissect_packets(capture_file *cf)
1791 {
1792   rescan_packets(cf, "Reprocessing", "all packets", TRUE, TRUE);
1793 }
1794
1795 /* Rescan the list of packets, reconstructing the CList.
1796
1797    "action" describes why we're doing this; it's used in the progress
1798    dialog box.
1799
1800    "action_item" describes what we're doing; it's used in the progress
1801    dialog box.
1802
1803    "refilter" is TRUE if we need to re-evaluate the filter expression.
1804
1805    "redissect" is TRUE if we need to make the dissectors reconstruct
1806    any state information they have (because a preference that affects
1807    some dissector has changed, meaning some dissector might construct
1808    its state differently from the way it was constructed the last time). */
1809 #ifdef NEW_PACKET_LIST
1810 static void
1811 rescan_packets(capture_file *cf, const char *action, const char *action_item,
1812         gboolean refilter, gboolean redissect)
1813 {
1814     /* Rescan packets new packet list */
1815   frame_data *fdata;
1816   progdlg_t  *progbar = NULL;
1817   gboolean    stop_flag;
1818   int         count;
1819   int         err;
1820   gchar      *err_info;
1821   frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
1822   int         selected_frame_num, preceding_frame_num, following_frame_num, prev_frame_num;
1823   gboolean    selected_frame_seen;
1824   int         frame_num;
1825   float       progbar_val;
1826   GTimeVal    start_time;
1827   gchar       status_str[100];
1828   int         progbar_nextstep;
1829   int         progbar_quantum;
1830   dfilter_t   *dfcode;
1831   gboolean    filtering_tap_listeners;
1832   guint       tap_flags;
1833   gboolean    add_to_packet_list = FALSE;
1834   gboolean compiled;
1835
1836   /* Compile the current display filter.
1837    * We assume this will not fail since cf->dfilter is only set in
1838    * cf_filter IFF the filter was valid.
1839    */
1840   compiled = dfilter_compile(cf->dfilter, &dfcode);
1841   g_assert(!cf->dfilter || (compiled && dfcode));
1842
1843   /* Do we have any tap listeners with filters? */
1844   filtering_tap_listeners = have_filtering_tap_listeners();
1845
1846   /* Get the union of the flags for all tap listeners. */
1847   tap_flags = union_of_tap_listener_flags();
1848
1849   reset_tap_listeners();
1850   /* Which frame, if any, is the currently selected frame?
1851      XXX - should the selected frame or the focus frame be the "current"
1852      frame, that frame being the one from which "Find Frame" searches
1853      start? */
1854   selected_frame = cf->current_frame;
1855
1856   /* Mark frane num as not found */
1857   selected_frame_num = -1;
1858
1859   /* Freeze the packet list while we redo it, so we don't get any
1860      screen updates while it happens. */
1861   new_packet_list_freeze();
1862
1863   if (redissect) {
1864     /* We need to re-initialize all the state information that protocols
1865        keep, because some preference that controls a dissector has changed,
1866        which might cause the state information to be constructed differently
1867        by that dissector. */
1868
1869     /* We might receive new packets while redissecting, and we don't
1870        want to dissect those before their time. */
1871     cf->redissecting = TRUE;
1872
1873     /* Cleanup all data structures used for dissection. */
1874     cleanup_dissection();
1875     /* Initialize all data structures used for dissection. */
1876     init_dissection();
1877
1878     /* We need to redissect the packets so we have to discard our old
1879      * packet list store. */
1880     new_packet_list_clear();
1881     add_to_packet_list = TRUE;
1882   }
1883
1884   /* We don't yet know which will be the first and last frames displayed. */
1885   cf->first_displayed = NULL;
1886   cf->last_displayed = NULL;
1887
1888   reset_elapsed();
1889
1890   /* We currently don't display any packets */
1891   cf->displayed_count = 0;
1892
1893   /* Iterate through the list of frames.  Call a routine for each frame
1894      to check whether it should be displayed and, if so, add it to
1895      the display list. */
1896   nstime_set_unset(&first_ts);
1897   nstime_set_unset(&prev_dis_ts);
1898   nstime_set_unset(&prev_cap_ts);
1899   cum_bytes = 0;
1900
1901   /* Update the progress bar when it gets to this value. */
1902   progbar_nextstep = 0;
1903   /* When we reach the value that triggers a progress bar update,
1904      bump that value by this amount. */
1905   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
1906   /* Count of packets at which we've looked. */
1907   count = 0;
1908   /* Progress so far. */
1909   progbar_val = 0.0f;
1910
1911   stop_flag = FALSE;
1912   g_get_current_time(&start_time);
1913
1914   /* no previous row yet */
1915   frame_num = -1;
1916   prev_frame_num = -1;
1917   prev_frame = NULL;
1918
1919   preceding_frame_num = -1;
1920   preceding_frame = NULL;
1921   following_frame_num = -1;
1922   following_frame = NULL;
1923
1924   selected_frame_seen = FALSE;
1925
1926   for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
1927     /* Create the progress bar if necessary.
1928        We check on every iteration of the loop, so that it takes no
1929        longer than the standard time to create it (otherwise, for a
1930        large file, we might take considerably longer than that standard
1931        time in order to get to the next progress bar step). */
1932     if (progbar == NULL)
1933       progbar = delayed_create_progress_dlg(action, action_item, TRUE,
1934                                             &stop_flag, &start_time,
1935                                             progbar_val);
1936
1937     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1938        when we update it, we have to run the GTK+ main loop to get it
1939        to repaint what's pending, and doing so may involve an "ioctl()"
1940        to see if there's any pending input from an X server, and doing
1941        that for every packet can be costly, especially on a big file. */
1942     if (count >= progbar_nextstep) {
1943       /* let's not divide by zero. I should never be started
1944        * with count == 0, so let's assert that
1945        */
1946       g_assert(cf->count > 0);
1947       progbar_val = (gfloat) count / cf->count;
1948
1949       if (progbar != NULL) {
1950         g_snprintf(status_str, sizeof(status_str),
1951                   "%4u of %u frames", count, cf->count);
1952         update_progress_dlg(progbar, progbar_val, status_str);
1953       }
1954
1955       progbar_nextstep += progbar_quantum;
1956     }
1957
1958     if (stop_flag) {
1959       /* Well, the user decided to abort the filtering.  Just stop.
1960
1961          XXX - go back to the previous filter?  Users probably just
1962      want not to wait for a filtering operation to finish;
1963      unless we cancel by having no filter, reverting to the
1964      previous filter will probably be even more expensive than
1965      continuing the filtering, as it involves going back to the
1966      beginning and filtering, and even with no filter we currently
1967      have to re-generate the entire clist, which is also expensive.
1968
1969      I'm not sure what Network Monitor does, but it doesn't appear
1970      to give you an unfiltered display if you cancel. */
1971       break;
1972     }
1973
1974     count++;
1975
1976     if (redissect) {
1977       /* Since all state for the frame was destroyed, mark the frame
1978        * as not visited, free the GSList referring to the state
1979        * data (the per-frame data itself was freed by
1980        * "init_dissection()"), and null out the GSList pointer. */
1981       fdata->flags.visited = 0;
1982       frame_data_cleanup(fdata);
1983
1984       /* cleanup_dissection() calls se_free_all();
1985        * And after that fdata->col_text (which is allocated using se_alloc0())
1986        * no longer points to valid memory.
1987        */
1988         fdata->col_text_len = se_alloc0(sizeof(fdata->col_text_len) * (cf->cinfo.num_cols));
1989         fdata->col_text = se_alloc0(sizeof(fdata->col_text) * (cf->cinfo.num_cols));
1990     }
1991
1992     if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
1993         cf->pd, fdata->cap_len, &err, &err_info)) {
1994             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1995             cf_read_error_message(err, err_info), cf->filename);
1996             break;
1997     }
1998
1999     /* If the previous frame is displayed, and we haven't yet seen the
2000        selected frame, remember that frame - it's the closest one we've
2001        yet seen before the selected frame. */
2002     if (prev_frame_num != -1 && !selected_frame_seen && prev_frame->flags.passed_dfilter) {
2003       preceding_frame_num = prev_frame_num;
2004       preceding_frame = prev_frame;
2005     }
2006     add_packet_to_packet_list(fdata, cf, dfcode, filtering_tap_listeners,
2007                                     tap_flags, &cf->pseudo_header, cf->pd,
2008                                     refilter,
2009                                     add_to_packet_list);
2010
2011     /* If this frame is displayed, and this is the first frame we've
2012        seen displayed after the selected frame, remember this frame -
2013        it's the closest one we've yet seen at or after the selected
2014        frame. */
2015     if (fdata->flags.passed_dfilter && selected_frame_seen && following_frame_num == -1) {
2016       following_frame_num = fdata->num;
2017       following_frame = fdata;
2018     }
2019     if (fdata == selected_frame) {
2020       selected_frame_seen = TRUE;
2021       if (fdata->flags.passed_dfilter)
2022           selected_frame_num = fdata->num;
2023     }
2024
2025     /* Remember this frame - it'll be the previous frame
2026        on the next pass through the loop. */
2027     prev_frame_num = fdata->num;
2028     prev_frame = fdata;
2029   }
2030
2031   /* We are done redissecting the packet list. */
2032   cf->redissecting = FALSE;
2033
2034   if (redissect) {
2035     /* Clear out what remains of the visited flags and per-frame data
2036        pointers.
2037
2038        XXX - that may cause various forms of bogosity when dissecting
2039        these frames, as they won't have been seen by this sequential
2040        pass, but the only alternative I see is to keep scanning them
2041        even though the user requested that the scan stop, and that
2042        would leave the user stuck with an Wireshark grinding on
2043        until it finishes.  Should we just stick them with that? */
2044     for (; fdata != NULL; fdata = fdata->next) {
2045       fdata->flags.visited = 0;
2046       frame_data_cleanup(fdata);
2047     }
2048   }
2049
2050   /* We're done filtering the packets; destroy the progress bar if it
2051      was created. */
2052   if (progbar != NULL)
2053     destroy_progress_dlg(progbar);
2054
2055   /* Unfreeze the packet list. */
2056   if (!add_to_packet_list)
2057     new_packet_list_recreate_visible_rows();
2058
2059   new_packet_list_thaw();
2060
2061   if (selected_frame_num == -1) {
2062     /* The selected frame didn't pass the filter. */
2063     if (selected_frame == NULL) {
2064       /* That's because there *was* no selected frame.  Make the first
2065          displayed frame the current frame. */
2066       selected_frame_num = 0;
2067     } else {
2068       /* Find the nearest displayed frame to the selected frame (whether
2069          it's before or after that frame) and make that the current frame.
2070          If the next and previous displayed frames are equidistant from the
2071          selected frame, choose the next one. */
2072       g_assert(following_frame == NULL ||
2073                following_frame->num >= selected_frame->num);
2074       g_assert(preceding_frame == NULL ||
2075                preceding_frame->num <= selected_frame->num);
2076       if (following_frame == NULL) {
2077         /* No frame after the selected frame passed the filter, so we
2078            have to select the last displayed frame before the selected
2079            frame. */
2080         selected_frame_num = preceding_frame_num;
2081         selected_frame = preceding_frame;
2082       } else if (preceding_frame == NULL) {
2083         /* No frame before the selected frame passed the filter, so we
2084            have to select the first displayed frame after the selected
2085            frame. */
2086         selected_frame_num = following_frame_num;
2087         selected_frame = following_frame;
2088       } else {
2089         /* Frames before and after the selected frame passed the filter, so
2090            we'll select the previous frame */
2091         selected_frame_num = preceding_frame_num;
2092         selected_frame = preceding_frame;
2093       }
2094     }
2095   }
2096
2097   if (selected_frame_num == -1) {
2098     /* There are no frames displayed at all. */
2099     cf_unselect_packet(cf);
2100   } else {
2101     /* Either the frame that was selected passed the filter, or we've
2102        found the nearest displayed frame to that frame.  Select it, make
2103        it the focus row, and make it visible. */
2104     if (selected_frame_num == 0) {
2105       new_packet_list_select_first_row();
2106     }else{
2107       new_packet_list_find_row_from_data(selected_frame, TRUE);
2108     }
2109   }
2110
2111   /* Cleanup and release all dfilter resources */
2112   if (dfcode != NULL){
2113     dfilter_free(dfcode);
2114   }
2115 }
2116
2117 #else
2118
2119 static void
2120 rescan_packets(capture_file *cf, const char *action, const char *action_item,
2121         gboolean refilter, gboolean redissect)
2122 {
2123   frame_data *fdata;
2124   progdlg_t  *progbar = NULL;
2125   gboolean    stop_flag;
2126   int         count;
2127   int         err;
2128   gchar      *err_info;
2129   frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
2130   int         selected_row, prev_row, preceding_row, following_row;
2131   gboolean    selected_frame_seen;
2132   int         row;
2133   float       progbar_val;
2134   GTimeVal    start_time;
2135   gchar       status_str[100];
2136   int         progbar_nextstep;
2137   int         progbar_quantum;
2138   dfilter_t   *dfcode;
2139   gboolean    filtering_tap_listeners;
2140   guint       tap_flags;
2141   gboolean    add_to_packet_list = TRUE;
2142   gboolean compiled;
2143
2144   /* Compile the current display filter.
2145    * We assume this will not fail since cf->dfilter is only set in
2146    * cf_filter IFF the filter was valid.
2147    */
2148   compiled = dfilter_compile(cf->dfilter, &dfcode);
2149   g_assert(!cf->dfilter || (compiled && dfcode));
2150
2151   /* Do we have any tap listeners with filters? */
2152   filtering_tap_listeners = have_filtering_tap_listeners();
2153
2154   /* Get the union of the flags for all tap listeners. */
2155   tap_flags = union_of_tap_listener_flags();
2156
2157   reset_tap_listeners();
2158   /* Which frame, if any, is the currently selected frame?
2159      XXX - should the selected frame or the focus frame be the "current"
2160      frame, that frame being the one from which "Find Frame" searches
2161      start? */
2162   selected_frame = cf->current_frame;
2163
2164   /* We don't yet know what row that frame will be on, if any, after we
2165      rebuild the clist, however. */
2166   selected_row = -1;
2167
2168   /* Freeze the packet list while we redo it, so we don't get any
2169      screen updates while it happens. */
2170   packet_list_freeze();
2171
2172   /* Clear it out. */
2173   packet_list_clear();
2174
2175   if (redissect) {
2176     /* We need to re-initialize all the state information that protocols
2177        keep, because some preference that controls a dissector has changed,
2178        which might cause the state information to be constructed differently
2179        by that dissector. */
2180
2181     /* We might receive new packets while redissecting, and we don't
2182        want to dissect those before their time. */
2183     cf->redissecting = TRUE;
2184
2185     /* Cleanup all data structures used for dissection. */
2186     cleanup_dissection();
2187     /* Initialize all data structures used for dissection. */
2188     init_dissection();
2189
2190   }
2191
2192   /* We don't yet know which will be the first and last frames displayed. */
2193   cf->first_displayed = NULL;
2194   cf->last_displayed = NULL;
2195
2196   reset_elapsed();
2197
2198   /* We currently don't display any packets */
2199   cf->displayed_count = 0;
2200
2201   /* Iterate through the list of frames.  Call a routine for each frame
2202      to check whether it should be displayed and, if so, add it to
2203      the display list. */
2204   nstime_set_unset(&first_ts);
2205   nstime_set_unset(&prev_dis_ts);
2206   cum_bytes = 0;
2207
2208   /* Update the progress bar when it gets to this value. */
2209   progbar_nextstep = 0;
2210   /* When we reach the value that triggers a progress bar update,
2211      bump that value by this amount. */
2212   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2213   /* Count of packets at which we've looked. */
2214   count = 0;
2215   /* Progress so far. */
2216   progbar_val = 0.0f;
2217
2218   stop_flag = FALSE;
2219   g_get_current_time(&start_time);
2220
2221   row = -1;     /* no previous row yet */
2222   prev_row = -1;
2223   prev_frame = NULL;
2224
2225   preceding_row = -1;
2226   preceding_frame = NULL;
2227   following_row = -1;
2228   following_frame = NULL;
2229
2230   selected_frame_seen = FALSE;
2231
2232   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
2233     /* Create the progress bar if necessary.
2234        We check on every iteration of the loop, so that it takes no
2235        longer than the standard time to create it (otherwise, for a
2236        large file, we might take considerably longer than that standard
2237        time in order to get to the next progress bar step). */
2238     if (progbar == NULL)
2239       progbar = delayed_create_progress_dlg(action, action_item, TRUE,
2240                                             &stop_flag, &start_time,
2241                                             progbar_val);
2242
2243     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2244        when we update it, we have to run the GTK+ main loop to get it
2245        to repaint what's pending, and doing so may involve an "ioctl()"
2246        to see if there's any pending input from an X server, and doing
2247        that for every packet can be costly, especially on a big file. */
2248     if (count >= progbar_nextstep) {
2249       /* let's not divide by zero. I should never be started
2250        * with count == 0, so let's assert that
2251        */
2252       g_assert(cf->count > 0);
2253       progbar_val = (gfloat) count / cf->count;
2254
2255       if (progbar != NULL) {
2256         g_snprintf(status_str, sizeof(status_str),
2257                   "%4u of %u frames", count, cf->count);
2258         update_progress_dlg(progbar, progbar_val, status_str);
2259       }
2260
2261       progbar_nextstep += progbar_quantum;
2262     }
2263
2264     if (stop_flag) {
2265       /* Well, the user decided to abort the filtering.  Just stop.
2266
2267          XXX - go back to the previous filter?  Users probably just
2268      want not to wait for a filtering operation to finish;
2269      unless we cancel by having no filter, reverting to the
2270      previous filter will probably be even more expensive than
2271      continuing the filtering, as it involves going back to the
2272      beginning and filtering, and even with no filter we currently
2273      have to re-generate the entire clist, which is also expensive.
2274
2275      I'm not sure what Network Monitor does, but it doesn't appear
2276      to give you an unfiltered display if you cancel. */
2277       break;
2278     }
2279
2280     count++;
2281
2282     if (redissect) {
2283       /* Since all state for the frame was destroyed, mark the frame
2284        * as not visited, free the GSList referring to the state
2285        * data (the per-frame data itself was freed by
2286        * "init_dissection()"), and null out the GSList pointer.
2287        */
2288       fdata->flags.visited = 0;
2289       frame_data_cleanup(fdata);
2290     }
2291
2292     if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
2293         cf->pd, fdata->cap_len, &err, &err_info)) {
2294             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2295             cf_read_error_message(err, err_info), cf->filename);
2296             break;
2297     }
2298
2299     /* If the previous frame is displayed, and we haven't yet seen the
2300        selected frame, remember that frame - it's the closest one we've
2301        yet seen before the selected frame. */
2302     if (prev_row != -1 && !selected_frame_seen) {
2303       preceding_row = prev_row;
2304       preceding_frame = prev_frame;
2305     }
2306     row = add_packet_to_packet_list(fdata, cf, dfcode, filtering_tap_listeners,
2307                                     tap_flags, &cf->pseudo_header, cf->pd,
2308                                     refilter,
2309                                     add_to_packet_list);
2310
2311     /* If this frame is displayed, and this is the first frame we've
2312        seen displayed after the selected frame, remember this frame -
2313        it's the closest one we've yet seen at or after the selected
2314        frame. */
2315     if (row != -1 && selected_frame_seen && following_row == -1) {
2316       following_row = row;
2317       following_frame = fdata;
2318     }
2319     if (fdata == selected_frame) {
2320       selected_row = row;
2321       selected_frame_seen = TRUE;
2322     }
2323
2324     /* Remember this row/frame - it'll be the previous row/frame
2325        on the next pass through the loop. */
2326     prev_row = row;
2327     prev_frame = fdata;
2328   }
2329
2330   /* We are done redissecting the packet list. */
2331   cf->redissecting = FALSE;
2332
2333   if (redissect) {
2334     /* Clear out what remains of the visited flags and per-frame data
2335        pointers.
2336
2337        XXX - that may cause various forms of bogosity when dissecting
2338        these frames, as they won't have been seen by this sequential
2339        pass, but the only alternative I see is to keep scanning them
2340        even though the user requested that the scan stop, and that
2341        would leave the user stuck with an Wireshark grinding on
2342        until it finishes.  Should we just stick them with that? */
2343     for (; fdata != NULL; fdata = fdata->next) {
2344       fdata->flags.visited = 0;
2345       frame_data_cleanup(fdata);
2346     }
2347   }
2348
2349   /* We're done filtering the packets; destroy the progress bar if it
2350      was created. */
2351   if (progbar != NULL)
2352     destroy_progress_dlg(progbar);
2353
2354   /* Unfreeze the packet list. */
2355   packet_list_thaw();
2356
2357   if (selected_row == -1) {
2358     /* The selected frame didn't pass the filter. */
2359     if (selected_frame == NULL) {
2360       /* That's because there *was* no selected frame.  Make the first
2361          displayed frame the current frame. */
2362       selected_row = 0;
2363     } else {
2364       /* Find the nearest displayed frame to the selected frame (whether
2365          it's before or after that frame) and make that the current frame.
2366          If the next and previous displayed frames are equidistant from the
2367          selected frame, choose the next one. */
2368       g_assert(following_frame == NULL ||
2369                following_frame->num >= selected_frame->num);
2370       g_assert(preceding_frame == NULL ||
2371                preceding_frame->num <= selected_frame->num);
2372       if (following_frame == NULL) {
2373         /* No frame after the selected frame passed the filter, so we
2374            have to select the last displayed frame before the selected
2375            frame. */
2376         selected_row = preceding_row;
2377       } else if (preceding_frame == NULL) {
2378         /* No frame before the selected frame passed the filter, so we
2379            have to select the first displayed frame after the selected
2380            frame. */
2381         selected_row = following_row;
2382       } else {
2383         /* Frames before and after the selected frame passed the filter, so
2384            we'll select the previous frame */
2385         selected_row = preceding_row;
2386       }
2387     }
2388   }
2389
2390   if (selected_row == -1) {
2391     /* There are no frames displayed at all. */
2392     cf_unselect_packet(cf);
2393   } else {
2394     /* Either the frame that was selected passed the filter, or we've
2395        found the nearest displayed frame to that frame.  Select it, make
2396        it the focus row, and make it visible. */
2397     if (selected_row == 0) {
2398       /* Set to invalid to force update of packet list and packet details */
2399       cf->current_row = -1;
2400     }
2401     packet_list_set_selected_row(selected_row);
2402   }
2403
2404   /* Cleanup and release all dfilter resources */
2405   if (dfcode != NULL){
2406     dfilter_free(dfcode);
2407   }
2408 }
2409 #endif /* NEW_PACKET_LIST */
2410
2411 /*
2412  * Scan trough all frame data and recalculate the ref time
2413  * without rereading the file.
2414  * XXX - do we need a progres bar or is this fast enough?
2415  */
2416 #ifdef NEW_PACKET_LIST
2417 static void
2418 ref_time_packets(capture_file *cf)
2419 {
2420   frame_data *fdata;
2421
2422   nstime_set_unset(&first_ts);
2423   nstime_set_unset(&prev_dis_ts);
2424   nstime_set_unset(&prev_cap_ts);
2425   cum_bytes = 0;
2426
2427   for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
2428     /* just add some value here until we know if it is being displayed or not */
2429     fdata->cum_bytes = cum_bytes + fdata->pkt_len;
2430
2431     /* If we don't have the time stamp of the first packet in the
2432      capture, it's because this is the first packet.  Save the time
2433      stamp of this packet as the time stamp of the first packet. */
2434     if (nstime_is_unset(&first_ts)) {
2435         first_ts  = fdata->abs_ts;
2436     }
2437       /* if this frames is marked as a reference time frame, reset
2438         firstsec and firstusec to this frame */
2439     if(fdata->flags.ref_time){
2440     first_ts = fdata->abs_ts;
2441     }
2442
2443     /* If we don't have the time stamp of the previous displayed packet,
2444      it's because this is the first displayed packet.  Save the time
2445      stamp of this packet as the time stamp of the previous displayed
2446      packet. */
2447     if (nstime_is_unset(&prev_dis_ts)) {
2448         prev_dis_ts = fdata->abs_ts;
2449     }
2450
2451     /* Get the time elapsed between the first packet and this packet. */
2452     nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
2453
2454     /* If it's greater than the current elapsed time, set the elapsed time
2455      to it (we check for "greater than" so as not to be confused by
2456      time moving backwards). */
2457     if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
2458         || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
2459         cf->elapsed_time = fdata->rel_ts;
2460     }
2461
2462     /* Get the time elapsed between the previous displayed packet and
2463      this packet. */
2464     nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
2465
2466     if( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) ){
2467         /* This frame either passed the display filter list or is marked as
2468         a time reference frame.  All time reference frames are displayed
2469         even if they dont pass the display filter */
2470         if(fdata->flags.ref_time){
2471             /* if this was a TIME REF frame we should reset the cul bytes field */
2472             cum_bytes = fdata->pkt_len;
2473             fdata->cum_bytes =  cum_bytes;
2474         } else {
2475             /* increase cum_bytes with this packets length */
2476             cum_bytes += fdata->pkt_len;
2477         }
2478     }
2479   }
2480 }
2481 #endif
2482
2483 typedef enum {
2484   PSP_FINISHED,
2485   PSP_STOPPED,
2486   PSP_FAILED
2487 } psp_return_t;
2488
2489 static psp_return_t
2490 process_specified_packets(capture_file *cf, packet_range_t *range,
2491     const char *string1, const char *string2, gboolean terminate_is_stop,
2492     gboolean (*callback)(capture_file *, frame_data *,
2493                          union wtap_pseudo_header *, const guint8 *, void *),
2494     void *callback_args)
2495 {
2496   frame_data *fdata;
2497   int         err;
2498   gchar      *err_info;
2499   union wtap_pseudo_header pseudo_header;
2500   guint8      pd[WTAP_MAX_PACKET_SIZE+1];
2501   psp_return_t ret = PSP_FINISHED;
2502
2503   progdlg_t  *progbar = NULL;
2504   int         progbar_count;
2505   float       progbar_val;
2506   gboolean    progbar_stop_flag;
2507   GTimeVal    progbar_start_time;
2508   gchar       progbar_status_str[100];
2509   int         progbar_nextstep;
2510   int         progbar_quantum;
2511   range_process_e process_this;
2512
2513   /* Update the progress bar when it gets to this value. */
2514   progbar_nextstep = 0;
2515   /* When we reach the value that triggers a progress bar update,
2516      bump that value by this amount. */
2517   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2518   /* Count of packets at which we've looked. */
2519   progbar_count = 0;
2520   /* Progress so far. */
2521   progbar_val = 0.0f;
2522
2523   progbar_stop_flag = FALSE;
2524   g_get_current_time(&progbar_start_time);
2525
2526   packet_range_process_init(range);
2527
2528   /* Iterate through the list of packets, printing the packets that
2529      were selected by the current display filter.  */
2530   for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
2531     /* Create the progress bar if necessary.
2532        We check on every iteration of the loop, so that it takes no
2533        longer than the standard time to create it (otherwise, for a
2534        large file, we might take considerably longer than that standard
2535        time in order to get to the next progress bar step). */
2536     if (progbar == NULL)
2537       progbar = delayed_create_progress_dlg(string1, string2,
2538                                             terminate_is_stop,
2539                                             &progbar_stop_flag,
2540                                             &progbar_start_time,
2541                                             progbar_val);
2542
2543     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2544        when we update it, we have to run the GTK+ main loop to get it
2545        to repaint what's pending, and doing so may involve an "ioctl()"
2546        to see if there's any pending input from an X server, and doing
2547        that for every packet can be costly, especially on a big file. */
2548     if (progbar_count >= progbar_nextstep) {
2549       /* let's not divide by zero. I should never be started
2550        * with count == 0, so let's assert that
2551        */
2552       g_assert(cf->count > 0);
2553       progbar_val = (gfloat) progbar_count / cf->count;
2554
2555       if (progbar != NULL) {
2556         g_snprintf(progbar_status_str, sizeof(progbar_status_str),
2557                    "%4u of %u packets", progbar_count, cf->count);
2558         update_progress_dlg(progbar, progbar_val, progbar_status_str);
2559       }
2560
2561       progbar_nextstep += progbar_quantum;
2562     }
2563
2564     if (progbar_stop_flag) {
2565       /* Well, the user decided to abort the operation.  Just stop,
2566          and arrange to return PSP_STOPPED to our caller, so they know
2567          it was stopped explicitly. */
2568       ret = PSP_STOPPED;
2569       break;
2570     }
2571
2572     progbar_count++;
2573
2574     /* do we have to process this packet? */
2575     process_this = packet_range_process_packet(range, fdata);
2576     if (process_this == range_process_next) {
2577         /* this packet uninteresting, continue with next one */
2578         continue;
2579     } else if (process_this == range_processing_finished) {
2580         /* all interesting packets processed, stop the loop */
2581         break;
2582     }
2583
2584     /* Get the packet */
2585     if (!wtap_seek_read(cf->wth, fdata->file_off, &pseudo_header,
2586                         pd, fdata->cap_len, &err, &err_info)) {
2587       /* Attempt to get the packet failed. */
2588       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2589                     cf_read_error_message(err, err_info), cf->filename);
2590       ret = PSP_FAILED;
2591       break;
2592     }
2593     /* Process the packet */
2594     if (!callback(cf, fdata, &pseudo_header, pd, callback_args)) {
2595       /* Callback failed.  We assume it reported the error appropriately. */
2596       ret = PSP_FAILED;
2597       break;
2598     }
2599   }
2600
2601   /* We're done printing the packets; destroy the progress bar if
2602      it was created. */
2603   if (progbar != NULL)
2604     destroy_progress_dlg(progbar);
2605
2606   return ret;
2607 }
2608
2609 typedef struct {
2610   gboolean construct_protocol_tree;
2611   column_info *cinfo;
2612 } retap_callback_args_t;
2613
2614 static gboolean
2615 retap_packet(capture_file *cf _U_, frame_data *fdata,
2616              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2617              void *argsp)
2618 {
2619   retap_callback_args_t *args = argsp;
2620   epan_dissect_t edt;
2621
2622   epan_dissect_init(&edt, args->construct_protocol_tree, FALSE);
2623   tap_queue_init(&edt);
2624   epan_dissect_run(&edt, pseudo_header, pd, fdata, args->cinfo);
2625   tap_push_tapped_queue(&edt);
2626   epan_dissect_cleanup(&edt);
2627
2628   return TRUE;
2629 }
2630
2631 cf_read_status_t
2632 cf_retap_packets(capture_file *cf)
2633 {
2634   packet_range_t range;
2635   retap_callback_args_t callback_args;
2636   gboolean filtering_tap_listeners;
2637   guint tap_flags;
2638
2639   /* Do we have any tap listeners with filters? */
2640   filtering_tap_listeners = have_filtering_tap_listeners();
2641
2642   tap_flags = union_of_tap_listener_flags();
2643
2644   /* If any tap listeners have filters, or require the protocol tree,
2645      construct the protocol tree. */
2646   callback_args.construct_protocol_tree = filtering_tap_listeners ||
2647                                           (tap_flags & TL_REQUIRES_PROTO_TREE);
2648
2649   /* If any tap listeners require the columns, construct them. */
2650   callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
2651
2652   /* Reset the tap listeners. */
2653   reset_tap_listeners();
2654
2655   /* Iterate through the list of packets, dissecting all packets and
2656      re-running the taps. */
2657   packet_range_init(&range);
2658   packet_range_process_init(&range);
2659   switch (process_specified_packets(cf, &range, "Recalculating statistics on",
2660                                     "all packets", TRUE, retap_packet,
2661                                     &callback_args)) {
2662   case PSP_FINISHED:
2663     /* Completed successfully. */
2664     return CF_READ_OK;
2665
2666   case PSP_STOPPED:
2667     /* Well, the user decided to abort the refiltering.
2668        Return CF_READ_ABORTED so our caller knows they did that. */
2669     return CF_READ_ABORTED;
2670
2671   case PSP_FAILED:
2672     /* Error while retapping. */
2673     return CF_READ_ERROR;
2674   }
2675
2676   g_assert_not_reached();
2677   return CF_READ_OK;
2678 }
2679
2680 typedef struct {
2681   print_args_t *print_args;
2682   gboolean      print_header_line;
2683   char         *header_line_buf;
2684   int           header_line_buf_len;
2685   gboolean      print_formfeed;
2686   gboolean      print_separator;
2687   char         *line_buf;
2688   int           line_buf_len;
2689   gint         *col_widths;
2690 } print_callback_args_t;
2691
2692 static gboolean
2693 print_packet(capture_file *cf, frame_data *fdata,
2694              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2695              void *argsp)
2696 {
2697   print_callback_args_t *args = argsp;
2698   epan_dissect_t edt;
2699   int             i;
2700   char           *cp;
2701   int             line_len;
2702   int             column_len;
2703   int             cp_off;
2704   gboolean        proto_tree_needed;
2705   char            bookmark_name[9+10+1];    /* "__frameNNNNNNNNNN__\0" */
2706   char            bookmark_title[6+10+1];   /* "Frame NNNNNNNNNN__\0" */
2707
2708   /* Create the protocol tree, and make it visible, if we're printing
2709      the dissection or the hex data.
2710      XXX - do we need it if we're just printing the hex data? */
2711   proto_tree_needed =
2712       args->print_args->print_dissections != print_dissections_none || args->print_args->print_hex || have_custom_cols(&cf->cinfo);
2713   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2714
2715   /* Fill in the column information if we're printing the summary
2716      information. */
2717   if (args->print_args->print_summary) {
2718     epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2719     epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2720   } else
2721     epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2722
2723   if (args->print_formfeed) {
2724     if (!new_page(args->print_args->stream))
2725       goto fail;
2726   } else {
2727       if (args->print_separator) {
2728         if (!print_line(args->print_args->stream, 0, ""))
2729           goto fail;
2730       }
2731   }
2732
2733   /*
2734    * We generate bookmarks, if the output format supports them.
2735    * The name is "__frameN__".
2736    */
2737   g_snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
2738
2739   if (args->print_args->print_summary) {
2740     if (args->print_header_line) {
2741       if (!print_line(args->print_args->stream, 0, args->header_line_buf))
2742         goto fail;
2743       args->print_header_line = FALSE;  /* we might not need to print any more */
2744     }
2745     cp = &args->line_buf[0];
2746     line_len = 0;
2747     for (i = 0; i < cf->cinfo.num_cols; i++) {
2748       /* Find the length of the string for this column. */
2749       column_len = (int) strlen(cf->cinfo.col_data[i]);
2750       if (args->col_widths[i] > column_len)
2751          column_len = args->col_widths[i];
2752
2753       /* Make sure there's room in the line buffer for the column; if not,
2754          double its length. */
2755       line_len += column_len + 1;   /* "+1" for space */
2756       if (line_len > args->line_buf_len) {
2757         cp_off = (int) (cp - args->line_buf);
2758         args->line_buf_len = 2 * line_len;
2759         args->line_buf = g_realloc(args->line_buf, args->line_buf_len + 1);
2760         cp = args->line_buf + cp_off;
2761       }
2762
2763       /* Right-justify the packet number column. */
2764       if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2765         g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], cf->cinfo.col_data[i]);
2766       else
2767         g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], cf->cinfo.col_data[i]);
2768       cp += column_len;
2769       if (i != cf->cinfo.num_cols - 1)
2770         *cp++ = ' ';
2771     }
2772     *cp = '\0';
2773
2774     /*
2775      * Generate a bookmark, using the summary line as the title.
2776      */
2777     if (!print_bookmark(args->print_args->stream, bookmark_name,
2778                         args->line_buf))
2779       goto fail;
2780
2781     if (!print_line(args->print_args->stream, 0, args->line_buf))
2782       goto fail;
2783   } else {
2784     /*
2785      * Generate a bookmark, using "Frame N" as the title, as we're not
2786      * printing the summary line.
2787      */
2788     g_snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
2789     if (!print_bookmark(args->print_args->stream, bookmark_name,
2790                         bookmark_title))
2791       goto fail;
2792   } /* if (print_summary) */
2793
2794   if (args->print_args->print_dissections != print_dissections_none) {
2795     if (args->print_args->print_summary) {
2796       /* Separate the summary line from the tree with a blank line. */
2797       if (!print_line(args->print_args->stream, 0, ""))
2798         goto fail;
2799     }
2800
2801     /* Print the information in that tree. */
2802     if (!proto_tree_print(args->print_args, &edt, args->print_args->stream))
2803       goto fail;
2804
2805     /* Print a blank line if we print anything after this (aka more than one packet). */
2806     args->print_separator = TRUE;
2807
2808     /* Print a header line if we print any more packet summaries */
2809     args->print_header_line = TRUE;
2810   }
2811
2812   if (args->print_args->print_hex) {
2813     /* Print the full packet data as hex. */
2814     if (!print_hex_data(args->print_args->stream, &edt))
2815       goto fail;
2816
2817     /* Print a blank line if we print anything after this (aka more than one packet). */
2818     args->print_separator = TRUE;
2819
2820     /* Print a header line if we print any more packet summaries */
2821     args->print_header_line = TRUE;
2822   } /* if (args->print_args->print_dissections != print_dissections_none) */
2823
2824   epan_dissect_cleanup(&edt);
2825
2826   /* do we want to have a formfeed between each packet from now on? */
2827   if(args->print_args->print_formfeed) {
2828     args->print_formfeed = TRUE;
2829   }
2830
2831   return TRUE;
2832
2833 fail:
2834   epan_dissect_cleanup(&edt);
2835   return FALSE;
2836 }
2837
2838 cf_print_status_t
2839 cf_print_packets(capture_file *cf, print_args_t *print_args)
2840 {
2841   int         i;
2842   print_callback_args_t callback_args;
2843   gint        data_width;
2844   char        *cp;
2845   int         cp_off;
2846   int         column_len;
2847   int         line_len;
2848   psp_return_t ret;
2849
2850   callback_args.print_args = print_args;
2851   callback_args.print_header_line = TRUE;
2852   callback_args.header_line_buf = NULL;
2853   callback_args.header_line_buf_len = 256;
2854   callback_args.print_formfeed = FALSE;
2855   callback_args.print_separator = FALSE;
2856   callback_args.line_buf = NULL;
2857   callback_args.line_buf_len = 256;
2858   callback_args.col_widths = NULL;
2859
2860   if (!print_preamble(print_args->stream, cf->filename)) {
2861     destroy_print_stream(print_args->stream);
2862     return CF_PRINT_WRITE_ERROR;
2863   }
2864
2865   if (print_args->print_summary) {
2866     /* We're printing packet summaries.  Allocate the header line buffer
2867        and get the column widths. */
2868     callback_args.header_line_buf = g_malloc(callback_args.header_line_buf_len + 1);
2869
2870     /* Find the widths for each of the columns - maximum of the
2871        width of the title and the width of the data - and construct
2872        a buffer with a line containing the column titles. */
2873     callback_args.col_widths = (gint *) g_malloc(sizeof(gint) * cf->cinfo.num_cols);
2874     cp = &callback_args.header_line_buf[0];
2875     line_len = 0;
2876     for (i = 0; i < cf->cinfo.num_cols; i++) {
2877       /* Don't pad the last column. */
2878       if (i == cf->cinfo.num_cols - 1)
2879         callback_args.col_widths[i] = 0;
2880       else {
2881         callback_args.col_widths[i] = (gint) strlen(cf->cinfo.col_title[i]);
2882         data_width = get_column_char_width(get_column_format(i));
2883         if (data_width > callback_args.col_widths[i])
2884           callback_args.col_widths[i] = data_width;
2885       }
2886
2887       /* Find the length of the string for this column. */
2888       column_len = (int) strlen(cf->cinfo.col_title[i]);
2889       if (callback_args.col_widths[i] > column_len)
2890         column_len = callback_args.col_widths[i];
2891
2892       /* Make sure there's room in the line buffer for the column; if not,
2893          double its length. */
2894       line_len += column_len + 1;   /* "+1" for space */
2895       if (line_len > callback_args.header_line_buf_len) {
2896         cp_off = (int) (cp - callback_args.header_line_buf);
2897         callback_args.header_line_buf_len = 2 * line_len;
2898         callback_args.header_line_buf = g_realloc(callback_args.header_line_buf,
2899                                                   callback_args.header_line_buf_len + 1);
2900         cp = callback_args.header_line_buf + cp_off;
2901       }
2902
2903       /* Right-justify the packet number column. */
2904 /*      if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2905         g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[i], cf->cinfo.col_title[i]);
2906       else*/
2907       g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[i], cf->cinfo.col_title[i]);
2908       cp += column_len;
2909       if (i != cf->cinfo.num_cols - 1)
2910         *cp++ = ' ';
2911     }
2912     *cp = '\0';
2913
2914     /* Now start out the main line buffer with the same length as the
2915        header line buffer. */
2916     callback_args.line_buf_len = callback_args.header_line_buf_len;
2917     callback_args.line_buf = g_malloc(callback_args.line_buf_len + 1);
2918   } /* if (print_summary) */
2919
2920   /* Iterate through the list of packets, printing the packets we were
2921      told to print. */
2922   ret = process_specified_packets(cf, &print_args->range, "Printing",
2923                                   "selected packets", TRUE, print_packet,
2924                                   &callback_args);
2925
2926   g_free(callback_args.header_line_buf);
2927   g_free(callback_args.line_buf);
2928   g_free(callback_args.col_widths);
2929
2930   switch (ret) {
2931
2932   case PSP_FINISHED:
2933     /* Completed successfully. */
2934     break;
2935
2936   case PSP_STOPPED:
2937     /* Well, the user decided to abort the printing.
2938
2939        XXX - note that what got generated before they did that
2940        will get printed if we're piping to a print program; we'd
2941        have to write to a file and then hand that to the print
2942        program to make it actually not print anything. */
2943     break;
2944
2945   case PSP_FAILED:
2946     /* Error while printing.
2947
2948        XXX - note that what got generated before they did that
2949        will get printed if we're piping to a print program; we'd
2950        have to write to a file and then hand that to the print
2951        program to make it actually not print anything. */
2952     destroy_print_stream(print_args->stream);
2953     return CF_PRINT_WRITE_ERROR;
2954   }
2955
2956   if (!print_finale(print_args->stream)) {
2957     destroy_print_stream(print_args->stream);
2958     return CF_PRINT_WRITE_ERROR;
2959   }
2960
2961   if (!destroy_print_stream(print_args->stream))
2962     return CF_PRINT_WRITE_ERROR;
2963
2964   return CF_PRINT_OK;
2965 }
2966
2967 static gboolean
2968 write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
2969                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2970           void *argsp)
2971 {
2972   FILE *fh = argsp;
2973   epan_dissect_t edt;
2974
2975   /* Create the protocol tree, but don't fill in the column information. */
2976   epan_dissect_init(&edt, TRUE, TRUE);
2977   epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2978
2979   /* Write out the information in that tree. */
2980   proto_tree_write_pdml(&edt, fh);
2981
2982   epan_dissect_cleanup(&edt);
2983
2984   return !ferror(fh);
2985 }
2986
2987 cf_print_status_t
2988 cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
2989 {
2990   FILE        *fh;
2991   psp_return_t ret;
2992
2993   fh = ws_fopen(print_args->file, "w");
2994   if (fh == NULL)
2995     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2996
2997   write_pdml_preamble(fh);
2998   if (ferror(fh)) {
2999     fclose(fh);
3000     return CF_PRINT_WRITE_ERROR;
3001   }
3002
3003   /* Iterate through the list of packets, printing the packets we were
3004      told to print. */
3005   ret = process_specified_packets(cf, &print_args->range, "Writing PDML",
3006                                   "selected packets", TRUE,
3007                                   write_pdml_packet, fh);
3008
3009   switch (ret) {
3010
3011   case PSP_FINISHED:
3012     /* Completed successfully. */
3013     break;
3014
3015   case PSP_STOPPED:
3016     /* Well, the user decided to abort the printing. */
3017     break;
3018
3019   case PSP_FAILED:
3020     /* Error while printing. */
3021     fclose(fh);
3022     return CF_PRINT_WRITE_ERROR;
3023   }
3024
3025   write_pdml_finale(fh);
3026   if (ferror(fh)) {
3027     fclose(fh);
3028     return CF_PRINT_WRITE_ERROR;
3029   }
3030
3031   /* XXX - check for an error */
3032   fclose(fh);
3033
3034   return CF_PRINT_OK;
3035 }
3036
3037 static gboolean
3038 write_psml_packet(capture_file *cf, frame_data *fdata,
3039                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
3040           void *argsp)
3041 {
3042   FILE *fh = argsp;
3043   epan_dissect_t edt;
3044   gboolean proto_tree_needed;
3045
3046   /* Fill in the column information, only create the protocol tree
3047      if having custom columns. */
3048   proto_tree_needed = have_custom_cols(&cf->cinfo);
3049   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
3050   epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
3051   epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
3052
3053   /* Write out the information in that tree. */
3054   proto_tree_write_psml(&edt, fh);
3055
3056   epan_dissect_cleanup(&edt);
3057
3058   return !ferror(fh);
3059 }
3060
3061 cf_print_status_t
3062 cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
3063 {
3064   FILE        *fh;
3065   psp_return_t ret;
3066
3067   fh = ws_fopen(print_args->file, "w");
3068   if (fh == NULL)
3069     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
3070
3071   write_psml_preamble(fh);
3072   if (ferror(fh)) {
3073     fclose(fh);
3074     return CF_PRINT_WRITE_ERROR;
3075   }
3076
3077   /* Iterate through the list of packets, printing the packets we were
3078      told to print. */
3079   ret = process_specified_packets(cf, &print_args->range, "Writing PSML",
3080                                   "selected packets", TRUE,
3081                                   write_psml_packet, fh);
3082
3083   switch (ret) {
3084
3085   case PSP_FINISHED:
3086     /* Completed successfully. */
3087     break;
3088
3089   case PSP_STOPPED:
3090     /* Well, the user decided to abort the printing. */
3091     break;
3092
3093   case PSP_FAILED:
3094     /* Error while printing. */
3095     fclose(fh);
3096     return CF_PRINT_WRITE_ERROR;
3097   }
3098
3099   write_psml_finale(fh);
3100   if (ferror(fh)) {
3101     fclose(fh);
3102     return CF_PRINT_WRITE_ERROR;
3103   }
3104
3105   /* XXX - check for an error */
3106   fclose(fh);
3107
3108   return CF_PRINT_OK;
3109 }
3110
3111 static gboolean
3112 write_csv_packet(capture_file *cf, frame_data *fdata,
3113                  union wtap_pseudo_header *pseudo_header, const guint8 *pd,
3114                  void *argsp)
3115 {
3116   FILE *fh = argsp;
3117   epan_dissect_t edt;
3118   gboolean proto_tree_needed;
3119
3120   /* Fill in the column information, only create the protocol tree
3121      if having custom columns. */
3122   proto_tree_needed = have_custom_cols(&cf->cinfo);
3123   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
3124   epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
3125   epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
3126
3127   /* Write out the information in that tree. */
3128   proto_tree_write_csv(&edt, fh);
3129
3130   epan_dissect_cleanup(&edt);
3131
3132   return !ferror(fh);
3133 }
3134
3135 cf_print_status_t
3136 cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
3137 {
3138   FILE        *fh;
3139   psp_return_t ret;
3140
3141   fh = ws_fopen(print_args->file, "w");
3142   if (fh == NULL)
3143     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
3144
3145   write_csv_preamble(fh);
3146   if (ferror(fh)) {
3147     fclose(fh);
3148     return CF_PRINT_WRITE_ERROR;
3149   }
3150
3151   /* Iterate through the list of packets, printing the packets we were
3152      told to print. */
3153   ret = process_specified_packets(cf, &print_args->range, "Writing CSV",
3154                                   "selected packets", TRUE,
3155                                   write_csv_packet, fh);
3156
3157   switch (ret) {
3158
3159   case PSP_FINISHED:
3160     /* Completed successfully. */
3161     break;
3162
3163   case PSP_STOPPED:
3164     /* Well, the user decided to abort the printing. */
3165     break;
3166
3167   case PSP_FAILED:
3168     /* Error while printing. */
3169     fclose(fh);
3170     return CF_PRINT_WRITE_ERROR;
3171   }
3172
3173   write_csv_finale(fh);
3174   if (ferror(fh)) {
3175     fclose(fh);
3176     return CF_PRINT_WRITE_ERROR;
3177   }
3178
3179   /* XXX - check for an error */
3180   fclose(fh);
3181
3182   return CF_PRINT_OK;
3183 }
3184
3185 static gboolean
3186 write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
3187              union wtap_pseudo_header *pseudo_header _U_,
3188              const guint8 *pd, void *argsp)
3189 {
3190   FILE *fh = argsp;
3191
3192   proto_tree_write_carrays(pd, fdata->cap_len, fdata->num, fh);
3193   return !ferror(fh);
3194 }
3195
3196 cf_print_status_t
3197 cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
3198 {
3199   FILE        *fh;
3200   psp_return_t ret;
3201
3202   fh = ws_fopen(print_args->file, "w");
3203
3204   if (fh == NULL)
3205     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
3206
3207   write_carrays_preamble(fh);
3208
3209   if (ferror(fh)) {
3210     fclose(fh);
3211     return CF_PRINT_WRITE_ERROR;
3212   }
3213
3214   /* Iterate through the list of packets, printing the packets we were
3215      told to print. */
3216   ret = process_specified_packets(cf, &print_args->range,
3217                   "Writing C Arrays",
3218                   "selected packets", TRUE,
3219                                   write_carrays_packet, fh);
3220   switch (ret) {
3221   case PSP_FINISHED:
3222     /* Completed successfully. */
3223     break;
3224   case PSP_STOPPED:
3225     /* Well, the user decided to abort the printing. */
3226     break;
3227   case PSP_FAILED:
3228     /* Error while printing. */
3229     fclose(fh);
3230     return CF_PRINT_WRITE_ERROR;
3231   }
3232
3233   write_carrays_finale(fh);
3234
3235   if (ferror(fh)) {
3236     fclose(fh);
3237     return CF_PRINT_WRITE_ERROR;
3238   }
3239
3240   fclose(fh);
3241   return CF_PRINT_OK;
3242 }
3243
3244 #ifndef NEW_PACKET_LIST /* This function is not needed with the new packet list */
3245
3246 /* Scan through the packet list and change all columns that use the
3247    "command-line-specified" time stamp format to use the current
3248    value of that format. */
3249 void
3250 cf_change_time_formats(capture_file *cf)
3251 {
3252   int         i;
3253   frame_data *fdata;
3254   progdlg_t  *progbar = NULL;
3255   gboolean    stop_flag;
3256   int         count;
3257   int         row;
3258   float       progbar_val;
3259   GTimeVal    start_time;
3260   gchar       status_str[100];
3261   int         progbar_nextstep;
3262   int         progbar_quantum;
3263   gboolean    sorted_by_frame_column;
3264
3265   /* Adjust timestamp precision if auto is selected */
3266   cf_timestamp_auto_precision(cf);
3267
3268   /* Are there any columns with time stamps in the "command-line-specified"
3269      format?
3270
3271      XXX - we have to force the "column is writable" flag on, as it
3272      might be off from the last frame that was dissected. */
3273   col_set_writable(&cf->cinfo, TRUE);
3274   if (!check_col(&cf->cinfo, COL_CLS_TIME) &&
3275       !check_col(&cf->cinfo, COL_ABS_TIME) &&
3276       !check_col(&cf->cinfo, COL_ABS_DATE_TIME) &&
3277       !check_col(&cf->cinfo, COL_REL_TIME) &&
3278       !check_col(&cf->cinfo, COL_DELTA_TIME) &&
3279       !check_col(&cf->cinfo, COL_DELTA_TIME_DIS)) {
3280     /* No, there aren't any columns in that format, so we have no work
3281        to do. */
3282     return;
3283   }
3284
3285   /* Freeze the packet list while we redo it, so we don't get any
3286      screen updates while it happens. */
3287   packet_list_freeze();
3288
3289   /* Update the progress bar when it gets to this value. */
3290   progbar_nextstep = 0;
3291   /* When we reach the value that triggers a progress bar update,
3292      bump that value by this amount. */
3293   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3294   /* Count of packets at which we've looked. */
3295   count = 0;
3296   /* Progress so far. */
3297   progbar_val = 0.0f;
3298
3299   /*  If the rows are currently sorted by the frame column then we know
3300    *  the row number of each packet: it's the row number of the previously
3301    *  displayed packet + 1.
3302    *
3303    *  Otherwise, if the display is sorted by a different column then we have
3304    *  to use the O(N) packet_list_find_row_from_data() (thus making the job
3305    *  of changing the time display format O(N**2)).
3306    *
3307    *  (XXX - In fact it's still O(N**2) because gtk_clist_set_text() takes
3308    *  the row number and walks that many elements down the clist to find
3309    *  the appropriate element.)
3310    */
3311   sorted_by_frame_column = FALSE;
3312   for (i = 0; i < cf->cinfo.num_cols; i++) {
3313     if (cf->cinfo.col_fmt[i] == COL_NUMBER)
3314     {
3315       sorted_by_frame_column = (i == packet_list_get_sort_column());
3316       break;
3317     }
3318   }
3319
3320   stop_flag = FALSE;
3321   g_get_current_time(&start_time);
3322
3323   /* Iterate through the list of packets, checking whether the packet
3324      is in a row of the summary list and, if so, whether there are
3325      any columns that show the time in the "command-line-specified"
3326      format and, if so, update that row. */
3327   for (fdata = cf->plist, row = -1; fdata != NULL; fdata = fdata->next) {
3328     /* Create the progress bar if necessary.
3329        We check on every iteration of the loop, so that it takes no
3330        longer than the standard time to create it (otherwise, for a
3331        large file, we might take considerably longer than that standard
3332        time in order to get to the next progress bar step). */
3333     if (progbar == NULL)
3334       progbar = delayed_create_progress_dlg("Changing", "time display",
3335         TRUE, &stop_flag, &start_time, progbar_val);
3336
3337     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3338        when we update it, we have to run the GTK+ main loop to get it
3339        to repaint what's pending, and doing so may involve an "ioctl()"
3340        to see if there's any pending input from an X server, and doing
3341        that for every packet can be costly, especially on a big file. */
3342     if (count >= progbar_nextstep) {
3343       /* let's not divide by zero. I should never be started
3344        * with count == 0, so let's assert that
3345        */
3346       g_assert(cf->count > 0);
3347
3348       progbar_val = (gfloat) count / cf->count;
3349
3350       if (progbar != NULL) {
3351         g_snprintf(status_str, sizeof(status_str),
3352                    "%4u of %u packets", count, cf->count);
3353         update_progress_dlg(progbar, progbar_val, status_str);
3354       }
3355
3356       progbar_nextstep += progbar_quantum;
3357     }
3358
3359     if (stop_flag) {
3360       /* Well, the user decided to abort the redisplay.  Just stop.
3361
3362          XXX - this leaves the time field in the old format in
3363      frames we haven't yet processed.  So it goes; should we
3364      simply not offer them the option of stopping? */
3365       break;
3366     }
3367
3368     count++;
3369
3370     /* Find what row this packet is in. */
3371     if (!sorted_by_frame_column) {
3372       /* This function is O(N), so we try to avoid using it... */
3373       row = packet_list_find_row_from_data(fdata);
3374     } else {
3375       /* ...which we do by maintaining a count of packets that are
3376          being displayed (i.e., that have passed the display filter),
3377          and using the current value of that count as the row number
3378          (which is why we can only do it when the display is sorted
3379          by the frame number). */
3380       if (fdata->flags.passed_dfilter)
3381         row++;
3382       else
3383         continue;
3384     }
3385
3386     if (row != -1) {
3387       /* This packet is in the summary list, on row "row". */
3388
3389       for (i = 0; i < cf->cinfo.num_cols; i++) {
3390         if (col_has_time_fmt(&cf->cinfo, i)) {
3391           /* This is one of the columns that shows the time in
3392              "command-line-specified" format; update it. */
3393           cf->cinfo.col_buf[i][0] = '\0';
3394           col_set_fmt_time(fdata, &cf->cinfo, cf->cinfo.col_fmt[i], i);
3395           packet_list_set_text(row, i, cf->cinfo.col_data[i]);
3396         }
3397       }
3398     }
3399   }
3400
3401   /* We're done redisplaying the packets; destroy the progress bar if it
3402      was created. */
3403   if (progbar != NULL)
3404     destroy_progress_dlg(progbar);
3405
3406   /* Set the column widths of those columns that show the time in
3407      "command-line-specified" format. */
3408   for (i = 0; i < cf->cinfo.num_cols; i++) {
3409     if (col_has_time_fmt(&cf->cinfo, i)) {
3410       packet_list_set_time_width(cf->cinfo.col_fmt[i], i);
3411     }
3412   }
3413
3414   /* Unfreeze the packet list. */
3415   packet_list_thaw();
3416 }
3417 #endif /* NEW_PACKET_LIST */
3418
3419
3420 typedef struct {
3421     const char  *string;
3422     size_t      string_len;
3423     capture_file    *cf;
3424     gboolean    frame_matched;
3425 } match_data;
3426
3427 gboolean
3428 cf_find_packet_protocol_tree(capture_file *cf, const char *string)
3429 {
3430   match_data        mdata;
3431
3432   mdata.string = string;
3433   mdata.string_len = strlen(string);
3434   return find_packet(cf, match_protocol_tree, &mdata);
3435 }
3436
3437 static gboolean
3438 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
3439 {
3440   match_data        *mdata = criterion;
3441   epan_dissect_t    edt;
3442
3443   /* Construct the protocol tree, including the displayed text */
3444   epan_dissect_init(&edt, TRUE, TRUE);
3445   /* We don't need the column information */
3446   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
3447
3448   /* Iterate through all the nodes, seeing if they have text that matches. */
3449   mdata->cf = cf;
3450   mdata->frame_matched = FALSE;
3451   proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
3452   epan_dissect_cleanup(&edt);
3453   return mdata->frame_matched;
3454 }
3455
3456 static void
3457 match_subtree_text(proto_node *node, gpointer data)
3458 {
3459   match_data    *mdata = (match_data*) data;
3460   const gchar   *string = mdata->string;
3461   size_t    string_len = mdata->string_len;
3462   capture_file  *cf = mdata->cf;
3463   field_info    *fi = PNODE_FINFO(node);
3464   gchar     label_str[ITEM_LABEL_LENGTH];
3465   gchar     *label_ptr;
3466   size_t    label_len;
3467   guint32   i;
3468   guint8    c_char;
3469   size_t    c_match = 0;
3470
3471   g_assert(fi && "dissection with an invisible proto tree?");
3472
3473   if (mdata->frame_matched) {
3474     /* We already had a match; don't bother doing any more work. */
3475     return;
3476   }
3477
3478   /* Don't match invisible entries. */
3479   if (PROTO_ITEM_IS_HIDDEN(node))
3480     return;
3481
3482   /* was a free format label produced? */
3483   if (fi->rep) {
3484     label_ptr = fi->rep->representation;
3485   } else {
3486     /* no, make a generic label */
3487     label_ptr = label_str;
3488     proto_item_fill_label(fi, label_str);
3489   }
3490
3491   /* Does that label match? */
3492   label_len = strlen(label_ptr);
3493   for (i = 0; i < label_len; i++) {
3494     c_char = label_ptr[i];
3495     if (cf->case_type)
3496       c_char = toupper(c_char);
3497     if (c_char == string[c_match]) {
3498       c_match++;
3499       if (c_match == string_len) {
3500     /* No need to look further; we have a match */
3501     mdata->frame_matched = TRUE;
3502     return;
3503       }
3504     } else
3505       c_match = 0;
3506   }
3507
3508   /* Recurse into the subtree, if it exists */
3509   if (node->first_child != NULL)
3510     proto_tree_children_foreach(node, match_subtree_text, mdata);
3511 }
3512
3513 gboolean
3514 cf_find_packet_summary_line(capture_file *cf, const char *string)
3515 {
3516   match_data        mdata;
3517
3518   mdata.string = string;
3519   mdata.string_len = strlen(string);
3520   return find_packet(cf, match_summary_line, &mdata);
3521 }
3522
3523 static gboolean
3524 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
3525 {
3526   match_data        *mdata = criterion;
3527   const gchar       *string = mdata->string;
3528   size_t        string_len = mdata->string_len;
3529   epan_dissect_t    edt;
3530   const char        *info_column;
3531   size_t        info_column_len;
3532   gboolean      frame_matched = FALSE;
3533   gint          colx;
3534   guint32       i;
3535   guint8        c_char;
3536   size_t        c_match = 0;
3537
3538   /* Don't bother constructing the protocol tree */
3539   epan_dissect_init(&edt, FALSE, FALSE);
3540   /* Get the column information */
3541   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, &cf->cinfo);
3542
3543   /* Find the Info column */
3544   for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
3545     if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
3546       /* Found it.  See if we match. */
3547       info_column = edt.pi.cinfo->col_data[colx];
3548       info_column_len = strlen(info_column);
3549       for (i = 0; i < info_column_len; i++) {
3550     c_char = info_column[i];
3551     if (cf->case_type)
3552       c_char = toupper(c_char);
3553     if (c_char == string[c_match]) {
3554       c_match++;
3555       if (c_match == string_len) {
3556         frame_matched = TRUE;
3557         break;
3558       }
3559     } else
3560       c_match = 0;
3561       }
3562       break;
3563     }
3564   }
3565   epan_dissect_cleanup(&edt);
3566   return frame_matched;
3567 }
3568
3569 typedef struct {
3570     const guint8 *data;
3571     size_t data_len;
3572 } cbs_t;    /* "Counted byte string" */
3573
3574 gboolean
3575 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size)
3576 {
3577   cbs_t info;
3578
3579   info.data = string;
3580   info.data_len = string_size;
3581
3582   /* String or hex search? */
3583   if (cf->string) {
3584     /* String search - what type of string? */
3585     switch (cf->scs_type) {
3586
3587     case SCS_ASCII_AND_UNICODE:
3588       return find_packet(cf, match_ascii_and_unicode, &info);
3589
3590     case SCS_ASCII:
3591       return find_packet(cf, match_ascii, &info);
3592
3593     case SCS_UNICODE:
3594       return find_packet(cf, match_unicode, &info);
3595
3596     default:
3597       g_assert_not_reached();
3598       return FALSE;
3599     }
3600   } else
3601     return find_packet(cf, match_binary, &info);
3602 }
3603
3604 static gboolean
3605 match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3606 {
3607   cbs_t     *info = criterion;
3608   const guint8  *ascii_text = info->data;
3609   size_t    textlen = info->data_len;
3610   gboolean  frame_matched;
3611   guint32   buf_len;
3612   guint32   i;
3613   guint8    c_char;
3614   size_t    c_match = 0;
3615
3616   frame_matched = FALSE;
3617   buf_len = fdata->pkt_len;
3618   for (i = 0; i < buf_len; i++) {
3619     c_char = cf->pd[i];
3620     if (cf->case_type)
3621       c_char = toupper(c_char);
3622     if (c_char != 0) {
3623       if (c_char == ascii_text[c_match]) {
3624     c_match++;
3625     if (c_match == textlen) {
3626       frame_matched = TRUE;
3627       cf->search_pos = i; /* Save the position of the last character
3628                    for highlighting the field. */
3629       break;
3630     }
3631       } else
3632     c_match = 0;
3633     }
3634   }
3635   return frame_matched;
3636 }
3637
3638 static gboolean
3639 match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
3640 {
3641   cbs_t     *info = criterion;
3642   const guint8  *ascii_text = info->data;
3643   size_t    textlen = info->data_len;
3644   gboolean  frame_matched;
3645   guint32   buf_len;
3646   guint32   i;
3647   guint8    c_char;
3648   size_t    c_match = 0;
3649
3650   frame_matched = FALSE;
3651   buf_len = fdata->pkt_len;
3652   for (i = 0; i < buf_len; i++) {
3653     c_char = cf->pd[i];
3654     if (cf->case_type)
3655       c_char = toupper(c_char);
3656     if (c_char == ascii_text[c_match]) {
3657       c_match++;
3658       if (c_match == textlen) {
3659     frame_matched = TRUE;
3660     cf->search_pos = i; /* Save the position of the last character
3661                    for highlighting the field. */
3662     break;
3663       }
3664     } else
3665       c_match = 0;
3666   }
3667   return frame_matched;
3668 }
3669
3670 static gboolean
3671 match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3672 {
3673   cbs_t     *info = criterion;
3674   const guint8  *ascii_text = info->data;
3675   size_t    textlen = info->data_len;
3676   gboolean  frame_matched;
3677   guint32   buf_len;
3678   guint32   i;
3679   guint8    c_char;
3680   size_t    c_match = 0;
3681
3682   frame_matched = FALSE;
3683   buf_len = fdata->pkt_len;
3684   for (i = 0; i < buf_len; i++) {
3685     c_char = cf->pd[i];
3686     if (cf->case_type)
3687       c_char = toupper(c_char);
3688     if (c_char == ascii_text[c_match]) {
3689       c_match++;
3690       i++;
3691       if (c_match == textlen) {
3692     frame_matched = TRUE;
3693     cf->search_pos = i; /* Save the position of the last character
3694                    for highlighting the field. */
3695     break;
3696       }
3697     } else
3698       c_match = 0;
3699   }
3700   return frame_matched;
3701 }
3702
3703 static gboolean
3704 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
3705 {
3706   cbs_t     *info = criterion;
3707   const guint8  *binary_data = info->data;
3708   size_t    datalen = info->data_len;
3709   gboolean  frame_matched;
3710   guint32   buf_len;
3711   guint32   i;
3712   size_t    c_match = 0;
3713
3714   frame_matched = FALSE;
3715   buf_len = fdata->pkt_len;
3716   for (i = 0; i < buf_len; i++) {
3717     if (cf->pd[i] == binary_data[c_match]) {
3718       c_match++;
3719       if (c_match == datalen) {
3720     frame_matched = TRUE;
3721     cf->search_pos = i; /* Save the position of the last character
3722                    for highlighting the field. */
3723     break;
3724       }
3725     } else
3726       c_match = 0;
3727   }
3728   return frame_matched;
3729 }
3730
3731 gboolean
3732 cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode)
3733 {
3734   return find_packet(cf, match_dfilter, sfcode);
3735 }
3736
3737 static gboolean
3738 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
3739 {
3740   dfilter_t     *sfcode = criterion;
3741   epan_dissect_t    edt;
3742   gboolean      frame_matched;
3743
3744   epan_dissect_init(&edt, TRUE, FALSE);
3745   epan_dissect_prime_dfilter(&edt, sfcode);
3746   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
3747   frame_matched = dfilter_apply_edt(sfcode, &edt);
3748   epan_dissect_cleanup(&edt);
3749   return frame_matched;
3750 }
3751
3752 static gboolean
3753 find_packet(capture_file *cf,
3754             gboolean (*match_function)(capture_file *, frame_data *, void *),
3755             void *criterion)
3756 {
3757   frame_data *start_fd;
3758   frame_data *fdata;
3759   frame_data *new_fd = NULL;
3760   progdlg_t  *progbar = NULL;
3761   gboolean    stop_flag;
3762   int         count;
3763   int         err;
3764   gchar      *err_info;
3765   int         row;
3766   float       progbar_val;
3767   GTimeVal    start_time;
3768   gchar       status_str[100];
3769   int         progbar_nextstep;
3770   int         progbar_quantum;
3771   char       *title;
3772
3773   start_fd = cf->current_frame;
3774   if (start_fd != NULL)  {
3775     /* Iterate through the list of packets, starting at the packet we've
3776        picked, calling a routine to run the filter on the packet, see if
3777        it matches, and stop if so.  */
3778     count = 0;
3779     fdata = start_fd;
3780
3781     /* Update the progress bar when it gets to this value. */
3782     progbar_nextstep = 0;
3783     /* When we reach the value that triggers a progress bar update,
3784        bump that value by this amount. */
3785     progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3786     /* Progress so far. */
3787     progbar_val = 0.0f;
3788
3789     stop_flag = FALSE;
3790     g_get_current_time(&start_time);
3791
3792     fdata = start_fd;
3793     title = cf->sfilter?cf->sfilter:"";
3794     for (;;) {
3795       /* Create the progress bar if necessary.
3796          We check on every iteration of the loop, so that it takes no
3797          longer than the standard time to create it (otherwise, for a
3798          large file, we might take considerably longer than that standard
3799          time in order to get to the next progress bar step). */
3800       if (progbar == NULL)
3801          progbar = delayed_create_progress_dlg("Searching", title,
3802            FALSE, &stop_flag, &start_time, progbar_val);
3803
3804       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3805          when we update it, we have to run the GTK+ main loop to get it
3806          to repaint what's pending, and doing so may involve an "ioctl()"
3807          to see if there's any pending input from an X server, and doing
3808          that for every packet can be costly, especially on a big file. */
3809       if (count >= progbar_nextstep) {
3810         /* let's not divide by zero. I should never be started
3811          * with count == 0, so let's assert that
3812          */
3813         g_assert(cf->count > 0);
3814
3815         progbar_val = (gfloat) count / cf->count;
3816
3817         if (progbar != NULL) {
3818           g_snprintf(status_str, sizeof(status_str),
3819                      "%4u of %u packets", count, cf->count);
3820           update_progress_dlg(progbar, progbar_val, status_str);
3821         }
3822
3823         progbar_nextstep += progbar_quantum;
3824       }
3825
3826       if (stop_flag) {
3827         /* Well, the user decided to abort the search.  Go back to the
3828            frame where we started. */
3829         new_fd = start_fd;
3830         break;
3831       }
3832
3833       /* Go past the current frame. */
3834       if (cf->sbackward) {
3835         /* Go on to the previous frame. */
3836         fdata = fdata->prev;
3837         if (fdata == NULL) {
3838           /*
3839            * XXX - other apps have a bit more of a detailed message
3840            * for this, and instead of offering "OK" and "Cancel",
3841            * they offer things such as "Continue" and "Cancel";
3842            * we need an API for popping up alert boxes with
3843            * {Verb} and "Cancel".
3844            */
3845
3846           if (prefs.gui_find_wrap)
3847           {
3848               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3849                             "%sBeginning of capture exceeded!%s\n\n"
3850                             "Search is continued from the end of the capture.",
3851                             simple_dialog_primary_start(), simple_dialog_primary_end());
3852               fdata = cf->plist_end;    /* wrap around */
3853           }
3854           else
3855           {
3856               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3857                             "%sBeginning of capture exceeded!%s\n\n"
3858                             "Try searching forwards.",
3859                             simple_dialog_primary_start(), simple_dialog_primary_end());
3860               fdata = start_fd;        /* stay on previous packet */
3861           }
3862         }
3863       } else {
3864         /* Go on to the next frame. */
3865         fdata = fdata->next;
3866         if (fdata == NULL) {
3867           if (prefs.gui_find_wrap)
3868           {
3869               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3870                             "%sEnd of capture exceeded!%s\n\n"
3871                             "Search is continued from the start of the capture.",
3872                             simple_dialog_primary_start(), simple_dialog_primary_end());
3873               fdata = cf->plist_start;    /* wrap around */
3874           }
3875           else
3876           {
3877               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3878                             "%sEnd of capture exceeded!%s\n\n"
3879                             "Try searching backwards.",
3880                             simple_dialog_primary_start(), simple_dialog_primary_end());
3881               fdata = start_fd;     /* stay on previous packet */
3882           }
3883         }
3884       }
3885
3886       count++;
3887
3888       /* Is this packet in the display? */
3889       if (fdata->flags.passed_dfilter) {
3890         /* Yes.  Load its data. */
3891         if (!wtap_seek_read(cf->wth, fdata->file_off, &cf->pseudo_header,
3892                 cf->pd, fdata->cap_len, &err, &err_info)) {
3893           /* Read error.  Report the error, and go back to the frame
3894              where we started. */
3895           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3896             cf_read_error_message(err, err_info), cf->filename);
3897           new_fd = start_fd;
3898           break;
3899         }
3900
3901     /* Does it match the search criterion? */
3902     if ((*match_function)(cf, fdata, criterion)) {
3903           new_fd = fdata;
3904           break;    /* found it! */
3905         }
3906       }
3907
3908       if (fdata == start_fd) {
3909         /* We're back to the frame we were on originally, and that frame
3910        doesn't match the search filter.  The search failed. */
3911         break;
3912       }
3913     }
3914
3915     /* We're done scanning the packets; destroy the progress bar if it
3916        was created. */
3917     if (progbar != NULL)
3918       destroy_progress_dlg(progbar);
3919   }
3920
3921   if (new_fd != NULL) {
3922 #ifdef NEW_PACKET_LIST
3923       /* Find and select */
3924       row = new_packet_list_find_row_from_data(fdata, TRUE);
3925 #else
3926     /* We found a frame.  Find what row it's in. */
3927     row = packet_list_find_row_from_data(new_fd);
3928 #endif /* NEW_PACKET_LIST */
3929     if (row == -1) {
3930         /* We didn't find a row even though we know that a frame
3931          * exists that satifies the search criteria. This means that the
3932          * frame isn't being displayed currently so we can't select it. */
3933         simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3934                       "%sEnd of capture exceeded!%s\n\n"
3935                       "The capture file is probably not fully loaded.",
3936                       simple_dialog_primary_start(), simple_dialog_primary_end());
3937         return FALSE;
3938     }
3939
3940 #ifndef NEW_PACKET_LIST
3941     /* Select that row, make it the focus row, and make it visible. */
3942     packet_list_set_selected_row(row);
3943 #endif /* NEW_PACKET_LIST */
3944     return TRUE;    /* success */
3945   } else
3946     return FALSE;   /* failure */
3947 }
3948
3949 gboolean
3950 cf_goto_frame(capture_file *cf, guint fnumber)
3951 {
3952   frame_data *fdata;
3953   int row;
3954
3955   for (fdata = cf->plist_start; fdata != NULL && fdata->num < fnumber; fdata = fdata->next)
3956     ;
3957
3958   if (fdata == NULL) {
3959     /* we didn't find a packet with that packet number */
3960     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3961           "There is no packet with the packet number %u.", fnumber);
3962     return FALSE;   /* we failed to go to that packet */
3963   }
3964   if (!fdata->flags.passed_dfilter) {
3965     /* that packet currently isn't displayed */
3966     /* XXX - add it to the set of displayed packets? */
3967     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3968           "The packet number %u isn't currently being displayed.", fnumber);
3969     return FALSE;   /* we failed to go to that packet */
3970   }
3971
3972 #ifdef NEW_PACKET_LIST
3973   row = new_packet_list_find_row_from_data(fdata, TRUE);
3974 #else
3975   /* We found that packet, and it's currently being displayed.
3976      Find what row it's in. */
3977   row = packet_list_find_row_from_data(fdata);
3978   g_assert(row != -1);
3979
3980   /* Select that row, make it the focus row, and make it visible. */
3981   packet_list_set_selected_row(row);
3982 #endif /* NEW_PACKET_LIST */
3983   return TRUE;  /* we got to that packet */
3984 }
3985
3986 gboolean
3987 cf_goto_top_frame(capture_file *cf _U_)
3988 {
3989 #ifdef NEW_PACKET_LIST
3990   /* Find and select */
3991   new_packet_list_select_first_row();
3992 #else
3993   frame_data *fdata;
3994   int row;
3995   frame_data *lowest_fdata = NULL;
3996
3997   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
3998     if (fdata->flags.passed_dfilter) {
3999         lowest_fdata = fdata;
4000         break;
4001     }
4002   }
4003
4004   if (lowest_fdata == NULL) {
4005       return FALSE;
4006   }
4007
4008   /* We found that packet, and it's currently being displayed.
4009      Find what row it's in. */
4010   row = packet_list_find_row_from_data(lowest_fdata);
4011   g_assert(row != -1);
4012
4013   /* Select that row, make it the focus row, and make it visible. */
4014   packet_list_set_selected_row(row);
4015 #endif /* NEW_PACKET_LIST */
4016   return TRUE;  /* we got to that packet */
4017 }
4018
4019 gboolean
4020 cf_goto_bottom_frame(capture_file *cf _U_) /* cf is unused w/ NEW_PACKET_LIST */
4021 {
4022 #ifdef NEW_PACKET_LIST
4023   /* Find and select */
4024   new_packet_list_select_last_row();
4025 #else
4026   frame_data *fdata;
4027   int row;
4028   frame_data *highest_fdata = NULL;
4029
4030   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
4031     if (fdata->flags.passed_dfilter) {
4032         highest_fdata = fdata;
4033     }
4034   }
4035
4036   if (highest_fdata == NULL) {
4037       return FALSE;
4038   }
4039
4040   /* We found that packet, and it's currently being displayed.
4041      Find what row it's in. */
4042   row = packet_list_find_row_from_data(highest_fdata);
4043   g_assert(row != -1);
4044
4045   /* Select that row, make it the focus row, and make it visible. */
4046   packet_list_set_selected_row(row);
4047 #endif /* NEW_PACKET_LIST */
4048   return TRUE;  /* we got to that packet */
4049 }
4050
4051 /*
4052  * Go to frame specified by currently selected protocol tree item.
4053  */
4054 gboolean
4055 cf_goto_framenum(capture_file *cf)
4056 {
4057   header_field_info       *hfinfo;
4058   guint32                 framenum;
4059
4060   if (cf->finfo_selected) {
4061     hfinfo = cf->finfo_selected->hfinfo;
4062     g_assert(hfinfo);
4063     if (hfinfo->type == FT_FRAMENUM) {
4064       framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
4065       if (framenum != 0)
4066         return cf_goto_frame(cf, framenum);
4067       }
4068   }
4069
4070   return FALSE;
4071 }
4072
4073 /* Select the packet on a given row. */
4074 void
4075 cf_select_packet(capture_file *cf, int row)
4076 {
4077   frame_data *fdata;
4078   int err;
4079   gchar *err_info;
4080
4081   /* Get the frame data struct pointer for this frame */
4082 #ifdef NEW_PACKET_LIST
4083   fdata = new_packet_list_get_row_data(row);
4084 #else
4085   fdata = (frame_data *)packet_list_get_row_data(row);
4086 #endif
4087
4088   if (fdata == NULL) {
4089     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
4090        the first entry is added to it by "real_insert_row()", that row
4091        is selected (see "real_insert_row()", in "gtk/gtkclist.c", in both
4092        our version and the vanilla GTK+ version).
4093
4094        This means that a "select-row" signal is emitted; this causes
4095        "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
4096        to be called.
4097
4098        "cf_select_packet()" fetches, above, the data associated with the
4099        row that was selected; however, as "gtk_clist_append()", which
4100        called "real_insert_row()", hasn't yet returned, we haven't yet
4101        associated any data with that row, so we get back a null pointer.
4102
4103        We can't assume that there's only one frame in the frame list,
4104        either, as we may be filtering the display.
4105
4106        We therefore assume that, if "row" is 0, i.e. the first row
4107        is being selected, and "cf->first_displayed" equals
4108        "cf->last_displayed", i.e. there's only one frame being
4109        displayed, that frame is the frame we want.
4110
4111        This means we have to set "cf->first_displayed" and
4112        "cf->last_displayed" before adding the row to the
4113        GtkCList; see the comment in "add_packet_to_packet_list()". */
4114
4115        if (row == 0 && cf->first_displayed == cf->last_displayed)
4116          fdata = cf->first_displayed;
4117   }
4118
4119   /* If fdata _still_ isn't set simply give up. */
4120   if (fdata == NULL) {
4121     return;
4122   }
4123
4124   /* Get the data in that frame. */
4125   if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
4126                cf->pd, fdata->cap_len, &err, &err_info)) {
4127     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4128           cf_read_error_message(err, err_info), cf->filename);
4129     return;
4130   }
4131
4132   /* Record that this frame is the current frame. */
4133   cf->current_frame = fdata;
4134   cf->current_row = row;
4135
4136   /* Create the logical protocol tree. */
4137   if (cf->edt != NULL)
4138     epan_dissect_free(cf->edt);
4139
4140   /* We don't need the columns here. */
4141   cf->edt = epan_dissect_new(TRUE, TRUE);
4142
4143   epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
4144           NULL);
4145
4146   dfilter_macro_build_ftv_cache(cf->edt->tree);
4147
4148   cf_callback_invoke(cf_cb_packet_selected, cf);
4149 }
4150
4151 /* Unselect the selected packet, if any. */
4152 void
4153 cf_unselect_packet(capture_file *cf)
4154 {
4155   /* Destroy the epan_dissect_t for the unselected packet. */
4156   if (cf->edt != NULL) {
4157     epan_dissect_free(cf->edt);
4158     cf->edt = NULL;
4159   }
4160
4161   /* No packet is selected. */
4162   cf->current_frame = NULL;
4163   cf->current_row = 0;
4164
4165   cf_callback_invoke(cf_cb_packet_unselected, cf);
4166
4167   /* No protocol tree means no selected field. */
4168   cf_unselect_field(cf);
4169 }
4170
4171 /* Unset the selected protocol tree field, if any. */
4172 void
4173 cf_unselect_field(capture_file *cf)
4174 {
4175   cf->finfo_selected = NULL;
4176
4177   cf_callback_invoke(cf_cb_field_unselected, cf);
4178 }
4179
4180 /*
4181  * Mark a particular frame.
4182  */
4183 void
4184 cf_mark_frame(capture_file *cf, frame_data *frame)
4185 {
4186   if (! frame->flags.marked) {
4187     frame->flags.marked = TRUE;
4188     if (cf->count > cf->marked_count)
4189       cf->marked_count++;
4190   }
4191 }
4192
4193 /*
4194  * Unmark a particular frame.
4195  */
4196 void
4197 cf_unmark_frame(capture_file *cf, frame_data *frame)
4198 {
4199   if (frame->flags.marked) {
4200     frame->flags.marked = FALSE;
4201     if (cf->marked_count > 0)
4202       cf->marked_count--;
4203   }
4204 }
4205
4206 typedef struct {
4207   wtap_dumper *pdh;
4208   const char  *fname;
4209 } save_callback_args_t;
4210
4211 /*
4212  * Save a capture to a file, in a particular format, saving either
4213  * all packets, all currently-displayed packets, or all marked packets.
4214  *
4215  * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
4216  * up a message box for the failure.
4217  */
4218 static gboolean
4219 save_packet(capture_file *cf _U_, frame_data *fdata,
4220             union wtap_pseudo_header *pseudo_header, const guint8 *pd,
4221             void *argsp)
4222 {
4223   save_callback_args_t *args = argsp;
4224   struct wtap_pkthdr hdr;
4225   int           err;
4226
4227   /* init the wtap header for saving */
4228   hdr.ts.secs    = fdata->abs_ts.secs;
4229   hdr.ts.nsecs   = fdata->abs_ts.nsecs;
4230   hdr.caplen     = fdata->cap_len;
4231   hdr.len        = fdata->pkt_len;
4232   hdr.pkt_encap  = fdata->lnk_t;
4233
4234   /* and save the packet */
4235   if (!wtap_dump(args->pdh, &hdr, pseudo_header, pd, &err)) {
4236     cf_write_failure_alert_box(args->fname, err);
4237     return FALSE;
4238   }
4239   return TRUE;
4240 }
4241
4242 /*
4243  * Can this capture file be saved in any format except by copying the raw data?
4244  */
4245 gboolean
4246 cf_can_save_as(capture_file *cf)
4247 {
4248   int ft;
4249
4250   for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
4251     /* To save a file with Wiretap, Wiretap has to handle that format,
4252        and its code to handle that format must be able to write a file
4253        with this file's encapsulation type. */
4254     if (wtap_dump_can_open(ft) && wtap_dump_can_write_encap(ft, cf->lnk_t)) {
4255       /* OK, we can write it out in this type. */
4256       return TRUE;
4257     }
4258   }
4259
4260   /* No, we couldn't save it in any format. */
4261   return FALSE;
4262 }
4263
4264 cf_status_t
4265 cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_format, gboolean compressed)
4266 {
4267   gchar        *from_filename;
4268   int           err;
4269   gboolean      do_copy;
4270   wtap_dumper  *pdh;
4271   save_callback_args_t callback_args;
4272
4273   cf_callback_invoke(cf_cb_file_safe_started, (gpointer) fname);
4274
4275   /* don't write over an existing file. */
4276   /* this should've been already checked by our caller, just to be sure... */
4277   if (file_exists(fname)) {
4278     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4279       "%sCapture file: \"%s\" already exists!%s\n\n"
4280       "Please choose a different filename.",
4281       simple_dialog_primary_start(), fname, simple_dialog_primary_end());
4282     goto fail;
4283   }
4284
4285   packet_range_process_init(range);
4286
4287
4288   if (packet_range_process_all(range) && save_format == cf->cd_t) {
4289     /* We're not filtering packets, and we're saving it in the format
4290        it's already in, so we can just move or copy the raw data. */
4291
4292     if (cf->is_tempfile) {
4293       /* The file being saved is a temporary file from a live
4294          capture, so it doesn't need to stay around under that name;
4295      first, try renaming the capture buffer file to the new name. */
4296 #ifndef _WIN32
4297       if (ws_rename(cf->filename, fname) == 0) {
4298         /* That succeeded - there's no need to copy the source file. */
4299         from_filename = NULL;
4300     do_copy = FALSE;
4301       } else {
4302         if (errno == EXDEV) {
4303       /* They're on different file systems, so we have to copy the
4304          file. */
4305       do_copy = TRUE;
4306           from_filename = cf->filename;
4307     } else {
4308       /* The rename failed, but not because they're on different
4309          file systems - put up an error message.  (Or should we
4310          just punt and try to copy?  The only reason why I'd
4311          expect the rename to fail and the copy to succeed would
4312          be if we didn't have permission to remove the file from
4313          the temporary directory, and that might be fixable - but
4314          is it worth requiring the user to go off and fix it?) */
4315       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4316                 file_rename_error_message(errno), fname);
4317       goto fail;
4318     }
4319       }
4320 #else
4321       do_copy = TRUE;
4322       from_filename = cf->filename;
4323 #endif
4324     } else {
4325       /* It's a permanent file, so we should copy it, and not remove the
4326          original. */
4327       do_copy = TRUE;
4328       from_filename = cf->filename;
4329     }
4330
4331     if (do_copy) {
4332       /* Copy the file, if we haven't moved it. */
4333       if (!copy_file_binary_mode(from_filename, fname))
4334     goto fail;
4335     }
4336   } else {
4337     /* Either we're filtering packets, or we're saving in a different
4338        format; we can't do that by copying or moving the capture file,
4339        we have to do it by writing the packets out in Wiretap. */
4340     pdh = wtap_dump_open(fname, save_format, cf->lnk_t, cf->snap,
4341         compressed, &err);
4342     if (pdh == NULL) {
4343       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4344       goto fail;
4345     }
4346
4347     /* XXX - we let the user save a subset of the packets.
4348
4349        If we do that, should we make that file the current file?  If so,
4350        it means we can no longer get at the other packets.  What does
4351        NetMon do? */
4352
4353     /* Iterate through the list of packets, processing the packets we were
4354        told to process.
4355
4356        XXX - we've already called "packet_range_process_init(range)", but
4357        "process_specified_packets()" will do it again.  Fortunately,
4358        that's harmless in this case, as we haven't done anything to
4359        "range" since we initialized it. */
4360     callback_args.pdh = pdh;
4361     callback_args.fname = fname;
4362     switch (process_specified_packets(cf, range, "Saving", "selected packets",
4363                                       TRUE, save_packet, &callback_args)) {
4364
4365     case PSP_FINISHED:
4366       /* Completed successfully. */
4367       break;
4368
4369     case PSP_STOPPED:
4370       /* The user decided to abort the saving.
4371          XXX - remove the output file? */
4372       break;
4373
4374     case PSP_FAILED:
4375       /* Error while saving. */
4376       wtap_dump_close(pdh, &err);
4377       goto fail;
4378     }
4379
4380     if (!wtap_dump_close(pdh, &err)) {
4381       cf_close_failure_alert_box(fname, err);
4382       goto fail;
4383     }
4384   }
4385
4386   cf_callback_invoke(cf_cb_file_safe_finished, NULL);
4387
4388   if (packet_range_process_all(range)) {
4389     /* We saved the entire capture, not just some packets from it.
4390        Open and read the file we saved it to.
4391
4392        XXX - this is somewhat of a waste; we already have the
4393        packets, all this gets us is updated file type information
4394        (which we could just stuff into "cf"), and having the new
4395        file be the one we have opened and from which we're reading
4396        the data, and it means we have to spend time opening and
4397        reading the file, which could be a significant amount of
4398        time if the file is large. */
4399     cf->user_saved = TRUE;
4400
4401     if ((cf_open(cf, fname, FALSE, &err)) == CF_OK) {
4402       /* XXX - report errors if this fails?
4403          What should we return if it fails or is aborted? */
4404       switch (cf_read(cf)) {
4405
4406       case CF_READ_OK:
4407       case CF_READ_ERROR:
4408     /* Just because we got an error, that doesn't mean we were unable
4409        to read any of the file; we handle what we could get from the
4410        file. */
4411     break;
4412
4413       case CF_READ_ABORTED:
4414     /* The user bailed out of re-reading the capture file; the
4415        capture file has been closed - just return (without
4416        changing any menu settings; "cf_close()" set them
4417        correctly for the "no capture file open" state). */
4418     break;
4419       }
4420       cf_callback_invoke(cf_cb_file_safe_reload_finished, NULL);
4421     }
4422   }
4423   return CF_OK;
4424
4425 fail:
4426   cf_callback_invoke(cf_cb_file_safe_failed, NULL);
4427   return CF_ERROR;
4428 }
4429
4430 static void
4431 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
4432                           gboolean for_writing, int file_type)
4433 {
4434   if (err < 0) {
4435     /* Wiretap error. */
4436     switch (err) {
4437
4438     case WTAP_ERR_NOT_REGULAR_FILE:
4439       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4440             "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
4441             filename);
4442       break;
4443
4444     case WTAP_ERR_RANDOM_OPEN_PIPE:
4445       /* Seen only when opening a capture file for reading. */
4446       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4447             "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.",
4448             filename);
4449       break;
4450
4451     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
4452       /* Seen only when opening a capture file for reading. */
4453       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4454             "The file \"%s\" isn't a capture file in a format Wireshark understands.",
4455             filename);
4456       break;
4457
4458     case WTAP_ERR_UNSUPPORTED:
4459       /* Seen only when opening a capture file for reading. */
4460       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4461             "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
4462             "(%s)",
4463             filename, err_info);
4464       g_free(err_info);
4465       break;
4466
4467     case WTAP_ERR_CANT_WRITE_TO_PIPE:
4468       /* Seen only when opening a capture file for writing. */
4469       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4470             "The file \"%s\" is a pipe, and %s capture files can't be "
4471             "written to a pipe.",
4472             filename, wtap_file_type_string(file_type));
4473       break;
4474
4475     case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
4476       /* Seen only when opening a capture file for writing. */
4477       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4478             "Wireshark doesn't support writing capture files in that format.");
4479       break;
4480
4481     case WTAP_ERR_UNSUPPORTED_ENCAP:
4482       if (for_writing) {
4483     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4484               "Wireshark can't save this capture in that format.");
4485       } else {
4486     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4487               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
4488               "(%s)",
4489               filename, err_info);
4490         g_free(err_info);
4491       }
4492       break;
4493
4494     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
4495       if (for_writing) {
4496     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4497               "Wireshark can't save this capture in that format.");
4498       } else {
4499     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4500               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
4501               filename);
4502       }
4503       break;
4504
4505     case WTAP_ERR_BAD_RECORD:
4506       /* Seen only when opening a capture file for reading. */
4507       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4508             "The file \"%s\" appears to be damaged or corrupt.\n"
4509             "(%s)",
4510             filename, err_info);
4511       g_free(err_info);
4512       break;
4513
4514     case WTAP_ERR_CANT_OPEN:
4515       if (for_writing) {
4516     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4517               "The file \"%s\" could not be created for some unknown reason.",
4518               filename);
4519       } else {
4520     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4521               "The file \"%s\" could not be opened for some unknown reason.",
4522               filename);
4523       }
4524       break;
4525
4526     case WTAP_ERR_SHORT_READ:
4527       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4528             "The file \"%s\" appears to have been cut short"
4529             " in the middle of a packet or other data.",
4530             filename);
4531       break;
4532
4533     case WTAP_ERR_SHORT_WRITE:
4534       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4535             "A full header couldn't be written to the file \"%s\".",
4536             filename);
4537       break;
4538
4539     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
4540       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4541             "Gzip compression not supported by this file type.");
4542       break;
4543
4544     default:
4545       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4546             "The file \"%s\" could not be %s: %s.",
4547             filename,
4548             for_writing ? "created" : "opened",
4549             wtap_strerror(err));
4550       break;
4551     }
4552   } else {
4553     /* OS error. */
4554     open_failure_alert_box(filename, err, for_writing);
4555   }
4556 }
4557
4558 static const char *
4559 file_rename_error_message(int err)
4560 {
4561   const char *errmsg;
4562   static char errmsg_errno[1024+1];
4563
4564   switch (err) {
4565
4566   case ENOENT:
4567     errmsg = "The path to the file \"%s\" doesn't exist.";
4568     break;
4569
4570   case EACCES:
4571     errmsg = "You don't have permission to move the capture file to \"%s\".";
4572     break;
4573
4574   default:
4575     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4576             "The file \"%%s\" could not be moved: %s.",
4577                 wtap_strerror(err));
4578     errmsg = errmsg_errno;
4579     break;
4580   }
4581   return errmsg;
4582 }
4583
4584 char *
4585 cf_read_error_message(int err, gchar *err_info)
4586 {
4587   static char errmsg_errno[1024+1];
4588
4589   switch (err) {
4590
4591   case WTAP_ERR_UNSUPPORTED_ENCAP:
4592     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4593                "The file \"%%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
4594                err_info);
4595     g_free(err_info);
4596     break;
4597
4598   case WTAP_ERR_BAD_RECORD:
4599     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4600          "An error occurred while reading from the file \"%%s\": %s.\n(%s)",
4601          wtap_strerror(err), err_info);
4602     g_free(err_info);
4603     break;
4604
4605   default:
4606     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4607          "An error occurred while reading from the file \"%%s\": %s.",
4608          wtap_strerror(err));
4609     break;
4610   }
4611   return errmsg_errno;
4612 }
4613
4614 static void
4615 cf_write_failure_alert_box(const char *filename, int err)
4616 {
4617   if (err < 0) {
4618     /* Wiretap error. */
4619     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4620           "An error occurred while writing to the file \"%s\": %s.",
4621           filename, wtap_strerror(err));
4622   } else {
4623     /* OS error. */
4624     write_failure_alert_box(filename, err);
4625   }
4626 }
4627
4628 /* Check for write errors - if the file is being written to an NFS server,
4629    a write error may not show up until the file is closed, as NFS clients
4630    might not send writes to the server until the "write()" call finishes,
4631    so that the write may fail on the server but the "write()" may succeed. */
4632 static void
4633 cf_close_failure_alert_box(const char *filename, int err)
4634 {
4635   if (err < 0) {
4636     /* Wiretap error. */
4637     switch (err) {
4638
4639     case WTAP_ERR_CANT_CLOSE:
4640       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4641             "The file \"%s\" couldn't be closed for some unknown reason.",
4642             filename);
4643       break;
4644
4645     case WTAP_ERR_SHORT_WRITE:
4646       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4647             "Not all the packets could be written to the file \"%s\".",
4648                     filename);
4649       break;
4650
4651     default:
4652       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4653             "An error occurred while closing the file \"%s\": %s.",
4654             filename, wtap_strerror(err));
4655       break;
4656     }
4657   } else {
4658     /* OS error.
4659        We assume that a close error from the OS is really a write error. */
4660     write_failure_alert_box(filename, err);
4661   }
4662 }
4663
4664 /* Reload the current capture file. */
4665 void
4666 cf_reload(capture_file *cf) {
4667   gchar *filename;
4668   gboolean is_tempfile;
4669   int err;
4670
4671   /* If the file could be opened, "cf_open()" calls "cf_close()"
4672      to get rid of state for the old capture file before filling in state
4673      for the new capture file.  "cf_close()" will remove the file if
4674      it's a temporary file; we don't want that to happen (for one thing,
4675      it'd prevent subsequent reopens from working).  Remember whether it's
4676      a temporary file, mark it as not being a temporary file, and then
4677      reopen it as the type of file it was.
4678
4679      Also, "cf_close()" will free "cf->filename", so we must make
4680      a copy of it first. */
4681   filename = g_strdup(cf->filename);
4682   is_tempfile = cf->is_tempfile;
4683   cf->is_tempfile = FALSE;
4684   if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
4685     switch (cf_read(cf)) {
4686
4687     case CF_READ_OK:
4688     case CF_READ_ERROR:
4689       /* Just because we got an error, that doesn't mean we were unable
4690          to read any of the file; we handle what we could get from the
4691          file. */
4692       break;
4693
4694     case CF_READ_ABORTED:
4695       /* The user bailed out of re-reading the capture file; the
4696          capture file has been closed - just free the capture file name
4697          string and return (without changing the last containing
4698          directory). */
4699       g_free(filename);
4700       return;
4701     }
4702   } else {
4703     /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
4704        Instead, the file was left open, so we should restore "cf->is_tempfile"
4705        ourselves.
4706
4707        XXX - change the menu?  Presumably "cf_open()" will do that;
4708        make sure it does! */
4709     cf->is_tempfile = is_tempfile;
4710   }
4711   /* "cf_open()" made a copy of the file name we handed it, so
4712      we should free up our copy. */
4713   g_free(filename);
4714 }