6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
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.
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.
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.
46 #include <epan/epan.h>
47 #include <epan/filesystem.h>
50 #include "color_filters.h"
52 #include <epan/column.h>
53 #include <epan/packet.h>
54 #include <epan/column-utils.h>
55 #include "packet-range.h"
62 #include <epan/prefs.h>
63 #include <epan/dfilter/dfilter.h>
64 #include <epan/epan_dissect.h>
66 #include <epan/dissectors/packet-data.h>
67 #include <epan/dissectors/packet-ber.h>
68 #include <epan/timestamp.h>
69 #include <epan/dfilter/dfilter-macro.h>
70 #include <wsutil/file_util.h>
71 #include <epan/strutil.h>
72 #include <epan/addr_resolv.h>
74 #include "ui/alert_box.h"
75 #include "ui/simple_dialog.h"
76 #include "ui/main_statusbar.h"
77 #include "ui/progress_dlg.h"
78 #include "ui/ui_util.h"
81 gboolean auto_scroll_live;
84 static guint32 cum_bytes;
85 static nstime_t first_ts;
86 static nstime_t prev_dis_ts;
87 static nstime_t prev_cap_ts;
89 static gulong computed_elapsed;
91 static void cf_reset_state(capture_file *cf);
93 static int read_packet(capture_file *cf, dfilter_t *dfcode,
94 gboolean filtering_tap_listeners, guint tap_flags, gint64 offset);
96 static void rescan_packets(capture_file *cf, const char *action, const char *action_item,
97 gboolean refilter, gboolean redissect);
104 static match_result match_protocol_tree(capture_file *cf, frame_data *fdata,
106 static void match_subtree_text(proto_node *node, gpointer data);
107 static match_result match_summary_line(capture_file *cf, frame_data *fdata,
109 static match_result match_ascii_and_unicode(capture_file *cf, frame_data *fdata,
111 static match_result match_ascii(capture_file *cf, frame_data *fdata,
113 static match_result match_unicode(capture_file *cf, frame_data *fdata,
115 static match_result match_binary(capture_file *cf, frame_data *fdata,
117 static match_result match_dfilter(capture_file *cf, frame_data *fdata,
119 static match_result match_marked(capture_file *cf, frame_data *fdata,
121 static match_result match_time_reference(capture_file *cf, frame_data *fdata,
123 static gboolean find_packet(capture_file *cf,
124 match_result (*match_function)(capture_file *, frame_data *, void *),
125 void *criterion, search_direction dir);
127 static void cf_open_failure_alert_box(const char *filename, int err,
128 gchar *err_info, gboolean for_writing,
130 static const char *file_rename_error_message(int err);
131 static void cf_close_failure_alert_box(const char *filename, int err);
132 static void ref_time_packets(capture_file *cf);
133 /* Update the progress bar this many times when reading a file. */
134 #define N_PROGBAR_UPDATES 100
135 /* We read around 200k/100ms don't update the progress bar more often than that */
136 #define MIN_QUANTUM 200000
137 #define MIN_NUMBER_OF_PACKET 1500
140 * We could probably use g_signal_...() instead of the callbacks below but that
141 * would require linking our CLI programs to libgobject and creating an object
142 * instance for the signals.
145 cf_callback_t cb_fct;
147 } cf_callback_data_t;
149 static GList *cf_callbacks = NULL;
152 cf_callback_invoke(int event, gpointer data)
154 cf_callback_data_t *cb;
155 GList *cb_item = cf_callbacks;
157 /* there should be at least one interested */
158 g_assert(cb_item != NULL);
160 while(cb_item != NULL) {
162 cb->cb_fct(event, data, cb->user_data);
163 cb_item = g_list_next(cb_item);
169 cf_callback_add(cf_callback_t func, gpointer user_data)
171 cf_callback_data_t *cb;
173 cb = g_malloc(sizeof(cf_callback_data_t));
175 cb->user_data = user_data;
177 cf_callbacks = g_list_append(cf_callbacks, cb);
181 cf_callback_remove(cf_callback_t func)
183 cf_callback_data_t *cb;
184 GList *cb_item = cf_callbacks;
186 while(cb_item != NULL) {
188 if(cb->cb_fct == func) {
189 cf_callbacks = g_list_remove(cf_callbacks, cb);
193 cb_item = g_list_next(cb_item);
196 g_assert_not_reached();
200 cf_timestamp_auto_precision(capture_file *cf)
203 int prec = timestamp_get_precision();
206 /* don't try to get the file's precision if none is opened */
207 if(cf->state == FILE_CLOSED) {
211 /* if we are in auto mode, set precision of current file */
212 if(prec == TS_PREC_AUTO ||
213 prec == TS_PREC_AUTO_SEC ||
214 prec == TS_PREC_AUTO_DSEC ||
215 prec == TS_PREC_AUTO_CSEC ||
216 prec == TS_PREC_AUTO_MSEC ||
217 prec == TS_PREC_AUTO_USEC ||
218 prec == TS_PREC_AUTO_NSEC)
220 switch(wtap_file_tsprecision(cf->wth)) {
221 case(WTAP_FILE_TSPREC_SEC):
222 timestamp_set_precision(TS_PREC_AUTO_SEC);
224 case(WTAP_FILE_TSPREC_DSEC):
225 timestamp_set_precision(TS_PREC_AUTO_DSEC);
227 case(WTAP_FILE_TSPREC_CSEC):
228 timestamp_set_precision(TS_PREC_AUTO_CSEC);
230 case(WTAP_FILE_TSPREC_MSEC):
231 timestamp_set_precision(TS_PREC_AUTO_MSEC);
233 case(WTAP_FILE_TSPREC_USEC):
234 timestamp_set_precision(TS_PREC_AUTO_USEC);
236 case(WTAP_FILE_TSPREC_NSEC):
237 timestamp_set_precision(TS_PREC_AUTO_NSEC);
240 g_assert_not_reached();
243 /* Set the column widths of those columns that show the time in
244 "command-line-specified" format. */
245 for (i = 0; i < cf->cinfo.num_cols; i++) {
246 if (col_has_time_fmt(&cf->cinfo, i)) {
247 new_packet_list_resize_column(i);
253 cf_get_computed_elapsed(void)
255 return computed_elapsed;
258 static void reset_elapsed(void)
260 computed_elapsed = 0;
263 static void compute_elapsed(GTimeVal *start_time)
268 g_get_current_time(&time_now);
270 delta_time = (time_now.tv_sec - start_time->tv_sec) * 1e6 +
271 time_now.tv_usec - start_time->tv_usec;
273 computed_elapsed = (gulong) (delta_time / 1000); /* ms*/
277 cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
282 wth = wtap_open_offline(fname, err, &err_info, TRUE);
286 /* The open succeeded. Close whatever capture file we had open,
287 and fill in the information for this file. */
290 /* Cleanup all data structures used for dissection. */
291 cleanup_dissection();
292 /* Initialize all data structures used for dissection. */
295 /* We're about to start reading the file. */
296 cf->state = FILE_READ_IN_PROGRESS;
301 /* Set the file name because we need it to set the follow stream filter.
302 XXX - is that still true? We need it for other reasons, though,
304 cf->filename = g_strdup(fname);
306 /* Indicate whether it's a permanent or temporary file. */
307 cf->is_tempfile = is_tempfile;
309 /* No user changes yet. */
310 cf->unsaved_changes = FALSE;
314 cf->cd_t = wtap_file_type(cf->wth);
316 cf->displayed_count = 0;
317 cf->marked_count = 0;
318 cf->ignored_count = 0;
319 cf->ref_time_count = 0;
320 cf->drops_known = FALSE;
322 cf->snap = wtap_snapshot_length(cf->wth);
324 /* Snapshot length not known. */
325 cf->has_snap = FALSE;
326 cf->snap = WTAP_MAX_PACKET_SIZE;
330 /* Allocate a frame_data_sequence for the frames in this file */
331 cf->frames = new_frame_data_sequence();
333 nstime_set_zero(&cf->elapsed_time);
334 nstime_set_unset(&first_ts);
335 nstime_set_unset(&prev_dis_ts);
336 nstime_set_unset(&prev_cap_ts);
339 /* Adjust timestamp precision if auto is selected, col width will be adjusted */
340 cf_timestamp_auto_precision(cf);
342 new_packet_list_queue_draw();
343 fileset_file_opened(fname);
345 if(cf->cd_t == WTAP_FILE_BER) {
346 /* tell the BER dissector the file name */
347 ber_set_filename(cf->filename);
350 wtap_set_cb_new_ipv4(cf->wth, add_ipv4_name);
351 wtap_set_cb_new_ipv6(cf->wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
356 cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
362 * Reset the state for the currently closed file, but don't do the
363 * UI callbacks; this is for use in "cf_open()", where we don't
364 * want the UI to go from "file open" to "file closed" back to
365 * "file open", we want it to go from "old file open" to "new file
366 * open and being read".
368 * XXX - currently, cf_open() calls cf_close(), rather than
372 cf_reset_state(capture_file *cf)
374 /* Die if we're in the middle of reading a file. */
375 g_assert(cf->state != FILE_READ_IN_PROGRESS);
381 /* We have no file open... */
382 if (cf->filename != NULL) {
383 /* If it's a temporary file, remove it. */
385 ws_unlink(cf->filename);
386 g_free(cf->filename);
389 /* ...which means we have no changes to that file to save. */
390 cf->unsaved_changes = FALSE;
392 dfilter_free(cf->rfcode);
394 if (cf->frames != NULL) {
395 free_frame_data_sequence(cf->frames);
398 #ifdef WANT_PACKET_EDITOR
399 if (cf->edited_frames) {
400 g_tree_destroy(cf->edited_frames);
401 cf->edited_frames = NULL;
404 cf_unselect_packet(cf); /* nothing to select */
405 cf->first_displayed = 0;
406 cf->last_displayed = 0;
408 /* No frames, no frame selected, no field in that frame selected. */
410 cf->current_frame = 0;
412 cf->finfo_selected = NULL;
414 /* Clear the packet list. */
415 new_packet_list_freeze();
416 new_packet_list_clear();
417 new_packet_list_thaw();
420 nstime_set_zero(&cf->elapsed_time);
422 reset_tap_listeners();
424 /* We have no file open. */
425 cf->state = FILE_CLOSED;
427 fileset_file_closed();
430 /* Reset everything to a pristine state */
432 cf_close(capture_file *cf)
434 if(cf->state != FILE_CLOSED) {
435 cf_callback_invoke(cf_cb_file_closing, cf);
437 /* close things, if not already closed before */
438 color_filters_cleanup();
440 cleanup_dissection();
442 cf_callback_invoke(cf_cb_file_closed, cf);
446 /* an out of memory exception occured, wait for a user button press to exit */
447 static void outofmemory_cb(gpointer dialog _U_, gint btn _U_, gpointer data _U_)
453 calc_progbar_val(capture_file *cf, gint64 size, gint64 file_pos, gchar *status_str, gulong status_size)
457 progbar_val = (gfloat) file_pos / (gfloat) size;
458 if (progbar_val > 1.0) {
460 /* The file probably grew while we were reading it.
461 * Update file size, and try again.
463 size = wtap_file_size(cf->wth, NULL);
466 progbar_val = (gfloat) file_pos / (gfloat) size;
468 /* If it's still > 1, either "wtap_file_size()" failed (in which
469 * case there's not much we can do about it), or the file
470 * *shrank* (in which case there's not much we can do about
471 * it); just clip the progress value at 1.0.
473 if (progbar_val > 1.0f)
477 g_snprintf(status_str, status_size,
478 "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
479 file_pos / 1024, size / 1024);
485 cf_read(capture_file *cf, gboolean from_save)
489 const gchar *name_ptr;
491 char errmsg_errno[1024+1];
494 progdlg_t *volatile progbar = NULL;
496 volatile gint64 size;
497 volatile float progbar_val;
499 gchar status_str[100];
500 volatile gint64 progbar_nextstep;
501 volatile gint64 progbar_quantum;
503 gboolean filtering_tap_listeners;
505 volatile int count = 0;
507 volatile int displayed_once = 0;
511 /* Compile the current display filter.
512 * We assume this will not fail since cf->dfilter is only set in
513 * cf_filter IFF the filter was valid.
515 compiled = dfilter_compile(cf->dfilter, &dfcode);
516 g_assert(!cf->dfilter || (compiled && dfcode));
518 /* Do we have any tap listeners with filters? */
519 filtering_tap_listeners = have_filtering_tap_listeners();
521 /* Get the union of the flags for all tap listeners. */
522 tap_flags = union_of_tap_listener_flags();
524 reset_tap_listeners();
526 name_ptr = get_basename(cf->filename);
528 if (from_save == FALSE)
529 cf_callback_invoke(cf_cb_file_read_started, cf);
531 cf_callback_invoke(cf_cb_file_save_started, (gpointer)name_ptr);
533 /* Find the size of the file. */
534 size = wtap_file_size(cf->wth, NULL);
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. */
541 progbar_quantum = size/N_PROGBAR_UPDATES;
542 if (progbar_quantum < MIN_QUANTUM)
543 progbar_quantum = MIN_QUANTUM;
546 /* Progress so far. */
549 /* The packet list window will be empty untill the file is completly loaded */
550 new_packet_list_freeze();
553 g_get_current_time(&start_time);
555 while ((wtap_read(cf->wth, &err, &err_info, &data_offset))) {
558 file_pos = wtap_read_so_far(cf->wth);
560 /* Create the progress bar if necessary.
561 * Check whether it should be created or not every MIN_NUMBER_OF_PACKET
563 if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)){
564 progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
565 if (from_save == FALSE)
566 progbar = delayed_create_progress_dlg("Loading", name_ptr,
567 TRUE, &stop_flag, &start_time, progbar_val);
569 progbar = delayed_create_progress_dlg("Saving", name_ptr,
570 TRUE, &stop_flag, &start_time, progbar_val);
573 /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
574 when we update it, we have to run the GTK+ main loop to get it
575 to repaint what's pending, and doing so may involve an "ioctl()"
576 to see if there's any pending input from an X server, and doing
577 that for every packet can be costly, especially on a big file. */
578 if (file_pos >= progbar_nextstep) {
579 if (progbar != NULL) {
580 progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
581 /* update the packet bar content on the first run or frequently on very large files */
583 if (progbar_quantum > 500000 || displayed_once == 0) {
584 if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->count != 0) {
586 packets_bar_update();
589 #endif /* HAVE_LIBPCAP */
590 update_progress_dlg(progbar, progbar_val, status_str);
592 progbar_nextstep += progbar_quantum;
597 /* Well, the user decided to abort the read. He/She will be warned and
598 it might be enough for him/her to work with the already loaded
600 This is especially true for very large capture files, where you don't
601 want to wait loading the whole file (which may last minutes or even
602 hours even on fast machines) just to see that it was the wrong file. */
606 read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
608 CATCH(OutOfMemoryError) {
611 dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
612 "%sOut Of Memory!%s\n"
614 "Sorry, but Wireshark has to terminate now!\n"
616 "Some infos / workarounds can be found at:\n"
617 "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
618 simple_dialog_primary_start(), simple_dialog_primary_end());
619 /* we have to terminate, as we cannot recover from the memory error */
620 simple_dialog_set_cb(dialog, outofmemory_cb, NULL);
622 main_window_update();
623 /* XXX - how to avoid a busy wait? */
631 /* Cleanup and release all dfilter resources */
633 dfilter_free(dfcode);
636 /* We're done reading the file; destroy the progress bar if it was created. */
638 destroy_progress_dlg(progbar);
640 /* We're done reading sequentially through the file. */
641 cf->state = FILE_READ_DONE;
643 /* Close the sequential I/O side, to free up memory it requires. */
644 wtap_sequential_close(cf->wth);
646 /* Allow the protocol dissectors to free up memory that they
647 * don't need after the sequential run-through of the packets. */
648 postseq_cleanup_all_protocols();
650 /* compute the time it took to load the file */
651 compute_elapsed(&start_time);
653 /* Set the file encapsulation type now; we don't know what it is until
654 we've looked at all the packets, as we don't know until then whether
655 there's more than one type (and thus whether it's
656 WTAP_ENCAP_PER_PACKET). */
657 cf->lnk_t = wtap_file_encap(cf->wth);
659 cf->current_frame = frame_data_sequence_find(cf->frames, cf->first_displayed);
662 new_packet_list_thaw();
663 if (from_save == FALSE)
664 cf_callback_invoke(cf_cb_file_read_finished, cf);
666 cf_callback_invoke(cf_cb_file_save_finished, cf);
668 /* If we have any displayed packets to select, select the first of those
669 packets by making the first row the selected row. */
670 if (cf->first_displayed != 0){
671 new_packet_list_select_first_row();
675 simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
676 "%sFile loading was cancelled!%s\n"
678 "The remaining packets in the file were discarded.\n"
680 "As a lot of packets from the original file will be missing,\n"
681 "remember to be careful when saving the current content to a file.\n",
682 simple_dialog_primary_start(), simple_dialog_primary_end());
683 return CF_READ_ERROR;
687 /* Put up a message box noting that the read failed somewhere along
688 the line. Don't throw out the stuff we managed to read, though,
692 case WTAP_ERR_UNSUPPORTED:
693 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
694 "The capture file contains record data that TShark doesn't support.\n(%s)",
697 errmsg = errmsg_errno;
700 case WTAP_ERR_UNSUPPORTED_ENCAP:
701 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
702 "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
705 errmsg = errmsg_errno;
708 case WTAP_ERR_CANT_READ:
709 errmsg = "An attempt to read from the capture file failed for"
710 " some unknown reason.";
713 case WTAP_ERR_SHORT_READ:
714 errmsg = "The capture file appears to have been cut short"
715 " in the middle of a packet.";
718 case WTAP_ERR_BAD_FILE:
719 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
720 "The capture file appears to be damaged or corrupt.\n(%s)",
723 errmsg = errmsg_errno;
726 case WTAP_ERR_DECOMPRESS:
727 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
728 "The compressed capture file appears to be damaged or corrupt.\n"
731 errmsg = errmsg_errno;
735 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
736 "An error occurred while reading the"
737 " capture file: %s.", wtap_strerror(err));
738 errmsg = errmsg_errno;
741 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", errmsg);
742 return CF_READ_ERROR;
749 cf_start_tail(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
751 cf_status_t cf_status;
753 cf_status = cf_open(cf, fname, is_tempfile, err);
758 cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
760 gint64 data_offset = 0;
762 volatile int newly_displayed_packets = 0;
764 gboolean filtering_tap_listeners;
768 /* Compile the current display filter.
769 * We assume this will not fail since cf->dfilter is only set in
770 * cf_filter IFF the filter was valid.
772 compiled = dfilter_compile(cf->dfilter, &dfcode);
773 g_assert(!cf->dfilter || (compiled && dfcode));
775 /* Do we have any tap listeners with filters? */
776 filtering_tap_listeners = have_filtering_tap_listeners();
778 /* Get the union of the flags for all tap listeners. */
779 tap_flags = union_of_tap_listener_flags();
783 new_packet_list_check_end();
784 /* Don't freeze/thaw the list when doing live capture */
785 /*new_packet_list_freeze();*/
787 /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: %u new: %u", cf->count, to_read);*/
789 while (to_read != 0) {
790 wtap_cleareof(cf->wth);
791 if (!wtap_read(cf->wth, err, &err_info, &data_offset)) {
794 if (cf->state == FILE_READ_ABORTED) {
795 /* Well, the user decided to exit Wireshark. Break out of the
796 loop, and let the code below (which is called even if there
797 aren't any packets left to read) exit. */
801 if (read_packet(cf, dfcode, filtering_tap_listeners, tap_flags,
802 data_offset) != -1) {
803 newly_displayed_packets++;
806 CATCH(OutOfMemoryError) {
809 dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
810 "%sOut Of Memory!%s\n"
812 "Sorry, but Wireshark has to terminate now!\n"
814 "The capture file is not lost, it can be found at:\n"
817 "Some infos / workarounds can be found at:\n"
818 "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
819 simple_dialog_primary_start(), simple_dialog_primary_end(), cf->filename);
820 /* we have to terminate, as we cannot recover from the memory error */
821 simple_dialog_set_cb(dialog, outofmemory_cb, NULL);
823 main_window_update();
824 /* XXX - how to avoid a busy wait? */
827 /* Don't freeze/thaw the list when doing live capture */
828 /*new_packet_list_thaw();*/
829 return CF_READ_ABORTED;
835 /* Cleanup and release all dfilter resources */
837 dfilter_free(dfcode);
840 /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: count %u state: %u err: %u",
841 cf->count, cf->state, *err);*/
843 /* Don't freeze/thaw the list when doing live capture */
844 /*new_packet_list_thaw();*/
845 /* With the new packet list the first packet
846 * isn't automatically selected.
848 if(!cf->current_frame)
849 new_packet_list_select_first_row();
851 /* moving to the end of the packet list - if the user requested so and
852 we have some new packets. */
853 if (newly_displayed_packets && auto_scroll_live && cf->count != 0)
854 new_packet_list_moveto_end();
856 if (cf->state == FILE_READ_ABORTED) {
857 /* Well, the user decided to exit Wireshark. Return CF_READ_ABORTED
858 so that our caller can kill off the capture child process;
859 this will cause an EOF on the pipe from the child, so
860 "cf_finish_tail()" will be called, and it will clean up
862 return CF_READ_ABORTED;
863 } else if (*err != 0) {
864 /* We got an error reading the capture file.
865 XXX - pop up a dialog box instead? */
866 g_warning("Error \"%s\" while reading: \"%s\"\n",
867 wtap_strerror(*err), cf->filename);
869 return CF_READ_ERROR;
875 cf_fake_continue_tail(capture_file *cf) {
876 cf->state = FILE_READ_DONE;
880 cf_finish_tail(capture_file *cf, int *err)
885 gboolean filtering_tap_listeners;
889 /* Compile the current display filter.
890 * We assume this will not fail since cf->dfilter is only set in
891 * cf_filter IFF the filter was valid.
893 compiled = dfilter_compile(cf->dfilter, &dfcode);
894 g_assert(!cf->dfilter || (compiled && dfcode));
896 /* Do we have any tap listeners with filters? */
897 filtering_tap_listeners = have_filtering_tap_listeners();
899 /* Get the union of the flags for all tap listeners. */
900 tap_flags = union_of_tap_listener_flags();
902 if(cf->wth == NULL) {
904 return CF_READ_ERROR;
907 new_packet_list_check_end();
908 /* Don't freeze/thaw the list when doing live capture */
909 /*new_packet_list_freeze();*/
911 while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
912 if (cf->state == FILE_READ_ABORTED) {
913 /* Well, the user decided to abort the read. Break out of the
914 loop, and let the code below (which is called even if there
915 aren't any packets left to read) exit. */
918 read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
921 /* Cleanup and release all dfilter resources */
923 dfilter_free(dfcode);
926 /* Don't freeze/thaw the list when doing live capture */
927 /*new_packet_list_thaw();*/
929 if (cf->state == FILE_READ_ABORTED) {
930 /* Well, the user decided to abort the read. We're only called
931 when the child capture process closes the pipe to us (meaning
932 it's probably exited), so we can just close the capture
933 file; we return CF_READ_ABORTED so our caller can do whatever
934 is appropriate when that happens. */
936 return CF_READ_ABORTED;
939 if (auto_scroll_live && cf->count != 0)
940 new_packet_list_moveto_end();
942 /* We're done reading sequentially through the file. */
943 cf->state = FILE_READ_DONE;
945 /* We're done reading sequentially through the file; close the
946 sequential I/O side, to free up memory it requires. */
947 wtap_sequential_close(cf->wth);
949 /* Allow the protocol dissectors to free up memory that they
950 * don't need after the sequential run-through of the packets. */
951 postseq_cleanup_all_protocols();
953 /* Set the file encapsulation type now; we don't know what it is until
954 we've looked at all the packets, as we don't know until then whether
955 there's more than one type (and thus whether it's
956 WTAP_ENCAP_PER_PACKET). */
957 cf->lnk_t = wtap_file_encap(cf->wth);
960 /* We got an error reading the capture file.
961 XXX - pop up a dialog box? */
962 return CF_READ_ERROR;
967 #endif /* HAVE_LIBPCAP */
970 cf_get_display_name(capture_file *cf)
972 const gchar *displayname;
974 /* Return a name to use in displays */
975 if (!cf->is_tempfile) {
976 /* Get the last component of the file name, and use that. */
978 displayname = get_basename(cf->filename);
980 displayname="(No file)";
983 /* The file we read is a temporary file from a live capture;
984 we don't mention its name. */
986 displayname = cf->source;
988 displayname = "(Untitled)";
994 void cf_set_tempfile_source(capture_file *cf, gchar *source) {
1000 cf->source = g_strdup(source);
1002 cf->source = g_strdup("");
1006 const gchar *cf_get_tempfile_source(capture_file *cf) {
1014 /* XXX - use a macro instead? */
1016 cf_get_packet_count(capture_file *cf)
1021 /* XXX - use a macro instead? */
1023 cf_set_packet_count(capture_file *cf, int packet_count)
1025 cf->count = packet_count;
1028 /* XXX - use a macro instead? */
1030 cf_is_tempfile(capture_file *cf)
1032 return cf->is_tempfile;
1035 void cf_set_tempfile(capture_file *cf, gboolean is_tempfile)
1037 cf->is_tempfile = is_tempfile;
1041 /* XXX - use a macro instead? */
1042 void cf_set_drops_known(capture_file *cf, gboolean drops_known)
1044 cf->drops_known = drops_known;
1047 /* XXX - use a macro instead? */
1048 void cf_set_drops(capture_file *cf, guint32 drops)
1053 /* XXX - use a macro instead? */
1054 gboolean cf_get_drops_known(capture_file *cf)
1056 return cf->drops_known;
1059 /* XXX - use a macro instead? */
1060 guint32 cf_get_drops(capture_file *cf)
1065 void cf_set_rfcode(capture_file *cf, dfilter_t *rfcode)
1067 cf->rfcode = rfcode;
1071 find_and_mark_frame_depended_upon(gpointer data, gpointer user_data)
1073 frame_data *dependent_fd;
1074 guint32 dependent_frame = GPOINTER_TO_UINT(data);
1075 capture_file *cf = (capture_file *)user_data;
1077 dependent_fd = frame_data_sequence_find(cf->frames, dependent_frame);
1078 dependent_fd->flags.dependent_of_displayed = 1;
1082 add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
1083 dfilter_t *dfcode, gboolean filtering_tap_listeners,
1085 union wtap_pseudo_header *pseudo_header, const guchar *buf,
1087 gboolean add_to_packet_list)
1089 gboolean create_proto_tree = FALSE;
1094 cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
1096 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1097 &first_ts, &prev_dis_ts, &prev_cap_ts);
1100 + we have a display filter and are re-applying it;
1101 + we have tap listeners with filters;
1102 + we have tap listeners that require a protocol tree;
1104 allocate a protocol tree root node, so that we'll construct
1105 a protocol tree against which a filter expression can be
1107 if ((dfcode != NULL && refilter) ||
1108 filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE))
1109 create_proto_tree = TRUE;
1111 /* Dissect the frame. */
1112 epan_dissect_init(&edt, create_proto_tree, FALSE);
1114 if (dfcode != NULL && refilter) {
1115 epan_dissect_prime_dfilter(&edt, dfcode);
1118 tap_queue_init(&edt);
1119 epan_dissect_run(&edt, pseudo_header, buf, fdata, cinfo);
1120 tap_push_tapped_queue(&edt);
1122 /* If we have a display filter, apply it if we're refiltering, otherwise
1123 leave the "passed_dfilter" flag alone.
1125 If we don't have a display filter, set "passed_dfilter" to 1. */
1126 if (dfcode != NULL) {
1128 fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, &edt) ? 1 : 0;
1130 if (fdata->flags.passed_dfilter) {
1131 /* This frame passed the display filter but it may depend on other
1132 * (potentially not displayed) frames. Find those frames and mark them
1135 * (We don't have to do this if we're not filtering--that is, the
1136 * 'else' case below.)
1138 g_slist_foreach(edt.pi.dependent_frames, find_and_mark_frame_depended_upon, cf);
1142 fdata->flags.passed_dfilter = 1;
1144 if(fdata->flags.passed_dfilter || fdata->flags.ref_time)
1145 cf->displayed_count++;
1147 if (add_to_packet_list) {
1148 /* We fill the needed columns from new_packet_list */
1149 row = new_packet_list_append(cinfo, fdata, &edt.pi);
1152 if(fdata->flags.passed_dfilter || fdata->flags.ref_time)
1154 frame_data_set_after_dissect(fdata, &cum_bytes, &prev_dis_ts);
1156 /* If we haven't yet seen the first frame, this is it.
1158 XXX - we must do this before we add the row to the display,
1159 as, if the display's GtkCList's selection mode is
1160 GTK_SELECTION_BROWSE, when the first entry is added to it,
1161 "cf_select_packet()" will be called, and it will fetch the row
1162 data for the 0th row, and will get a null pointer rather than
1163 "fdata", as "gtk_clist_append()" won't yet have returned and
1164 thus "gtk_clist_set_row_data()" won't yet have been called.
1166 We thus need to leave behind bread crumbs so that
1167 "cf_select_packet()" can find this frame. See the comment
1168 in "cf_select_packet()". */
1169 if (cf->first_displayed == 0)
1170 cf->first_displayed = fdata->num;
1172 /* This is the last frame we've seen so far. */
1173 cf->last_displayed = fdata->num;
1176 epan_dissect_cleanup(&edt);
1180 /* read in a new packet */
1181 /* returns the row of the new packet in the packet list or -1 if not displayed */
1183 read_packet(capture_file *cf, dfilter_t *dfcode,
1184 gboolean filtering_tap_listeners, guint tap_flags, gint64 offset)
1186 const struct wtap_pkthdr *phdr = wtap_phdr(cf->wth);
1187 union wtap_pseudo_header *pseudo_header = wtap_pseudoheader(cf->wth);
1188 const guchar *buf = wtap_buf_ptr(cf->wth);
1195 /* The frame number of this packet is one more than the count of
1196 frames in this packet. */
1197 framenum = cf->count + 1;
1199 frame_data_init(&fdlocal, framenum, phdr, offset, cum_bytes);
1204 epan_dissect_init(&edt, TRUE, FALSE);
1205 epan_dissect_prime_dfilter(&edt, cf->rfcode);
1206 epan_dissect_run(&edt, pseudo_header, buf, &fdlocal, NULL);
1207 passed = dfilter_apply_edt(cf->rfcode, &edt);
1208 epan_dissect_cleanup(&edt);
1212 /* This does a shallow copy of fdlocal, which is good enough. */
1213 fdata = frame_data_sequence_add(cf->frames, &fdlocal);
1216 cf->f_datalen = offset + fdlocal.cap_len;
1218 if (!cf->redissecting) {
1219 row = add_packet_to_packet_list(fdata, cf, dfcode,
1220 filtering_tap_listeners, tap_flags,
1221 pseudo_header, buf, TRUE, TRUE);
1229 cf_merge_files(char **out_filenamep, int in_file_count,
1230 char *const *in_filenames, int file_type, gboolean do_append)
1232 merge_in_file_t *in_files, *in_file;
1237 int open_err, read_err, write_err, close_err;
1241 char errmsg_errno[1024+1];
1243 gboolean got_read_error = FALSE, got_write_error = FALSE;
1245 progdlg_t *progbar = NULL;
1247 gint64 f_len, file_pos;
1249 GTimeVal start_time;
1250 gchar status_str[100];
1251 gint64 progbar_nextstep;
1252 gint64 progbar_quantum;
1254 /* open the input files */
1255 if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
1256 &open_err, &err_info, &err_fileno)) {
1258 cf_open_failure_alert_box(in_filenames[err_fileno], open_err, err_info,
1263 if (*out_filenamep != NULL) {
1264 out_filename = *out_filenamep;
1265 out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
1269 out_fd = create_tempfile(&tmpname, "wireshark");
1272 out_filename = g_strdup(tmpname);
1273 *out_filenamep = out_filename;
1277 merge_close_in_files(in_file_count, in_files);
1279 cf_open_failure_alert_box(out_filename, open_err, NULL, TRUE, file_type);
1283 pdh = wtap_dump_fdopen(out_fd, file_type,
1284 merge_select_frame_type(in_file_count, in_files),
1285 merge_max_snapshot_length(in_file_count, in_files),
1286 FALSE /* compressed */, &open_err);
1289 merge_close_in_files(in_file_count, in_files);
1291 cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
1296 /* Get the sum of the sizes of all the files. */
1298 for (i = 0; i < in_file_count; i++)
1299 f_len += in_files[i].size;
1301 /* Update the progress bar when it gets to this value. */
1302 progbar_nextstep = 0;
1303 /* When we reach the value that triggers a progress bar update,
1304 bump that value by this amount. */
1305 progbar_quantum = f_len/N_PROGBAR_UPDATES;
1306 /* Progress so far. */
1310 g_get_current_time(&start_time);
1312 /* do the merge (or append) */
1315 in_file = merge_append_read_packet(in_file_count, in_files, &read_err,
1318 in_file = merge_read_packet(in_file_count, in_files, &read_err,
1320 if (in_file == NULL) {
1325 if (read_err != 0) {
1326 /* I/O error reading from in_file */
1327 got_read_error = TRUE;
1331 /* Get the sum of the data offsets in all of the files. */
1333 for (i = 0; i < in_file_count; i++)
1334 data_offset += in_files[i].data_offset;
1336 /* Create the progress bar if necessary.
1337 We check on every iteration of the loop, so that it takes no
1338 longer than the standard time to create it (otherwise, for a
1339 large file, we might take considerably longer than that standard
1340 time in order to get to the next progress bar step). */
1341 if (progbar == NULL) {
1342 progbar = delayed_create_progress_dlg("Merging", "files",
1343 FALSE, &stop_flag, &start_time, progbar_val);
1346 /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1347 when we update it, we have to run the GTK+ main loop to get it
1348 to repaint what's pending, and doing so may involve an "ioctl()"
1349 to see if there's any pending input from an X server, and doing
1350 that for every packet can be costly, especially on a big file. */
1351 if (data_offset >= progbar_nextstep) {
1352 /* Get the sum of the seek positions in all of the files. */
1354 for (i = 0; i < in_file_count; i++)
1355 file_pos += wtap_read_so_far(in_files[i].wth);
1356 progbar_val = (gfloat) file_pos / (gfloat) f_len;
1357 if (progbar_val > 1.0f) {
1358 /* Some file probably grew while we were reading it.
1359 That "shouldn't happen", so we'll just clip the progress
1363 if (progbar != NULL) {
1364 g_snprintf(status_str, sizeof(status_str),
1365 "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
1366 file_pos / 1024, f_len / 1024);
1367 update_progress_dlg(progbar, progbar_val, status_str);
1369 progbar_nextstep += progbar_quantum;
1373 /* Well, the user decided to abort the merge. */
1377 if (!wtap_dump(pdh, wtap_phdr(in_file->wth), wtap_pseudoheader(in_file->wth),
1378 wtap_buf_ptr(in_file->wth), &write_err)) {
1379 got_write_error = TRUE;
1384 /* We're done merging the files; destroy the progress bar if it was created. */
1385 if (progbar != NULL)
1386 destroy_progress_dlg(progbar);
1388 merge_close_in_files(in_file_count, in_files);
1389 if (!got_read_error && !got_write_error) {
1390 if (!wtap_dump_close(pdh, &write_err))
1391 got_write_error = TRUE;
1393 wtap_dump_close(pdh, &close_err);
1395 if (got_read_error) {
1397 * Find the file on which we got the error, and report the error.
1399 for (i = 0; i < in_file_count; i++) {
1400 if (in_files[i].state == GOT_ERROR) {
1401 /* Put up a message box noting that a read failed somewhere along
1405 case WTAP_ERR_UNSUPPORTED_ENCAP:
1406 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1407 "The capture file %%s has a packet with a network type that Wireshark doesn't support.\n(%s)",
1410 errmsg = errmsg_errno;
1413 case WTAP_ERR_CANT_READ:
1414 errmsg = "An attempt to read from the capture file %s failed for"
1415 " some unknown reason.";
1418 case WTAP_ERR_SHORT_READ:
1419 errmsg = "The capture file %s appears to have been cut short"
1420 " in the middle of a packet.";
1423 case WTAP_ERR_BAD_FILE:
1424 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1425 "The capture file %%s appears to be damaged or corrupt.\n(%s)",
1428 errmsg = errmsg_errno;
1431 case WTAP_ERR_DECOMPRESS:
1432 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1433 "The compressed capture file %%s appears to be damaged or corrupt.\n"
1436 errmsg = errmsg_errno;
1440 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1441 "An error occurred while reading the"
1442 " capture file %%s: %s.", wtap_strerror(read_err));
1443 errmsg = errmsg_errno;
1446 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, errmsg, in_files[i].filename);
1451 if (got_write_error) {
1452 /* Put up an alert box for the write error. */
1453 if (write_err < 0) {
1454 /* Wiretap error. */
1455 switch (write_err) {
1457 case WTAP_ERR_UNSUPPORTED_ENCAP:
1459 * This is a problem with the particular frame we're writing;
1460 * note that, and give the frame number.
1462 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1463 "Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file.",
1464 in_file->packet_num, in_file->filename,
1465 wtap_file_type_string(file_type));
1469 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1470 "An error occurred while writing to the file \"%s\": %s.",
1471 out_filename, wtap_strerror(write_err));
1476 write_failure_alert_box(out_filename, write_err);
1480 if (got_read_error || got_write_error || stop_flag) {
1481 /* Callers aren't expected to treat an error or an explicit abort
1482 differently - we put up error dialogs ourselves, so they don't
1490 cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force)
1492 const char *filter_new = dftext ? dftext : "";
1493 const char *filter_old = cf->dfilter ? cf->dfilter : "";
1495 GTimeVal start_time;
1497 /* if new filter equals old one, do nothing unless told to do so */
1498 if (!force && strcmp(filter_new, filter_old) == 0) {
1504 if (dftext == NULL) {
1505 /* The new filter is an empty filter (i.e., display all packets).
1506 * so leave dfcode==NULL
1510 * We have a filter; make a copy of it (as we'll be saving it),
1511 * and try to compile it.
1513 dftext = g_strdup(dftext);
1514 if (!dfilter_compile(dftext, &dfcode)) {
1515 /* The attempt failed; report an error. */
1516 gchar *safe_dftext = simple_dialog_format_message(dftext);
1517 gchar *safe_dfilter_error_msg = simple_dialog_format_message(
1519 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1522 "The following display filter isn't a valid display filter:\n%s\n"
1523 "See the help for a description of the display filter syntax.",
1524 simple_dialog_primary_start(), safe_dfilter_error_msg,
1525 simple_dialog_primary_end(), safe_dftext);
1526 g_free(safe_dfilter_error_msg);
1527 g_free(safe_dftext);
1533 if (dfcode == NULL) {
1534 /* Yes - free the filter text, and set it to null. */
1540 /* We have a valid filter. Replace the current filter. */
1541 g_free(cf->dfilter);
1542 cf->dfilter = dftext;
1543 g_get_current_time(&start_time);
1546 /* Now rescan the packet list, applying the new filter, but not
1547 throwing away information constructed on a previous pass. */
1548 if (dftext == NULL) {
1549 rescan_packets(cf, "Resetting", "Filter", TRUE, FALSE);
1551 rescan_packets(cf, "Filtering", dftext, TRUE, FALSE);
1554 /* Cleanup and release all dfilter resources */
1555 dfilter_free(dfcode);
1561 cf_reftime_packets(capture_file *cf)
1564 ref_time_packets(cf);
1568 cf_redissect_packets(capture_file *cf)
1570 rescan_packets(cf, "Reprocessing", "all packets", TRUE, TRUE);
1574 cf_read_frame_r(capture_file *cf, frame_data *fdata,
1575 union wtap_pseudo_header *pseudo_header, guint8 *pd)
1579 char errmsg_errno[1024+1];
1581 #ifdef WANT_PACKET_EDITOR
1582 /* if fdata->file_off == -1 it means packet was edited, and we must find data inside edited_frames tree */
1583 if (G_UNLIKELY(fdata->file_off == -1)) {
1584 const modified_frame_data *frame = (const modified_frame_data *) g_tree_lookup(cf->edited_frames, GINT_TO_POINTER(fdata->num));
1587 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "fdata->file_off == -1, but can't find modified frame!");
1591 *pseudo_header = frame->ph;
1592 memcpy(pd, frame->pd, fdata->cap_len);
1597 if (!wtap_seek_read(cf->wth, fdata->file_off, pseudo_header, pd,
1598 fdata->cap_len, &err, &err_info)) {
1601 case WTAP_ERR_UNSUPPORTED_ENCAP:
1602 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1603 "The file \"%%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
1608 case WTAP_ERR_BAD_FILE:
1609 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1610 "An error occurred while reading from the file \"%%s\": %s.\n(%s)",
1611 wtap_strerror(err), err_info);
1616 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1617 "An error occurred while reading from the file \"%%s\": %s.",
1618 wtap_strerror(err));
1621 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, errmsg_errno, cf->filename);
1628 cf_read_frame(capture_file *cf, frame_data *fdata)
1630 return cf_read_frame_r(cf, fdata, &cf->pseudo_header, cf->pd);
1633 /* Rescan the list of packets, reconstructing the CList.
1635 "action" describes why we're doing this; it's used in the progress
1638 "action_item" describes what we're doing; it's used in the progress
1641 "refilter" is TRUE if we need to re-evaluate the filter expression.
1643 "redissect" is TRUE if we need to make the dissectors reconstruct
1644 any state information they have (because a preference that affects
1645 some dissector has changed, meaning some dissector might construct
1646 its state differently from the way it was constructed the last time). */
1648 rescan_packets(capture_file *cf, const char *action, const char *action_item,
1649 gboolean refilter, gboolean redissect)
1651 /* Rescan packets new packet list */
1654 progdlg_t *progbar = NULL;
1657 frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
1658 int selected_frame_num, preceding_frame_num, following_frame_num, prev_frame_num;
1659 gboolean selected_frame_seen;
1661 GTimeVal start_time;
1662 gchar status_str[100];
1663 int progbar_nextstep;
1664 int progbar_quantum;
1666 gboolean filtering_tap_listeners;
1668 gboolean add_to_packet_list = FALSE;
1671 /* Compile the current display filter.
1672 * We assume this will not fail since cf->dfilter is only set in
1673 * cf_filter IFF the filter was valid.
1675 compiled = dfilter_compile(cf->dfilter, &dfcode);
1676 g_assert(!cf->dfilter || (compiled && dfcode));
1678 /* Do we have any tap listeners with filters? */
1679 filtering_tap_listeners = have_filtering_tap_listeners();
1681 /* Get the union of the flags for all tap listeners. */
1682 tap_flags = union_of_tap_listener_flags();
1684 reset_tap_listeners();
1685 /* Which frame, if any, is the currently selected frame?
1686 XXX - should the selected frame or the focus frame be the "current"
1687 frame, that frame being the one from which "Find Frame" searches
1689 selected_frame = cf->current_frame;
1691 /* Mark frame num as not found */
1692 selected_frame_num = -1;
1694 /* Freeze the packet list while we redo it, so we don't get any
1695 screen updates while it happens. */
1696 new_packet_list_freeze();
1699 /* We need to re-initialize all the state information that protocols
1700 keep, because some preference that controls a dissector has changed,
1701 which might cause the state information to be constructed differently
1702 by that dissector. */
1704 /* We might receive new packets while redissecting, and we don't
1705 want to dissect those before their time. */
1706 cf->redissecting = TRUE;
1708 /* Cleanup all data structures used for dissection. */
1709 cleanup_dissection();
1710 /* Initialize all data structures used for dissection. */
1713 /* We need to redissect the packets so we have to discard our old
1714 * packet list store. */
1715 new_packet_list_clear();
1716 add_to_packet_list = TRUE;
1719 /* We don't yet know which will be the first and last frames displayed. */
1720 cf->first_displayed = 0;
1721 cf->last_displayed = 0;
1723 /* We currently don't display any packets */
1724 cf->displayed_count = 0;
1726 /* Iterate through the list of frames. Call a routine for each frame
1727 to check whether it should be displayed and, if so, add it to
1728 the display list. */
1729 nstime_set_unset(&first_ts);
1730 nstime_set_unset(&prev_dis_ts);
1731 nstime_set_unset(&prev_cap_ts);
1734 /* Update the progress bar when it gets to this value. */
1735 progbar_nextstep = 0;
1736 /* When we reach the value that triggers a progress bar update,
1737 bump that value by this amount. */
1738 progbar_quantum = cf->count/N_PROGBAR_UPDATES;
1739 /* Count of packets at which we've looked. */
1741 /* Progress so far. */
1745 g_get_current_time(&start_time);
1747 /* no previous row yet */
1748 prev_frame_num = -1;
1751 preceding_frame_num = -1;
1752 preceding_frame = NULL;
1753 following_frame_num = -1;
1754 following_frame = NULL;
1756 selected_frame_seen = FALSE;
1758 for (framenum = 1; framenum <= cf->count; framenum++) {
1759 fdata = frame_data_sequence_find(cf->frames, framenum);
1761 /* Create the progress bar if necessary.
1762 We check on every iteration of the loop, so that it takes no
1763 longer than the standard time to create it (otherwise, for a
1764 large file, we might take considerably longer than that standard
1765 time in order to get to the next progress bar step). */
1766 if (progbar == NULL)
1767 progbar = delayed_create_progress_dlg(action, action_item, TRUE,
1768 &stop_flag, &start_time,
1771 /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1772 when we update it, we have to run the GTK+ main loop to get it
1773 to repaint what's pending, and doing so may involve an "ioctl()"
1774 to see if there's any pending input from an X server, and doing
1775 that for every packet can be costly, especially on a big file. */
1776 if (count >= progbar_nextstep) {
1777 /* let's not divide by zero. I should never be started
1778 * with count == 0, so let's assert that
1780 g_assert(cf->count > 0);
1781 progbar_val = (gfloat) count / cf->count;
1783 if (progbar != NULL) {
1784 g_snprintf(status_str, sizeof(status_str),
1785 "%4u of %u frames", count, cf->count);
1786 update_progress_dlg(progbar, progbar_val, status_str);
1789 progbar_nextstep += progbar_quantum;
1793 /* Well, the user decided to abort the filtering. Just stop.
1795 XXX - go back to the previous filter? Users probably just
1796 want not to wait for a filtering operation to finish;
1797 unless we cancel by having no filter, reverting to the
1798 previous filter will probably be even more expensive than
1799 continuing the filtering, as it involves going back to the
1800 beginning and filtering, and even with no filter we currently
1801 have to re-generate the entire clist, which is also expensive.
1803 I'm not sure what Network Monitor does, but it doesn't appear
1804 to give you an unfiltered display if you cancel. */
1811 /* Since all state for the frame was destroyed, mark the frame
1812 * as not visited, free the GSList referring to the state
1813 * data (the per-frame data itself was freed by
1814 * "init_dissection()"), and null out the GSList pointer. */
1815 fdata->flags.visited = 0;
1816 frame_data_cleanup(fdata);
1819 if (!cf_read_frame(cf, fdata))
1820 break; /* error reading the frame */
1822 /* If the previous frame is displayed, and we haven't yet seen the
1823 selected frame, remember that frame - it's the closest one we've
1824 yet seen before the selected frame. */
1825 if (prev_frame_num != -1 && !selected_frame_seen && prev_frame->flags.passed_dfilter) {
1826 preceding_frame_num = prev_frame_num;
1827 preceding_frame = prev_frame;
1829 add_packet_to_packet_list(fdata, cf, dfcode, filtering_tap_listeners,
1830 tap_flags, &cf->pseudo_header, cf->pd,
1832 add_to_packet_list);
1834 /* If this frame is displayed, and this is the first frame we've
1835 seen displayed after the selected frame, remember this frame -
1836 it's the closest one we've yet seen at or after the selected
1838 if (fdata->flags.passed_dfilter && selected_frame_seen && following_frame_num == -1) {
1839 following_frame_num = fdata->num;
1840 following_frame = fdata;
1842 if (fdata == selected_frame) {
1843 selected_frame_seen = TRUE;
1844 if (fdata->flags.passed_dfilter)
1845 selected_frame_num = fdata->num;
1848 /* Remember this frame - it'll be the previous frame
1849 on the next pass through the loop. */
1850 prev_frame_num = fdata->num;
1854 /* We are done redissecting the packet list. */
1855 cf->redissecting = FALSE;
1858 /* Clear out what remains of the visited flags and per-frame data
1861 XXX - that may cause various forms of bogosity when dissecting
1862 these frames, as they won't have been seen by this sequential
1863 pass, but the only alternative I see is to keep scanning them
1864 even though the user requested that the scan stop, and that
1865 would leave the user stuck with an Wireshark grinding on
1866 until it finishes. Should we just stick them with that? */
1867 for (; framenum <= cf->count; framenum++) {
1868 fdata = frame_data_sequence_find(cf->frames, framenum);
1869 fdata->flags.visited = 0;
1870 frame_data_cleanup(fdata);
1874 /* We're done filtering the packets; destroy the progress bar if it
1876 if (progbar != NULL)
1877 destroy_progress_dlg(progbar);
1879 /* Unfreeze the packet list. */
1880 if (!add_to_packet_list)
1881 new_packet_list_recreate_visible_rows();
1883 /* Compute the time it took to filter the file */
1884 compute_elapsed(&start_time);
1886 new_packet_list_thaw();
1888 if (selected_frame_num == -1) {
1889 /* The selected frame didn't pass the filter. */
1890 if (selected_frame == NULL) {
1891 /* That's because there *was* no selected frame. Make the first
1892 displayed frame the current frame. */
1893 selected_frame_num = 0;
1895 /* Find the nearest displayed frame to the selected frame (whether
1896 it's before or after that frame) and make that the current frame.
1897 If the next and previous displayed frames are equidistant from the
1898 selected frame, choose the next one. */
1899 g_assert(following_frame == NULL ||
1900 following_frame->num >= selected_frame->num);
1901 g_assert(preceding_frame == NULL ||
1902 preceding_frame->num <= selected_frame->num);
1903 if (following_frame == NULL) {
1904 /* No frame after the selected frame passed the filter, so we
1905 have to select the last displayed frame before the selected
1907 selected_frame_num = preceding_frame_num;
1908 selected_frame = preceding_frame;
1909 } else if (preceding_frame == NULL) {
1910 /* No frame before the selected frame passed the filter, so we
1911 have to select the first displayed frame after the selected
1913 selected_frame_num = following_frame_num;
1914 selected_frame = following_frame;
1916 /* Frames before and after the selected frame passed the filter, so
1917 we'll select the previous frame */
1918 selected_frame_num = preceding_frame_num;
1919 selected_frame = preceding_frame;
1924 if (selected_frame_num == -1) {
1925 /* There are no frames displayed at all. */
1926 cf_unselect_packet(cf);
1928 /* Either the frame that was selected passed the filter, or we've
1929 found the nearest displayed frame to that frame. Select it, make
1930 it the focus row, and make it visible. */
1931 /* Set to invalid to force update of packet list and packet details */
1932 cf->current_row = -1;
1933 if (selected_frame_num == 0) {
1934 new_packet_list_select_first_row();
1936 if (!new_packet_list_select_row_from_data(selected_frame)) {
1937 /* We didn't find a row corresponding to this frame.
1938 This means that the frame isn't being displayed currently,
1939 so we can't select it. */
1940 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
1941 "%sEnd of capture exceeded!%s\n\n"
1942 "The capture file is probably not fully dissected.",
1943 simple_dialog_primary_start(), simple_dialog_primary_end());
1948 /* Cleanup and release all dfilter resources */
1949 dfilter_free(dfcode);
1954 * Scan trough all frame data and recalculate the ref time
1955 * without rereading the file.
1956 * XXX - do we need a progres bar or is this fast enough?
1959 ref_time_packets(capture_file *cf)
1964 nstime_set_unset(&first_ts);
1965 nstime_set_unset(&prev_dis_ts);
1968 for (framenum = 1; framenum <= cf->count; framenum++) {
1969 fdata = frame_data_sequence_find(cf->frames, framenum);
1971 /* just add some value here until we know if it is being displayed or not */
1972 fdata->cum_bytes = cum_bytes + fdata->pkt_len;
1978 /* If we don't have the time stamp of the first packet in the
1979 capture, it's because this is the first packet. Save the time
1980 stamp of this packet as the time stamp of the first packet. */
1981 if (nstime_is_unset(&first_ts)) {
1982 first_ts = fdata->abs_ts;
1984 /* if this frames is marked as a reference time frame, reset
1985 firstsec and firstusec to this frame */
1986 if(fdata->flags.ref_time){
1987 first_ts = fdata->abs_ts;
1990 /* If we don't have the time stamp of the previous displayed packet,
1991 it's because this is the first displayed packet. Save the time
1992 stamp of this packet as the time stamp of the previous displayed
1994 if (nstime_is_unset(&prev_dis_ts)) {
1995 prev_dis_ts = fdata->abs_ts;
1998 /* Get the time elapsed between the first packet and this packet. */
1999 nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
2001 /* If it's greater than the current elapsed time, set the elapsed time
2002 to it (we check for "greater than" so as not to be confused by
2003 time moving backwards). */
2004 if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
2005 || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
2006 cf->elapsed_time = fdata->rel_ts;
2009 /* If this frame is displayed, get the time elapsed between the
2010 previous displayed packet and this packet. */
2011 if( fdata->flags.passed_dfilter ) {
2012 nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
2013 prev_dis_ts = fdata->abs_ts;
2019 if( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) ){
2020 /* This frame either passed the display filter list or is marked as
2021 a time reference frame. All time reference frames are displayed
2022 even if they dont pass the display filter */
2023 if(fdata->flags.ref_time){
2024 /* if this was a TIME REF frame we should reset the cum_bytes field */
2025 cum_bytes = fdata->pkt_len;
2026 fdata->cum_bytes = cum_bytes;
2028 /* increase cum_bytes with this packets length */
2029 cum_bytes += fdata->pkt_len;
2042 process_specified_packets(capture_file *cf, packet_range_t *range,
2043 const char *string1, const char *string2, gboolean terminate_is_stop,
2044 gboolean (*callback)(capture_file *, frame_data *,
2045 union wtap_pseudo_header *, const guint8 *, void *),
2046 void *callback_args)
2050 union wtap_pseudo_header pseudo_header;
2051 guint8 pd[WTAP_MAX_PACKET_SIZE+1];
2052 psp_return_t ret = PSP_FINISHED;
2054 progdlg_t *progbar = NULL;
2057 gboolean progbar_stop_flag;
2058 GTimeVal progbar_start_time;
2059 gchar progbar_status_str[100];
2060 int progbar_nextstep;
2061 int progbar_quantum;
2062 range_process_e process_this;
2064 /* Update the progress bar when it gets to this value. */
2065 progbar_nextstep = 0;
2066 /* When we reach the value that triggers a progress bar update,
2067 bump that value by this amount. */
2068 progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2069 /* Count of packets at which we've looked. */
2071 /* Progress so far. */
2074 progbar_stop_flag = FALSE;
2075 g_get_current_time(&progbar_start_time);
2077 packet_range_process_init(range);
2079 /* Iterate through all the packets, printing the packets that
2080 were selected by the current display filter. */
2081 for (framenum = 1; framenum <= cf->count; framenum++) {
2082 fdata = frame_data_sequence_find(cf->frames, framenum);
2084 /* Create the progress bar if necessary.
2085 We check on every iteration of the loop, so that it takes no
2086 longer than the standard time to create it (otherwise, for a
2087 large file, we might take considerably longer than that standard
2088 time in order to get to the next progress bar step). */
2089 if (progbar == NULL)
2090 progbar = delayed_create_progress_dlg(string1, string2,
2093 &progbar_start_time,
2096 /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2097 when we update it, we have to run the GTK+ main loop to get it
2098 to repaint what's pending, and doing so may involve an "ioctl()"
2099 to see if there's any pending input from an X server, and doing
2100 that for every packet can be costly, especially on a big file. */
2101 if (progbar_count >= progbar_nextstep) {
2102 /* let's not divide by zero. I should never be started
2103 * with count == 0, so let's assert that
2105 g_assert(cf->count > 0);
2106 progbar_val = (gfloat) progbar_count / cf->count;
2108 if (progbar != NULL) {
2109 g_snprintf(progbar_status_str, sizeof(progbar_status_str),
2110 "%4u of %u packets", progbar_count, cf->count);
2111 update_progress_dlg(progbar, progbar_val, progbar_status_str);
2114 progbar_nextstep += progbar_quantum;
2117 if (progbar_stop_flag) {
2118 /* Well, the user decided to abort the operation. Just stop,
2119 and arrange to return PSP_STOPPED to our caller, so they know
2120 it was stopped explicitly. */
2127 /* do we have to process this packet? */
2128 process_this = packet_range_process_packet(range, fdata);
2129 if (process_this == range_process_next) {
2130 /* this packet uninteresting, continue with next one */
2132 } else if (process_this == range_processing_finished) {
2133 /* all interesting packets processed, stop the loop */
2137 /* Get the packet */
2138 if (!cf_read_frame_r(cf, fdata, &pseudo_header, pd)) {
2139 /* Attempt to get the packet failed. */
2143 /* Process the packet */
2144 if (!callback(cf, fdata, &pseudo_header, pd, callback_args)) {
2145 /* Callback failed. We assume it reported the error appropriately. */
2151 /* We're done printing the packets; destroy the progress bar if
2153 if (progbar != NULL)
2154 destroy_progress_dlg(progbar);
2160 gboolean construct_protocol_tree;
2162 } retap_callback_args_t;
2165 retap_packet(capture_file *cf _U_, frame_data *fdata,
2166 union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2169 retap_callback_args_t *args = argsp;
2172 epan_dissect_init(&edt, args->construct_protocol_tree, FALSE);
2173 tap_queue_init(&edt);
2174 epan_dissect_run(&edt, pseudo_header, pd, fdata, args->cinfo);
2175 tap_push_tapped_queue(&edt);
2176 epan_dissect_cleanup(&edt);
2182 cf_retap_packets(capture_file *cf)
2184 packet_range_t range;
2185 retap_callback_args_t callback_args;
2186 gboolean filtering_tap_listeners;
2189 /* Do we have any tap listeners with filters? */
2190 filtering_tap_listeners = have_filtering_tap_listeners();
2192 tap_flags = union_of_tap_listener_flags();
2194 /* If any tap listeners have filters, or require the protocol tree,
2195 construct the protocol tree. */
2196 callback_args.construct_protocol_tree = filtering_tap_listeners ||
2197 (tap_flags & TL_REQUIRES_PROTO_TREE);
2199 /* If any tap listeners require the columns, construct them. */
2200 callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
2202 /* Reset the tap listeners. */
2203 reset_tap_listeners();
2205 /* Iterate through the list of packets, dissecting all packets and
2206 re-running the taps. */
2207 packet_range_init(&range);
2208 packet_range_process_init(&range);
2209 switch (process_specified_packets(cf, &range, "Recalculating statistics on",
2210 "all packets", TRUE, retap_packet,
2213 /* Completed successfully. */
2217 /* Well, the user decided to abort the refiltering.
2218 Return CF_READ_ABORTED so our caller knows they did that. */
2219 return CF_READ_ABORTED;
2222 /* Error while retapping. */
2223 return CF_READ_ERROR;
2226 g_assert_not_reached();
2231 print_args_t *print_args;
2232 gboolean print_header_line;
2233 char *header_line_buf;
2234 int header_line_buf_len;
2235 gboolean print_formfeed;
2236 gboolean print_separator;
2240 } print_callback_args_t;
2243 print_packet(capture_file *cf, frame_data *fdata,
2244 union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2247 print_callback_args_t *args = argsp;
2254 gboolean proto_tree_needed;
2255 char bookmark_name[9+10+1]; /* "__frameNNNNNNNNNN__\0" */
2256 char bookmark_title[6+10+1]; /* "Frame NNNNNNNNNN__\0" */
2258 /* Create the protocol tree, and make it visible, if we're printing
2259 the dissection or the hex data.
2260 XXX - do we need it if we're just printing the hex data? */
2262 args->print_args->print_dissections != print_dissections_none || args->print_args->print_hex || have_custom_cols(&cf->cinfo);
2263 epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2265 /* Fill in the column information if we're printing the summary
2267 if (args->print_args->print_summary) {
2268 col_custom_prime_edt(&edt, &cf->cinfo);
2269 epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2270 epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2272 epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2274 if (args->print_formfeed) {
2275 if (!new_page(args->print_args->stream))
2278 if (args->print_separator) {
2279 if (!print_line(args->print_args->stream, 0, ""))
2285 * We generate bookmarks, if the output format supports them.
2286 * The name is "__frameN__".
2288 g_snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
2290 if (args->print_args->print_summary) {
2291 if (args->print_header_line) {
2292 if (!print_line(args->print_args->stream, 0, args->header_line_buf))
2294 args->print_header_line = FALSE; /* we might not need to print any more */
2296 cp = &args->line_buf[0];
2298 for (i = 0; i < cf->cinfo.num_cols; i++) {
2299 /* Find the length of the string for this column. */
2300 column_len = (int) strlen(cf->cinfo.col_data[i]);
2301 if (args->col_widths[i] > column_len)
2302 column_len = args->col_widths[i];
2304 /* Make sure there's room in the line buffer for the column; if not,
2305 double its length. */
2306 line_len += column_len + 1; /* "+1" for space */
2307 if (line_len > args->line_buf_len) {
2308 cp_off = (int) (cp - args->line_buf);
2309 args->line_buf_len = 2 * line_len;
2310 args->line_buf = g_realloc(args->line_buf, args->line_buf_len + 1);
2311 cp = args->line_buf + cp_off;
2314 /* Right-justify the packet number column. */
2315 if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2316 g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], cf->cinfo.col_data[i]);
2318 g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], cf->cinfo.col_data[i]);
2320 if (i != cf->cinfo.num_cols - 1)
2326 * Generate a bookmark, using the summary line as the title.
2328 if (!print_bookmark(args->print_args->stream, bookmark_name,
2332 if (!print_line(args->print_args->stream, 0, args->line_buf))
2336 * Generate a bookmark, using "Frame N" as the title, as we're not
2337 * printing the summary line.
2339 g_snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
2340 if (!print_bookmark(args->print_args->stream, bookmark_name,
2343 } /* if (print_summary) */
2345 if (args->print_args->print_dissections != print_dissections_none) {
2346 if (args->print_args->print_summary) {
2347 /* Separate the summary line from the tree with a blank line. */
2348 if (!print_line(args->print_args->stream, 0, ""))
2352 /* Print the information in that tree. */
2353 if (!proto_tree_print(args->print_args, &edt, args->print_args->stream))
2356 /* Print a blank line if we print anything after this (aka more than one packet). */
2357 args->print_separator = TRUE;
2359 /* Print a header line if we print any more packet summaries */
2360 args->print_header_line = TRUE;
2363 if (args->print_args->print_hex) {
2364 /* Print the full packet data as hex. */
2365 if (!print_hex_data(args->print_args->stream, &edt))
2368 /* Print a blank line if we print anything after this (aka more than one packet). */
2369 args->print_separator = TRUE;
2371 /* Print a header line if we print any more packet summaries */
2372 args->print_header_line = TRUE;
2373 } /* if (args->print_args->print_dissections != print_dissections_none) */
2375 epan_dissect_cleanup(&edt);
2377 /* do we want to have a formfeed between each packet from now on? */
2378 if(args->print_args->print_formfeed) {
2379 args->print_formfeed = TRUE;
2385 epan_dissect_cleanup(&edt);
2390 cf_print_packets(capture_file *cf, print_args_t *print_args)
2393 print_callback_args_t callback_args;
2401 callback_args.print_args = print_args;
2402 callback_args.print_header_line = TRUE;
2403 callback_args.header_line_buf = NULL;
2404 callback_args.header_line_buf_len = 256;
2405 callback_args.print_formfeed = FALSE;
2406 callback_args.print_separator = FALSE;
2407 callback_args.line_buf = NULL;
2408 callback_args.line_buf_len = 256;
2409 callback_args.col_widths = NULL;
2411 if (!print_preamble(print_args->stream, cf->filename)) {
2412 destroy_print_stream(print_args->stream);
2413 return CF_PRINT_WRITE_ERROR;
2416 if (print_args->print_summary) {
2417 /* We're printing packet summaries. Allocate the header line buffer
2418 and get the column widths. */
2419 callback_args.header_line_buf = g_malloc(callback_args.header_line_buf_len + 1);
2421 /* Find the widths for each of the columns - maximum of the
2422 width of the title and the width of the data - and construct
2423 a buffer with a line containing the column titles. */
2424 callback_args.col_widths = (gint *) g_malloc(sizeof(gint) * cf->cinfo.num_cols);
2425 cp = &callback_args.header_line_buf[0];
2427 for (i = 0; i < cf->cinfo.num_cols; i++) {
2428 /* Don't pad the last column. */
2429 if (i == cf->cinfo.num_cols - 1)
2430 callback_args.col_widths[i] = 0;
2432 callback_args.col_widths[i] = (gint) strlen(cf->cinfo.col_title[i]);
2433 data_width = get_column_char_width(get_column_format(i));
2434 if (data_width > callback_args.col_widths[i])
2435 callback_args.col_widths[i] = data_width;
2438 /* Find the length of the string for this column. */
2439 column_len = (int) strlen(cf->cinfo.col_title[i]);
2440 if (callback_args.col_widths[i] > column_len)
2441 column_len = callback_args.col_widths[i];
2443 /* Make sure there's room in the line buffer for the column; if not,
2444 double its length. */
2445 line_len += column_len + 1; /* "+1" for space */
2446 if (line_len > callback_args.header_line_buf_len) {
2447 cp_off = (int) (cp - callback_args.header_line_buf);
2448 callback_args.header_line_buf_len = 2 * line_len;
2449 callback_args.header_line_buf = g_realloc(callback_args.header_line_buf,
2450 callback_args.header_line_buf_len + 1);
2451 cp = callback_args.header_line_buf + cp_off;
2454 /* Right-justify the packet number column. */
2455 /* if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2456 g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[i], cf->cinfo.col_title[i]);
2458 g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[i], cf->cinfo.col_title[i]);
2460 if (i != cf->cinfo.num_cols - 1)
2465 /* Now start out the main line buffer with the same length as the
2466 header line buffer. */
2467 callback_args.line_buf_len = callback_args.header_line_buf_len;
2468 callback_args.line_buf = g_malloc(callback_args.line_buf_len + 1);
2469 } /* if (print_summary) */
2471 /* Iterate through the list of packets, printing the packets we were
2473 ret = process_specified_packets(cf, &print_args->range, "Printing",
2474 "selected packets", TRUE, print_packet,
2477 g_free(callback_args.header_line_buf);
2478 g_free(callback_args.line_buf);
2479 g_free(callback_args.col_widths);
2484 /* Completed successfully. */
2488 /* Well, the user decided to abort the printing.
2490 XXX - note that what got generated before they did that
2491 will get printed if we're piping to a print program; we'd
2492 have to write to a file and then hand that to the print
2493 program to make it actually not print anything. */
2497 /* Error while printing.
2499 XXX - note that what got generated before they did that
2500 will get printed if we're piping to a print program; we'd
2501 have to write to a file and then hand that to the print
2502 program to make it actually not print anything. */
2503 destroy_print_stream(print_args->stream);
2504 return CF_PRINT_WRITE_ERROR;
2507 if (!print_finale(print_args->stream)) {
2508 destroy_print_stream(print_args->stream);
2509 return CF_PRINT_WRITE_ERROR;
2512 if (!destroy_print_stream(print_args->stream))
2513 return CF_PRINT_WRITE_ERROR;
2519 write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
2520 union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2526 /* Create the protocol tree, but don't fill in the column information. */
2527 epan_dissect_init(&edt, TRUE, TRUE);
2528 epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2530 /* Write out the information in that tree. */
2531 proto_tree_write_pdml(&edt, fh);
2533 epan_dissect_cleanup(&edt);
2539 cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
2544 fh = ws_fopen(print_args->file, "w");
2546 return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2548 write_pdml_preamble(fh, cf->filename);
2551 return CF_PRINT_WRITE_ERROR;
2554 /* Iterate through the list of packets, printing the packets we were
2556 ret = process_specified_packets(cf, &print_args->range, "Writing PDML",
2557 "selected packets", TRUE,
2558 write_pdml_packet, fh);
2563 /* Completed successfully. */
2567 /* Well, the user decided to abort the printing. */
2571 /* Error while printing. */
2573 return CF_PRINT_WRITE_ERROR;
2576 write_pdml_finale(fh);
2579 return CF_PRINT_WRITE_ERROR;
2582 /* XXX - check for an error */
2589 write_psml_packet(capture_file *cf, frame_data *fdata,
2590 union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2595 gboolean proto_tree_needed;
2597 /* Fill in the column information, only create the protocol tree
2598 if having custom columns. */
2599 proto_tree_needed = have_custom_cols(&cf->cinfo);
2600 epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2601 col_custom_prime_edt(&edt, &cf->cinfo);
2602 epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2603 epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2605 /* Write out the information in that tree. */
2606 proto_tree_write_psml(&edt, fh);
2608 epan_dissect_cleanup(&edt);
2614 cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
2619 fh = ws_fopen(print_args->file, "w");
2621 return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2623 write_psml_preamble(fh);
2626 return CF_PRINT_WRITE_ERROR;
2629 /* Iterate through the list of packets, printing the packets we were
2631 ret = process_specified_packets(cf, &print_args->range, "Writing PSML",
2632 "selected packets", TRUE,
2633 write_psml_packet, fh);
2638 /* Completed successfully. */
2642 /* Well, the user decided to abort the printing. */
2646 /* Error while printing. */
2648 return CF_PRINT_WRITE_ERROR;
2651 write_psml_finale(fh);
2654 return CF_PRINT_WRITE_ERROR;
2657 /* XXX - check for an error */
2664 write_csv_packet(capture_file *cf, frame_data *fdata,
2665 union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2670 gboolean proto_tree_needed;
2672 /* Fill in the column information, only create the protocol tree
2673 if having custom columns. */
2674 proto_tree_needed = have_custom_cols(&cf->cinfo);
2675 epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2676 col_custom_prime_edt(&edt, &cf->cinfo);
2677 epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2678 epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2680 /* Write out the information in that tree. */
2681 proto_tree_write_csv(&edt, fh);
2683 epan_dissect_cleanup(&edt);
2689 cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
2694 fh = ws_fopen(print_args->file, "w");
2696 return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2698 write_csv_preamble(fh);
2701 return CF_PRINT_WRITE_ERROR;
2704 /* Iterate through the list of packets, printing the packets we were
2706 ret = process_specified_packets(cf, &print_args->range, "Writing CSV",
2707 "selected packets", TRUE,
2708 write_csv_packet, fh);
2713 /* Completed successfully. */
2717 /* Well, the user decided to abort the printing. */
2721 /* Error while printing. */
2723 return CF_PRINT_WRITE_ERROR;
2726 write_csv_finale(fh);
2729 return CF_PRINT_WRITE_ERROR;
2732 /* XXX - check for an error */
2739 write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
2740 union wtap_pseudo_header *pseudo_header,
2741 const guint8 *pd, void *argsp)
2746 epan_dissect_init(&edt, TRUE, TRUE);
2747 epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2748 proto_tree_write_carrays(fdata->num, fh, &edt);
2749 epan_dissect_cleanup(&edt);
2755 cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
2760 fh = ws_fopen(print_args->file, "w");
2763 return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2765 write_carrays_preamble(fh);
2769 return CF_PRINT_WRITE_ERROR;
2772 /* Iterate through the list of packets, printing the packets we were
2774 ret = process_specified_packets(cf, &print_args->range,
2776 "selected packets", TRUE,
2777 write_carrays_packet, fh);
2780 /* Completed successfully. */
2783 /* Well, the user decided to abort the printing. */
2786 /* Error while printing. */
2788 return CF_PRINT_WRITE_ERROR;
2791 write_carrays_finale(fh);
2795 return CF_PRINT_WRITE_ERROR;
2803 cf_find_packet_protocol_tree(capture_file *cf, const char *string,
2804 search_direction dir)
2808 mdata.string = string;
2809 mdata.string_len = strlen(string);
2810 return find_packet(cf, match_protocol_tree, &mdata, dir);
2814 cf_find_string_protocol_tree(capture_file *cf, proto_tree *tree, match_data *mdata)
2816 mdata->frame_matched = FALSE;
2817 mdata->string = convert_string_case(cf->sfilter, cf->case_type);
2818 mdata->string_len = strlen(mdata->string);
2820 /* Iterate through all the nodes looking for matching text */
2821 proto_tree_children_foreach(tree, match_subtree_text, mdata);
2822 return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
2826 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
2828 match_data *mdata = criterion;
2831 /* Load the frame's data. */
2832 if (!cf_read_frame(cf, fdata)) {
2833 /* Attempt to get the packet failed. */
2837 /* Construct the protocol tree, including the displayed text */
2838 epan_dissect_init(&edt, TRUE, TRUE);
2839 /* We don't need the column information */
2840 epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
2842 /* Iterate through all the nodes, seeing if they have text that matches. */
2844 mdata->frame_matched = FALSE;
2845 proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
2846 epan_dissect_cleanup(&edt);
2847 return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
2851 match_subtree_text(proto_node *node, gpointer data)
2853 match_data *mdata = (match_data*) data;
2854 const gchar *string = mdata->string;
2855 size_t string_len = mdata->string_len;
2856 capture_file *cf = mdata->cf;
2857 field_info *fi = PNODE_FINFO(node);
2858 gchar label_str[ITEM_LABEL_LENGTH];
2865 g_assert(fi && "dissection with an invisible proto tree?");
2867 if (mdata->frame_matched) {
2868 /* We already had a match; don't bother doing any more work. */
2872 /* Don't match invisible entries. */
2873 if (PROTO_ITEM_IS_HIDDEN(node))
2876 /* was a free format label produced? */
2878 label_ptr = fi->rep->representation;
2880 /* no, make a generic label */
2881 label_ptr = label_str;
2882 proto_item_fill_label(fi, label_str);
2885 /* Does that label match? */
2886 label_len = strlen(label_ptr);
2887 for (i = 0; i < label_len; i++) {
2888 c_char = label_ptr[i];
2890 c_char = toupper(c_char);
2891 if (c_char == string[c_match]) {
2893 if (c_match == string_len) {
2894 /* No need to look further; we have a match */
2895 mdata->frame_matched = TRUE;
2903 /* Recurse into the subtree, if it exists */
2904 if (node->first_child != NULL)
2905 proto_tree_children_foreach(node, match_subtree_text, mdata);
2909 cf_find_packet_summary_line(capture_file *cf, const char *string,
2910 search_direction dir)
2914 mdata.string = string;
2915 mdata.string_len = strlen(string);
2916 return find_packet(cf, match_summary_line, &mdata, dir);
2920 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
2922 match_data *mdata = criterion;
2923 const gchar *string = mdata->string;
2924 size_t string_len = mdata->string_len;
2926 const char *info_column;
2927 size_t info_column_len;
2928 match_result result = MR_NOTMATCHED;
2934 /* Load the frame's data. */
2935 if (!cf_read_frame(cf, fdata)) {
2936 /* Attempt to get the packet failed. */
2940 /* Don't bother constructing the protocol tree */
2941 epan_dissect_init(&edt, FALSE, FALSE);
2942 /* Get the column information */
2943 epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, &cf->cinfo);
2945 /* Find the Info column */
2946 for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
2947 if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
2948 /* Found it. See if we match. */
2949 info_column = edt.pi.cinfo->col_data[colx];
2950 info_column_len = strlen(info_column);
2951 for (i = 0; i < info_column_len; i++) {
2952 c_char = info_column[i];
2954 c_char = toupper(c_char);
2955 if (c_char == string[c_match]) {
2957 if (c_match == string_len) {
2958 result = MR_MATCHED;
2967 epan_dissect_cleanup(&edt);
2974 } cbs_t; /* "Counted byte string" */
2977 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size,
2978 search_direction dir)
2983 info.data_len = string_size;
2985 /* String or hex search? */
2987 /* String search - what type of string? */
2988 switch (cf->scs_type) {
2990 case SCS_ASCII_AND_UNICODE:
2991 return find_packet(cf, match_ascii_and_unicode, &info, dir);
2994 return find_packet(cf, match_ascii, &info, dir);
2997 return find_packet(cf, match_unicode, &info, dir);
3000 g_assert_not_reached();
3004 return find_packet(cf, match_binary, &info, dir);
3008 match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3010 cbs_t *info = criterion;
3011 const guint8 *ascii_text = info->data;
3012 size_t textlen = info->data_len;
3013 match_result result;
3019 /* Load the frame's data. */
3020 if (!cf_read_frame(cf, fdata)) {
3021 /* Attempt to get the packet failed. */
3025 result = MR_NOTMATCHED;
3026 buf_len = fdata->pkt_len;
3028 while (i < buf_len) {
3031 c_char = toupper(c_char);
3032 if (c_char != '\0') {
3033 if (c_char == ascii_text[c_match]) {
3035 if (c_match == textlen) {
3036 result = MR_MATCHED;
3037 cf->search_pos = i; /* Save the position of the last character
3038 for highlighting the field. */
3043 g_assert(i>=c_match);
3044 i -= (guint32)c_match;
3054 match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
3056 cbs_t *info = criterion;
3057 const guint8 *ascii_text = info->data;
3058 size_t textlen = info->data_len;
3059 match_result result;
3065 /* Load the frame's data. */
3066 if (!cf_read_frame(cf, fdata)) {
3067 /* Attempt to get the packet failed. */
3071 result = MR_NOTMATCHED;
3072 buf_len = fdata->pkt_len;
3074 while (i < buf_len) {
3077 c_char = toupper(c_char);
3078 if (c_char == ascii_text[c_match]) {
3080 if (c_match == textlen) {
3081 result = MR_MATCHED;
3082 cf->search_pos = i; /* Save the position of the last character
3083 for highlighting the field. */
3088 g_assert(i>=c_match);
3089 i -= (guint32)c_match;
3099 match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3101 cbs_t *info = criterion;
3102 const guint8 *ascii_text = info->data;
3103 size_t textlen = info->data_len;
3104 match_result result;
3110 /* Load the frame's data. */
3111 if (!cf_read_frame(cf, fdata)) {
3112 /* Attempt to get the packet failed. */
3116 result = MR_NOTMATCHED;
3117 buf_len = fdata->pkt_len;
3119 while (i < buf_len) {
3122 c_char = toupper(c_char);
3123 if (c_char == ascii_text[c_match]) {
3125 if (c_match == textlen) {
3126 result = MR_MATCHED;
3127 cf->search_pos = i; /* Save the position of the last character
3128 for highlighting the field. */
3134 g_assert(i>=(c_match*2));
3135 i -= (guint32)c_match*2;
3144 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
3146 cbs_t *info = criterion;
3147 const guint8 *binary_data = info->data;
3148 size_t datalen = info->data_len;
3149 match_result result;
3154 /* Load the frame's data. */
3155 if (!cf_read_frame(cf, fdata)) {
3156 /* Attempt to get the packet failed. */
3160 result = MR_NOTMATCHED;
3161 buf_len = fdata->pkt_len;
3163 while (i < buf_len) {
3164 if (cf->pd[i] == binary_data[c_match]) {
3166 if (c_match == datalen) {
3167 result = MR_MATCHED;
3168 cf->search_pos = i; /* Save the position of the last character
3169 for highlighting the field. */
3174 g_assert(i>=c_match);
3175 i -= (guint32)c_match;
3184 cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode,
3185 search_direction dir)
3187 return find_packet(cf, match_dfilter, sfcode, dir);
3191 cf_find_packet_dfilter_string(capture_file *cf, const char *filter,
3192 search_direction dir)
3197 if (!dfilter_compile(filter, &sfcode)) {
3199 * XXX - this shouldn't happen, as the filter string is machine
3204 if (sfcode == NULL) {
3206 * XXX - this shouldn't happen, as the filter string is machine
3211 result = find_packet(cf, match_dfilter, sfcode, dir);
3212 dfilter_free(sfcode);
3217 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
3219 dfilter_t *sfcode = criterion;
3221 match_result result;
3223 /* Load the frame's data. */
3224 if (!cf_read_frame(cf, fdata)) {
3225 /* Attempt to get the packet failed. */
3229 epan_dissect_init(&edt, TRUE, FALSE);
3230 epan_dissect_prime_dfilter(&edt, sfcode);
3231 epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
3232 result = dfilter_apply_edt(sfcode, &edt) ? MR_MATCHED : MR_NOTMATCHED;
3233 epan_dissect_cleanup(&edt);
3238 cf_find_packet_marked(capture_file *cf, search_direction dir)
3240 return find_packet(cf, match_marked, NULL, dir);
3244 match_marked(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3246 return fdata->flags.marked ? MR_MATCHED : MR_NOTMATCHED;
3250 cf_find_packet_time_reference(capture_file *cf, search_direction dir)
3252 return find_packet(cf, match_time_reference, NULL, dir);
3256 match_time_reference(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3258 return fdata->flags.ref_time ? MR_MATCHED : MR_NOTMATCHED;
3262 find_packet(capture_file *cf,
3263 match_result (*match_function)(capture_file *, frame_data *, void *),
3264 void *criterion, search_direction dir)
3266 frame_data *start_fd;
3269 frame_data *new_fd = NULL;
3270 progdlg_t *progbar = NULL;
3275 GTimeVal start_time;
3276 gchar status_str[100];
3277 int progbar_nextstep;
3278 int progbar_quantum;
3280 match_result result;
3282 start_fd = cf->current_frame;
3283 if (start_fd != NULL) {
3284 /* Iterate through the list of packets, starting at the packet we've
3285 picked, calling a routine to run the filter on the packet, see if
3286 it matches, and stop if so. */
3288 framenum = start_fd->num;
3290 /* Update the progress bar when it gets to this value. */
3291 progbar_nextstep = 0;
3292 /* When we reach the value that triggers a progress bar update,
3293 bump that value by this amount. */
3294 progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3295 /* Progress so far. */
3299 g_get_current_time(&start_time);
3301 title = cf->sfilter?cf->sfilter:"";
3303 /* Create the progress bar if necessary.
3304 We check on every iteration of the loop, so that it takes no
3305 longer than the standard time to create it (otherwise, for a
3306 large file, we might take considerably longer than that standard
3307 time in order to get to the next progress bar step). */
3308 if (progbar == NULL)
3309 progbar = delayed_create_progress_dlg("Searching", title,
3310 FALSE, &stop_flag, &start_time, progbar_val);
3312 /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3313 when we update it, we have to run the GTK+ main loop to get it
3314 to repaint what's pending, and doing so may involve an "ioctl()"
3315 to see if there's any pending input from an X server, and doing
3316 that for every packet can be costly, especially on a big file. */
3317 if (count >= progbar_nextstep) {
3318 /* let's not divide by zero. I should never be started
3319 * with count == 0, so let's assert that
3321 g_assert(cf->count > 0);
3323 progbar_val = (gfloat) count / cf->count;
3325 if (progbar != NULL) {
3326 g_snprintf(status_str, sizeof(status_str),
3327 "%4u of %u packets", count, cf->count);
3328 update_progress_dlg(progbar, progbar_val, status_str);
3331 progbar_nextstep += progbar_quantum;
3335 /* Well, the user decided to abort the search. Go back to the
3336 frame where we started. */
3341 /* Go past the current frame. */
3342 if (dir == SD_BACKWARD) {
3343 /* Go on to the previous frame. */
3344 if (framenum == 1) {
3346 * XXX - other apps have a bit more of a detailed message
3347 * for this, and instead of offering "OK" and "Cancel",
3348 * they offer things such as "Continue" and "Cancel";
3349 * we need an API for popping up alert boxes with
3350 * {Verb} and "Cancel".
3353 if (prefs.gui_find_wrap)
3355 statusbar_push_temporary_msg("Search reached the beginning. Continuing at end.");
3356 framenum = cf->count; /* wrap around */
3360 statusbar_push_temporary_msg("Search reached the beginning.");
3361 framenum = start_fd->num; /* stay on previous packet */
3366 /* Go on to the next frame. */
3367 if (framenum == cf->count) {
3368 if (prefs.gui_find_wrap)
3370 statusbar_push_temporary_msg("Search reached the end. Continuing at beginning.");
3371 framenum = 1; /* wrap around */
3375 statusbar_push_temporary_msg("Search reached the end.");
3376 framenum = start_fd->num; /* stay on previous packet */
3381 fdata = frame_data_sequence_find(cf->frames, framenum);
3385 /* Is this packet in the display? */
3386 if (fdata->flags.passed_dfilter) {
3387 /* Yes. Does it match the search criterion? */
3388 result = (*match_function)(cf, fdata, criterion);
3389 if (result == MR_ERROR) {
3390 /* Error; our caller has reported the error. Go back to the frame
3391 where we started. */
3394 } else if (result == MR_MATCHED) {
3395 /* Yes. Go to the new frame. */
3401 if (fdata == start_fd) {
3402 /* We're back to the frame we were on originally, and that frame
3403 doesn't match the search filter. The search failed. */
3408 /* We're done scanning the packets; destroy the progress bar if it
3410 if (progbar != NULL)
3411 destroy_progress_dlg(progbar);
3414 if (new_fd != NULL) {
3415 /* Find and select */
3416 cf->search_in_progress = TRUE;
3417 found = new_packet_list_select_row_from_data(new_fd);
3418 cf->search_in_progress = FALSE;
3419 cf->search_pos = 0; /* Reset the position */
3421 /* We didn't find a row corresponding to this frame.
3422 This means that the frame isn't being displayed currently,
3423 so we can't select it. */
3424 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3425 "%sEnd of capture exceeded!%s\n\n"
3426 "The capture file is probably not fully dissected.",
3427 simple_dialog_primary_start(), simple_dialog_primary_end());
3430 return TRUE; /* success */
3432 return FALSE; /* failure */
3436 cf_goto_frame(capture_file *cf, guint fnumber)
3440 fdata = frame_data_sequence_find(cf->frames, fnumber);
3442 if (fdata == NULL) {
3443 /* we didn't find a packet with that packet number */
3444 statusbar_push_temporary_msg("There is no packet number %u.", fnumber);
3445 return FALSE; /* we failed to go to that packet */
3447 if (!fdata->flags.passed_dfilter) {
3448 /* that packet currently isn't displayed */
3449 /* XXX - add it to the set of displayed packets? */
3450 statusbar_push_temporary_msg("Packet number %u isn't displayed.", fnumber);
3451 return FALSE; /* we failed to go to that packet */
3454 if (!new_packet_list_select_row_from_data(fdata)) {
3455 /* We didn't find a row corresponding to this frame.
3456 This means that the frame isn't being displayed currently,
3457 so we can't select it. */
3458 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3459 "%sEnd of capture exceeded!%s\n\n"
3460 "The capture file is probably not fully dissected.",
3461 simple_dialog_primary_start(), simple_dialog_primary_end());
3464 return TRUE; /* we got to that packet */
3468 cf_goto_top_frame(void)
3470 /* Find and select */
3471 new_packet_list_select_first_row();
3472 return TRUE; /* we got to that packet */
3476 cf_goto_bottom_frame(void)
3478 /* Find and select */
3479 new_packet_list_select_last_row();
3480 return TRUE; /* we got to that packet */
3484 * Go to frame specified by currently selected protocol tree item.
3487 cf_goto_framenum(capture_file *cf)
3489 header_field_info *hfinfo;
3492 if (cf->finfo_selected) {
3493 hfinfo = cf->finfo_selected->hfinfo;
3495 if (hfinfo->type == FT_FRAMENUM) {
3496 framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
3498 return cf_goto_frame(cf, framenum);
3505 /* Select the packet on a given row. */
3507 cf_select_packet(capture_file *cf, int row)
3511 /* Get the frame data struct pointer for this frame */
3512 fdata = new_packet_list_get_row_data(row);
3514 if (fdata == NULL) {
3515 /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
3516 the first entry is added to it by "real_insert_row()", that row
3517 is selected (see "real_insert_row()", in "ui/gtk/gtkclist.c", in both
3518 our version and the vanilla GTK+ version).
3520 This means that a "select-row" signal is emitted; this causes
3521 "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
3524 "cf_select_packet()" fetches, above, the data associated with the
3525 row that was selected; however, as "gtk_clist_append()", which
3526 called "real_insert_row()", hasn't yet returned, we haven't yet
3527 associated any data with that row, so we get back a null pointer.
3529 We can't assume that there's only one frame in the frame list,
3530 either, as we may be filtering the display.
3532 We therefore assume that, if "row" is 0, i.e. the first row
3533 is being selected, and "cf->first_displayed" equals
3534 "cf->last_displayed", i.e. there's only one frame being
3535 displayed, that frame is the frame we want.
3537 This means we have to set "cf->first_displayed" and
3538 "cf->last_displayed" before adding the row to the
3539 GtkCList; see the comment in "add_packet_to_packet_list()". */
3541 if (row == 0 && cf->first_displayed == cf->last_displayed)
3542 fdata = frame_data_sequence_find(cf->frames, cf->first_displayed);
3545 /* If fdata _still_ isn't set simply give up. */
3546 if (fdata == NULL) {
3550 /* Get the data in that frame. */
3551 if (!cf_read_frame (cf, fdata)) {
3555 /* Record that this frame is the current frame. */
3556 cf->current_frame = fdata;
3557 cf->current_row = row;
3559 /* Create the logical protocol tree. */
3560 if (cf->edt != NULL)
3561 epan_dissect_free(cf->edt);
3563 /* We don't need the columns here. */
3564 cf->edt = epan_dissect_new(TRUE, TRUE);
3566 tap_build_interesting(cf->edt);
3567 epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
3570 dfilter_macro_build_ftv_cache(cf->edt->tree);
3572 cf_callback_invoke(cf_cb_packet_selected, cf);
3575 /* Unselect the selected packet, if any. */
3577 cf_unselect_packet(capture_file *cf)
3579 /* Destroy the epan_dissect_t for the unselected packet. */
3580 if (cf->edt != NULL) {
3581 epan_dissect_free(cf->edt);
3585 /* No packet is selected. */
3586 cf->current_frame = NULL;
3587 cf->current_row = 0;
3589 cf_callback_invoke(cf_cb_packet_unselected, cf);
3591 /* No protocol tree means no selected field. */
3592 cf_unselect_field(cf);
3595 /* Unset the selected protocol tree field, if any. */
3597 cf_unselect_field(capture_file *cf)
3599 cf->finfo_selected = NULL;
3601 cf_callback_invoke(cf_cb_field_unselected, cf);
3605 * Mark a particular frame.
3608 cf_mark_frame(capture_file *cf, frame_data *frame)
3610 if (! frame->flags.marked) {
3611 frame->flags.marked = TRUE;
3612 if (cf->count > cf->marked_count)
3618 * Unmark a particular frame.
3621 cf_unmark_frame(capture_file *cf, frame_data *frame)
3623 if (frame->flags.marked) {
3624 frame->flags.marked = FALSE;
3625 if (cf->marked_count > 0)
3631 * Ignore a particular frame.
3634 cf_ignore_frame(capture_file *cf, frame_data *frame)
3636 if (! frame->flags.ignored) {
3637 frame->flags.ignored = TRUE;
3638 if (cf->count > cf->ignored_count)
3639 cf->ignored_count++;
3644 * Un-ignore a particular frame.
3647 cf_unignore_frame(capture_file *cf, frame_data *frame)
3649 if (frame->flags.ignored) {
3650 frame->flags.ignored = FALSE;
3651 if (cf->ignored_count > 0)
3652 cf->ignored_count--;
3657 * Read the comment in SHB block
3661 cf_read_shb_comment(capture_file *cf)
3663 wtapng_section_t *shb_inf;
3664 const gchar *temp_str;
3666 /* Get info from SHB */
3667 shb_inf = wtap_file_get_shb_info(cf->wth);
3670 temp_str = shb_inf->opt_comment;
3678 cf_update_capture_comment(capture_file *cf, gchar *comment)
3680 wtapng_section_t *shb_inf;
3682 /* Get info from SHB */
3683 shb_inf = wtap_file_get_shb_info(cf->wth);
3685 /* See if the comment has changed or not */
3686 if (shb_inf && shb_inf->opt_comment) {
3687 if (strcmp(shb_inf->opt_comment, comment) == 0) {
3693 /* The comment has changed, let's update it */
3694 wtap_write_shb_comment(cf->wth, comment);
3695 /* Mark the file as having unsaved changes */
3696 cf->unsaved_changes = TRUE;
3703 } save_callback_args_t;
3706 * Save a capture to a file, in a particular format, saving either
3707 * all packets, all currently-displayed packets, or all marked packets.
3709 * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
3710 * up a message box for the failure.
3713 save_packet(capture_file *cf _U_, frame_data *fdata,
3714 union wtap_pseudo_header *pseudo_header, const guint8 *pd,
3717 save_callback_args_t *args = argsp;
3718 struct wtap_pkthdr hdr;
3721 /* init the wtap header for saving */
3722 /* XXX - these are the only flags that correspond to data that we have
3723 in the frame_data structure and that matter on a per-packet basis.
3725 For WTAP_HAS_CAP_LEN, either the file format has separate "captured"
3726 and "on the wire" lengths, or it doesn't.
3728 For WTAP_HAS_DROP_COUNT, Wiretap doesn't actually supply the value
3731 For WTAP_HAS_PACK_FLAGS, we currently don't save the FCS length
3732 from the packet flags. */
3733 hdr.presence_flags = 0;
3734 if (fdata->flags.has_ts)
3735 hdr.presence_flags |= WTAP_HAS_TS;
3736 if (fdata->flags.has_ts)
3737 hdr.presence_flags |= WTAP_HAS_INTERFACE_ID;
3738 hdr.ts.secs = fdata->abs_ts.secs;
3739 hdr.ts.nsecs = fdata->abs_ts.nsecs;
3740 hdr.caplen = fdata->cap_len;
3741 hdr.len = fdata->pkt_len;
3742 hdr.pkt_encap = fdata->lnk_t;
3744 hdr.interface_id = fdata->interface_id; /* identifier of the interface. */
3746 hdr.opt_comment = fdata->opt_comment; /* NULL if not available */
3749 hdr.pack_flags = /* XXX - 0 for now (any value for "we don't have it"?) */
3751 /* and save the packet */
3752 if (!wtap_dump(args->pdh, &hdr, pseudo_header, pd, &err)) {
3754 /* Wiretap error. */
3757 case WTAP_ERR_UNSUPPORTED_ENCAP:
3759 * This is a problem with the particular frame we're writing;
3760 * note that, and give the frame number.
3762 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3763 "Frame %u has a network type that can't be saved in a \"%s\" file.",
3764 fdata->num, wtap_file_type_string(args->file_type));
3768 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3769 "An error occurred while writing to the file \"%s\": %s.",
3770 args->fname, wtap_strerror(err));
3775 write_failure_alert_box(args->fname, err);
3783 * Can this capture file be saved in any format except by copying the raw data?
3786 cf_can_save_as(capture_file *cf)
3790 for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
3791 /* To save a file with Wiretap, Wiretap has to handle that format,
3792 and its code to handle that format must be able to write a file
3793 with this file's encapsulation type. */
3794 if (wtap_dump_can_open(ft) && wtap_dump_can_write_encap(ft, cf->lnk_t)) {
3795 /* OK, we can write it out in this type. */
3800 /* No, we couldn't save it in any format. */
3805 cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_format, gboolean compressed)
3807 gchar *from_filename;
3811 save_callback_args_t callback_args;
3813 cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
3815 /* don't write over an existing file. */
3816 /* this should've been already checked by our caller, just to be sure... */
3817 if (file_exists(fname)) {
3818 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3819 "%sCapture file: \"%s\" already exists!%s\n\n"
3820 "Please choose a different filename.",
3821 simple_dialog_primary_start(), fname, simple_dialog_primary_end());
3825 packet_range_process_init(range);
3827 if (packet_range_process_all(range) && save_format == cf->cd_t) {
3828 /* We're not filtering packets, and we're saving it in the format
3829 it's already in, so we can just move or copy the raw data. */
3831 if (cf->is_tempfile) {
3832 /* The file being saved is a temporary file from a live
3833 capture, so it doesn't need to stay around under that name;
3834 first, try renaming the capture buffer file to the new name. */
3836 if (ws_rename(cf->filename, fname) == 0) {
3837 /* That succeeded - there's no need to copy the source file. */
3838 from_filename = NULL;
3841 if (errno == EXDEV) {
3842 /* They're on different file systems, so we have to copy the
3845 from_filename = cf->filename;
3847 /* The rename failed, but not because they're on different
3848 file systems - put up an error message. (Or should we
3849 just punt and try to copy? The only reason why I'd
3850 expect the rename to fail and the copy to succeed would
3851 be if we didn't have permission to remove the file from
3852 the temporary directory, and that might be fixable - but
3853 is it worth requiring the user to go off and fix it?) */
3854 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3855 file_rename_error_message(errno), fname);
3861 from_filename = cf->filename;
3864 /* It's a permanent file, so we should copy it, and not remove the
3867 from_filename = cf->filename;
3871 /* Copy the file, if we haven't moved it. */
3872 if (!copy_file_binary_mode(from_filename, fname))
3876 /* Either we're filtering packets, or we're saving in a different
3877 format; we can't do that by copying or moving the capture file,
3878 we have to do it by writing the packets out in Wiretap. */
3880 wtapng_section_t *shb_hdr = NULL;
3881 wtapng_iface_descriptions_t *idb_inf = NULL;
3883 shb_hdr = wtap_file_get_shb_info(cf->wth);
3884 idb_inf = wtap_file_get_idb_info(cf->wth);
3886 pdh = wtap_dump_open_ng(fname, save_format, cf->lnk_t, cf->snap,
3887 compressed, shb_hdr, idb_inf, &err);
3892 cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
3896 /* Add address resolution */
3897 wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
3899 /* XXX - we let the user save a subset of the packets.
3901 If we do that, should we make that file the current file? If so,
3902 it means we can no longer get at the other packets. What does
3905 /* Iterate through the list of packets, processing the packets we were
3908 XXX - we've already called "packet_range_process_init(range)", but
3909 "process_specified_packets()" will do it again. Fortunately,
3910 that's harmless in this case, as we haven't done anything to
3911 "range" since we initialized it. */
3912 callback_args.pdh = pdh;
3913 callback_args.fname = fname;
3914 callback_args.file_type = save_format;
3915 switch (process_specified_packets(cf, range, "Saving", "selected packets",
3916 TRUE, save_packet, &callback_args)) {
3919 /* Completed successfully. */
3923 /* The user decided to abort the saving.
3924 XXX - remove the output file? */
3928 /* Error while saving. */
3929 wtap_dump_close(pdh, &err);
3933 if (!wtap_dump_close(pdh, &err)) {
3934 cf_close_failure_alert_box(fname, err);
3939 cf_callback_invoke(cf_cb_file_save_finished, NULL);
3941 if (packet_range_process_all(range)) {
3942 /* We saved the entire capture, not just some packets from it.
3943 Open and read the file we saved it to.
3945 XXX - this is somewhat of a waste; we already have the
3946 packets, all this gets us is updated file type information
3947 (which we could just stuff into "cf"), and having the new
3948 file be the one we have opened and from which we're reading
3949 the data, and it means we have to spend time opening and
3950 reading the file, which could be a significant amount of
3951 time if the file is large. */
3952 cf->unsaved_changes = FALSE;
3954 if ((cf_open(cf, fname, FALSE, &err)) == CF_OK) {
3955 /* XXX - report errors if this fails?
3956 What should we return if it fails or is aborted? */
3958 switch (cf_read(cf, TRUE)) {
3962 /* Just because we got an error, that doesn't mean we were unable
3963 to read any of the file; we handle what we could get from the
3967 case CF_READ_ABORTED:
3968 /* The user bailed out of re-reading the capture file; the
3969 capture file has been closed - just return (without
3970 changing any menu settings; "cf_close()" set them
3971 correctly for the "no capture file open" state). */
3974 cf_callback_invoke(cf_cb_file_save_reload_finished, cf);
3980 cf_callback_invoke(cf_cb_file_save_failed, NULL);
3985 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
3986 gboolean for_writing, int file_type)
3989 /* Wiretap error. */
3992 case WTAP_ERR_NOT_REGULAR_FILE:
3993 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3994 "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
3998 case WTAP_ERR_RANDOM_OPEN_PIPE:
3999 /* Seen only when opening a capture file for reading. */
4000 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4001 "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.\n"
4002 "To capture from a pipe or FIFO use wireshark -i -",
4006 case WTAP_ERR_FILE_UNKNOWN_FORMAT:
4007 /* Seen only when opening a capture file for reading. */
4008 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4009 "The file \"%s\" isn't a capture file in a format Wireshark understands.",
4013 case WTAP_ERR_UNSUPPORTED:
4014 /* Seen only when opening a capture file for reading. */
4015 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4016 "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
4018 filename, err_info);
4022 case WTAP_ERR_CANT_WRITE_TO_PIPE:
4023 /* Seen only when opening a capture file for writing. */
4024 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4025 "The file \"%s\" is a pipe, and %s capture files can't be "
4026 "written to a pipe.",
4027 filename, wtap_file_type_string(file_type));
4030 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
4031 /* Seen only when opening a capture file for writing. */
4032 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4033 "Wireshark doesn't support writing capture files in that format.");
4036 case WTAP_ERR_UNSUPPORTED_ENCAP:
4038 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4039 "Wireshark can't save this capture in that format.");
4041 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4042 "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
4044 filename, err_info);
4049 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
4051 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4052 "Wireshark can't save this capture in that format.");
4054 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4055 "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
4060 case WTAP_ERR_BAD_FILE:
4061 /* Seen only when opening a capture file for reading. */
4062 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4063 "The file \"%s\" appears to be damaged or corrupt.\n"
4065 filename, err_info);
4069 case WTAP_ERR_CANT_OPEN:
4071 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4072 "The file \"%s\" could not be created for some unknown reason.",
4075 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4076 "The file \"%s\" could not be opened for some unknown reason.",
4081 case WTAP_ERR_SHORT_READ:
4082 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4083 "The file \"%s\" appears to have been cut short"
4084 " in the middle of a packet or other data.",
4088 case WTAP_ERR_SHORT_WRITE:
4089 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4090 "A full header couldn't be written to the file \"%s\".",
4094 case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
4095 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4096 "This file type cannot be written as a compressed file.");
4099 case WTAP_ERR_DECOMPRESS:
4100 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4101 "The compressed file \"%s\" appears to be damaged or corrupt.\n"
4102 "(%s)", filename, err_info);
4107 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4108 "The file \"%s\" could not be %s: %s.",
4110 for_writing ? "created" : "opened",
4111 wtap_strerror(err));
4116 open_failure_alert_box(filename, err, for_writing);
4121 file_rename_error_message(int err)
4124 static char errmsg_errno[1024+1];
4129 errmsg = "The path to the file \"%s\" doesn't exist.";
4133 errmsg = "You don't have permission to move the capture file to \"%s\".";
4137 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4138 "The file \"%%s\" could not be moved: %s.",
4139 wtap_strerror(err));
4140 errmsg = errmsg_errno;
4146 /* Check for write errors - if the file is being written to an NFS server,
4147 a write error may not show up until the file is closed, as NFS clients
4148 might not send writes to the server until the "write()" call finishes,
4149 so that the write may fail on the server but the "write()" may succeed. */
4151 cf_close_failure_alert_box(const char *filename, int err)
4154 /* Wiretap error. */
4157 case WTAP_ERR_CANT_CLOSE:
4158 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4159 "The file \"%s\" couldn't be closed for some unknown reason.",
4163 case WTAP_ERR_SHORT_WRITE:
4164 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4165 "Not all the packets could be written to the file \"%s\".",
4170 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4171 "An error occurred while closing the file \"%s\": %s.",
4172 filename, wtap_strerror(err));
4177 We assume that a close error from the OS is really a write error. */
4178 write_failure_alert_box(filename, err);
4182 /* Reload the current capture file. */
4184 cf_reload(capture_file *cf) {
4186 gboolean is_tempfile;
4189 /* If the file could be opened, "cf_open()" calls "cf_close()"
4190 to get rid of state for the old capture file before filling in state
4191 for the new capture file. "cf_close()" will remove the file if
4192 it's a temporary file; we don't want that to happen (for one thing,
4193 it'd prevent subsequent reopens from working). Remember whether it's
4194 a temporary file, mark it as not being a temporary file, and then
4195 reopen it as the type of file it was.
4197 Also, "cf_close()" will free "cf->filename", so we must make
4198 a copy of it first. */
4199 filename = g_strdup(cf->filename);
4200 is_tempfile = cf->is_tempfile;
4201 cf->is_tempfile = FALSE;
4202 if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
4203 switch (cf_read(cf, FALSE)) {
4207 /* Just because we got an error, that doesn't mean we were unable
4208 to read any of the file; we handle what we could get from the
4212 case CF_READ_ABORTED:
4213 /* The user bailed out of re-reading the capture file; the
4214 capture file has been closed - just free the capture file name
4215 string and return (without changing the last containing
4221 /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
4222 Instead, the file was left open, so we should restore "cf->is_tempfile"
4225 XXX - change the menu? Presumably "cf_open()" will do that;
4226 make sure it does! */
4227 cf->is_tempfile = is_tempfile;
4229 /* "cf_open()" made a copy of the file name we handed it, so
4230 we should free up our copy. */
4240 * indent-tabs-mode: nil
4243 * ex: set shiftwidth=2 tabstop=8 expandtab:
4244 * :indentSize=2:tabSize=8:noTabs=true: