4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
41 #include <wsutil/tempfile.h>
42 #include <wsutil/file_util.h>
43 #include <wsutil/filesystem.h>
44 #include <wsutil/ws_version_info.h>
46 #include <wiretap/merge.h>
48 #include <epan/exceptions.h>
49 #include <epan/epan-int.h>
50 #include <epan/epan.h>
51 #include <epan/column.h>
52 #include <epan/packet.h>
53 #include <epan/column-utils.h>
54 #include <epan/expert.h>
55 #include <epan/prefs.h>
56 #include <epan/dfilter/dfilter.h>
57 #include <epan/epan_dissect.h>
59 #include <epan/dissectors/packet-ber.h>
60 #include <epan/timestamp.h>
61 #include <epan/dfilter/dfilter-macro.h>
62 #include <epan/strutil.h>
63 #include <epan/addr_resolv.h>
66 #include "color_filters.h"
70 #include "frame_tvbuff.h"
72 #include "ui/alert_box.h"
73 #include "ui/simple_dialog.h"
74 #include "ui/main_statusbar.h"
75 #include "ui/progress_dlg.h"
76 #include "ui/ui_util.h"
78 /* Needed for addrinfo */
79 #ifdef HAVE_SYS_TYPES_H
80 # include <sys/types.h>
83 #ifdef HAVE_SYS_SOCKET_H
84 #include <sys/socket.h>
87 #ifdef HAVE_NETINET_IN_H
88 # include <netinet/in.h>
95 #ifdef HAVE_WINSOCK2_H
96 # include <winsock2.h>
99 #if defined(_WIN32) && defined(INET6)
100 # include <ws2tcpip.h>
104 gboolean auto_scroll_live; /* GTK+ only? */
107 static int read_packet(capture_file *cf, dfilter_t *dfcode, epan_dissect_t *edt,
108 column_info *cinfo, gint64 offset);
110 static void rescan_packets(capture_file *cf, const char *action, const char *action_item, gboolean redissect);
117 static match_result match_protocol_tree(capture_file *cf, frame_data *fdata,
119 static void match_subtree_text(proto_node *node, gpointer data);
120 static match_result match_summary_line(capture_file *cf, frame_data *fdata,
122 static match_result match_narrow_and_wide(capture_file *cf, frame_data *fdata,
124 static match_result match_narrow(capture_file *cf, frame_data *fdata,
126 static match_result match_wide(capture_file *cf, frame_data *fdata,
128 static match_result match_binary(capture_file *cf, frame_data *fdata,
130 static match_result match_dfilter(capture_file *cf, frame_data *fdata,
132 static match_result match_marked(capture_file *cf, frame_data *fdata,
134 static match_result match_time_reference(capture_file *cf, frame_data *fdata,
136 static gboolean find_packet(capture_file *cf,
137 match_result (*match_function)(capture_file *, frame_data *, void *),
138 void *criterion, search_direction dir);
140 static const char *cf_get_user_packet_comment(capture_file *cf, const frame_data *fd);
142 static void cf_open_failure_alert_box(const char *filename, int err,
143 gchar *err_info, gboolean for_writing,
145 static void cf_rename_failure_alert_box(const char *filename, int err);
146 static void cf_close_failure_alert_box(const char *filename, int err);
147 static void ref_time_packets(capture_file *cf);
148 /* Update the progress bar this many times when reading a file. */
149 #define N_PROGBAR_UPDATES 100
150 /* We read around 200k/100ms don't update the progress bar more often than that */
151 #define MIN_QUANTUM 200000
152 #define MIN_NUMBER_OF_PACKET 1500
155 * We could probably use g_signal_...() instead of the callbacks below but that
156 * would require linking our CLI programs to libgobject and creating an object
157 * instance for the signals.
160 cf_callback_t cb_fct;
162 } cf_callback_data_t;
164 static GList *cf_callbacks = NULL;
167 cf_callback_invoke(int event, gpointer data)
169 cf_callback_data_t *cb;
170 GList *cb_item = cf_callbacks;
172 /* there should be at least one interested */
173 g_assert(cb_item != NULL);
175 while (cb_item != NULL) {
176 cb = (cf_callback_data_t *)cb_item->data;
177 cb->cb_fct(event, data, cb->user_data);
178 cb_item = g_list_next(cb_item);
184 cf_callback_add(cf_callback_t func, gpointer user_data)
186 cf_callback_data_t *cb;
188 cb = g_new(cf_callback_data_t,1);
190 cb->user_data = user_data;
192 cf_callbacks = g_list_prepend(cf_callbacks, cb);
196 cf_callback_remove(cf_callback_t func, gpointer user_data)
198 cf_callback_data_t *cb;
199 GList *cb_item = cf_callbacks;
201 while (cb_item != NULL) {
202 cb = (cf_callback_data_t *)cb_item->data;
203 if (cb->cb_fct == func && cb->user_data == user_data) {
204 cf_callbacks = g_list_remove(cf_callbacks, cb);
208 cb_item = g_list_next(cb_item);
211 g_assert_not_reached();
215 cf_timestamp_auto_precision(capture_file *cf)
219 /* don't try to get the file's precision if none is opened */
220 if (cf->state == FILE_CLOSED) {
224 /* Set the column widths of those columns that show the time in
225 "command-line-specified" format. */
226 for (i = 0; i < cf->cinfo.num_cols; i++) {
227 if (col_has_time_fmt(&cf->cinfo, i)) {
228 packet_list_resize_column(i);
234 cf_get_computed_elapsed(capture_file *cf)
236 return cf->computed_elapsed;
240 * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
243 static void compute_elapsed(capture_file *cf, GTimeVal *start_time)
248 g_get_current_time(&time_now);
250 delta_time = (time_now.tv_sec - start_time->tv_sec) * 1e6 +
251 time_now.tv_usec - start_time->tv_usec;
253 cf->computed_elapsed = (gulong) (delta_time / 1000); /* ms */
256 static const nstime_t *
257 ws_get_frame_ts(void *data, guint32 frame_num)
259 capture_file *cf = (capture_file *) data;
261 if (cf->prev_dis && cf->prev_dis->num == frame_num)
262 return &cf->prev_dis->abs_ts;
264 if (cf->prev_cap && cf->prev_cap->num == frame_num)
265 return &cf->prev_cap->abs_ts;
268 frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
270 return (fd) ? &fd->abs_ts : NULL;
277 ws_get_user_comment(void *data, const frame_data *fd)
279 capture_file *cf = (capture_file *) data;
281 return cf_get_user_packet_comment(cf, fd);
285 ws_epan_new(capture_file *cf)
287 epan_t *epan = epan_new();
290 epan->get_frame_ts = ws_get_frame_ts;
291 epan->get_interface_name = cap_file_get_interface_name;
292 epan->get_user_comment = ws_get_user_comment;
298 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
303 wth = wtap_open_offline(fname, type, err, &err_info, TRUE);
307 /* The open succeeded. Close whatever capture file we had open,
308 and fill in the information for this file. */
311 /* Initialize the packet header. */
312 wtap_phdr_init(&cf->phdr);
314 /* XXX - we really want to initialize this after we've read all
315 the packets, so we know how much we'll ultimately need. */
316 ws_buffer_init(&cf->buf, 1500);
318 /* Create new epan session for dissection.
319 * (The old one was freed in cf_close().)
321 cf->epan = ws_epan_new(cf);
323 /* We're about to start reading the file. */
324 cf->state = FILE_READ_IN_PROGRESS;
329 /* Set the file name because we need it to set the follow stream filter.
330 XXX - is that still true? We need it for other reasons, though,
332 cf->filename = g_strdup(fname);
334 /* Indicate whether it's a permanent or temporary file. */
335 cf->is_tempfile = is_tempfile;
337 /* No user changes yet. */
338 cf->unsaved_changes = FALSE;
340 cf->computed_elapsed = 0;
342 cf->cd_t = wtap_file_type_subtype(cf->wth);
343 cf->open_type = type;
344 cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
346 cf->packet_comment_count = 0;
347 cf->displayed_count = 0;
348 cf->marked_count = 0;
349 cf->ignored_count = 0;
350 cf->ref_time_count = 0;
351 cf->drops_known = FALSE;
353 cf->snap = wtap_snapshot_length(cf->wth);
355 /* Snapshot length not known. */
356 cf->has_snap = FALSE;
357 cf->snap = WTAP_MAX_PACKET_SIZE;
361 /* Allocate a frame_data_sequence for the frames in this file */
362 cf->frames = new_frame_data_sequence();
364 nstime_set_zero(&cf->elapsed_time);
370 /* Adjust timestamp precision if auto is selected, col width will be adjusted */
371 cf_timestamp_auto_precision(cf);
373 packet_list_queue_draw();
374 cf_callback_invoke(cf_cb_file_opened, cf);
376 if (cf->cd_t == WTAP_FILE_TYPE_SUBTYPE_BER) {
377 /* tell the BER dissector the file name */
378 ber_set_filename(cf->filename);
381 wtap_set_cb_new_ipv4(cf->wth, add_ipv4_name);
382 wtap_set_cb_new_ipv6(cf->wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
387 cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
392 * Add an encapsulation type to cf->linktypes.
395 cf_add_encapsulation_type(capture_file *cf, int encap)
399 for (i = 0; i < cf->linktypes->len; i++) {
400 if (g_array_index(cf->linktypes, gint, i) == encap)
401 return; /* it's already there */
403 /* It's not already there - add it. */
404 g_array_append_val(cf->linktypes, encap);
407 /* Reset everything to a pristine state */
409 cf_close(capture_file *cf)
411 if (cf->state == FILE_CLOSED)
412 return; /* Nothing to do */
414 /* Die if we're in the middle of reading a file. */
415 g_assert(cf->state != FILE_READ_IN_PROGRESS);
417 cf_callback_invoke(cf_cb_file_closing, cf);
419 /* close things, if not already closed before */
420 color_filters_cleanup();
426 /* We have no file open... */
427 if (cf->filename != NULL) {
428 /* If it's a temporary file, remove it. */
430 ws_unlink(cf->filename);
431 g_free(cf->filename);
434 /* ...which means we have no changes to that file to save. */
435 cf->unsaved_changes = FALSE;
437 /* no open_routine type */
438 cf->open_type = WTAP_TYPE_AUTO;
440 /* Clean up the packet header. */
441 wtap_phdr_cleanup(&cf->phdr);
443 /* Free up the packet buffer. */
444 ws_buffer_free(&cf->buf);
446 dfilter_free(cf->rfcode);
448 if (cf->frames != NULL) {
449 free_frame_data_sequence(cf->frames);
452 #ifdef WANT_PACKET_EDITOR
453 if (cf->edited_frames) {
454 g_tree_destroy(cf->edited_frames);
455 cf->edited_frames = NULL;
458 if (cf->frames_user_comments) {
459 g_tree_destroy(cf->frames_user_comments);
460 cf->frames_user_comments = NULL;
462 cf_unselect_packet(cf); /* nothing to select */
463 cf->first_displayed = 0;
464 cf->last_displayed = 0;
466 /* No frames, no frame selected, no field in that frame selected. */
468 cf->current_frame = 0;
470 cf->finfo_selected = NULL;
472 /* No frame link-layer types, either. */
473 if (cf->linktypes != NULL) {
474 g_array_free(cf->linktypes, TRUE);
475 cf->linktypes = NULL;
478 /* Clear the packet list. */
479 packet_list_freeze();
484 nstime_set_zero(&cf->elapsed_time);
486 reset_tap_listeners();
491 /* We have no file open. */
492 cf->state = FILE_CLOSED;
494 cf_callback_invoke(cf_cb_file_closed, cf);
498 calc_progbar_val(capture_file *cf, gint64 size, gint64 file_pos, gchar *status_str, gulong status_size)
502 progbar_val = (gfloat) file_pos / (gfloat) size;
503 if (progbar_val > 1.0) {
505 /* The file probably grew while we were reading it.
506 * Update file size, and try again.
508 size = wtap_file_size(cf->wth, NULL);
511 progbar_val = (gfloat) file_pos / (gfloat) size;
513 /* If it's still > 1, either "wtap_file_size()" failed (in which
514 * case there's not much we can do about it), or the file
515 * *shrank* (in which case there's not much we can do about
516 * it); just clip the progress value at 1.0.
518 if (progbar_val > 1.0f)
522 g_snprintf(status_str, status_size,
523 "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
524 file_pos / 1024, size / 1024);
530 cf_read(capture_file *cf, gboolean reloading)
535 progdlg_t *progbar = NULL;
540 volatile gboolean create_proto_tree;
544 /* Compile the current display filter.
545 * We assume this will not fail since cf->dfilter is only set in
546 * cf_filter IFF the filter was valid.
548 compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
549 g_assert(!cf->dfilter || (compiled && dfcode));
551 /* Get the union of the flags for all tap listeners. */
552 tap_flags = union_of_tap_listener_flags();
554 (dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
556 reset_tap_listeners();
558 name_ptr = g_filename_display_basename(cf->filename);
561 cf_callback_invoke(cf_cb_file_reload_started, cf);
563 cf_callback_invoke(cf_cb_file_read_started, cf);
565 /* Record whether the file is compressed.
566 XXX - do we know this at open time? */
567 cf->iscompressed = wtap_iscompressed(cf->wth);
569 /* The packet list window will be empty until the file is completly loaded */
570 packet_list_freeze();
573 g_get_current_time(&start_time);
575 epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
579 int displayed_once = 0;
587 gint64 progbar_quantum;
588 gint64 progbar_nextstep;
590 gchar status_str[100];
594 cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
596 /* Find the size of the file. */
597 size = wtap_file_size(cf->wth, NULL);
599 /* Update the progress bar when it gets to this value. */
600 progbar_nextstep = 0;
601 /* When we reach the value that triggers a progress bar update,
602 bump that value by this amount. */
604 progbar_quantum = size/N_PROGBAR_UPDATES;
605 if (progbar_quantum < MIN_QUANTUM)
606 progbar_quantum = MIN_QUANTUM;
610 while ((wtap_read(cf->wth, &err, &err_info, &data_offset))) {
613 file_pos = wtap_read_so_far(cf->wth);
615 /* Create the progress bar if necessary.
616 * Check whether it should be created or not every MIN_NUMBER_OF_PACKET
618 if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)) {
619 progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
621 progbar = delayed_create_progress_dlg(cf->window, "Reloading", name_ptr,
622 TRUE, &stop_flag, &start_time, progbar_val);
624 progbar = delayed_create_progress_dlg(cf->window, "Loading", name_ptr,
625 TRUE, &stop_flag, &start_time, progbar_val);
628 /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
629 when we update it, we have to run the GTK+ main loop to get it
630 to repaint what's pending, and doing so may involve an "ioctl()"
631 to see if there's any pending input from an X server, and doing
632 that for every packet can be costly, especially on a big file. */
633 if (file_pos >= progbar_nextstep) {
634 if (progbar != NULL) {
635 progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
636 /* update the packet bar content on the first run or frequently on very large files */
638 if (progbar_quantum > 500000 || displayed_once == 0) {
639 if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->count != 0) {
641 packets_bar_update();
644 #endif /* HAVE_LIBPCAP */
645 update_progress_dlg(progbar, progbar_val, status_str);
647 progbar_nextstep += progbar_quantum;
652 /* Well, the user decided to abort the read. He/She will be warned and
653 it might be enough for him/her to work with the already loaded
655 This is especially true for very large capture files, where you don't
656 want to wait loading the whole file (which may last minutes or even
657 hours even on fast machines) just to see that it was the wrong file. */
660 read_packet(cf, dfcode, &edt, cinfo, data_offset);
663 CATCH(OutOfMemoryError) {
664 simple_message_box(ESD_TYPE_ERROR, NULL,
665 "More information and workarounds can be found at\n"
666 "https://wiki.wireshark.org/KnownBugs/OutOfMemory",
667 "Sorry, but Wireshark has run out of memory and has to terminate now.");
669 /* Could we close the current capture and free up memory from that? */
671 /* we have to terminate, as we cannot recover from the memory error */
677 /* Free the display name */
680 /* Cleanup and release all dfilter resources */
681 if (dfcode != NULL) {
682 dfilter_free(dfcode);
685 epan_dissect_cleanup(&edt);
687 /* We're done reading the file; destroy the progress bar if it was created. */
689 destroy_progress_dlg(progbar);
691 /* We're done reading sequentially through the file. */
692 cf->state = FILE_READ_DONE;
694 /* Close the sequential I/O side, to free up memory it requires. */
695 wtap_sequential_close(cf->wth);
697 /* Allow the protocol dissectors to free up memory that they
698 * don't need after the sequential run-through of the packets. */
699 postseq_cleanup_all_protocols();
701 /* compute the time it took to load the file */
702 compute_elapsed(cf, &start_time);
704 /* Set the file encapsulation type now; we don't know what it is until
705 we've looked at all the packets, as we don't know until then whether
706 there's more than one type (and thus whether it's
707 WTAP_ENCAP_PER_PACKET). */
708 cf->lnk_t = wtap_file_encap(cf->wth);
710 cf->current_frame = frame_data_sequence_find(cf->frames, cf->first_displayed);
715 cf_callback_invoke(cf_cb_file_reload_finished, cf);
717 cf_callback_invoke(cf_cb_file_read_finished, cf);
719 /* If we have any displayed packets to select, select the first of those
720 packets by making the first row the selected row. */
721 if (cf->first_displayed != 0) {
722 packet_list_select_first_row();
726 simple_message_box(ESD_TYPE_WARN, NULL,
727 "The remaining packets in the file were discarded.\n"
729 "As a lot of packets from the original file will be missing,\n"
730 "remember to be careful when saving the current content to a file.\n",
731 "File loading was cancelled.");
732 return CF_READ_ERROR;
736 /* Put up a message box noting that the read failed somewhere along
737 the line. Don't throw out the stuff we managed to read, though,
741 case WTAP_ERR_UNSUPPORTED:
742 simple_error_message_box(
743 "The capture file contains record data that Wireshark doesn't support.\n(%s)",
744 err_info != NULL ? err_info : "no information supplied");
748 case WTAP_ERR_SHORT_READ:
749 simple_error_message_box(
750 "The capture file appears to have been cut short"
751 " in the middle of a packet.");
754 case WTAP_ERR_BAD_FILE:
755 simple_error_message_box(
756 "The capture file appears to be damaged or corrupt.\n(%s)",
757 err_info != NULL ? err_info : "no information supplied");
761 case WTAP_ERR_DECOMPRESS:
762 simple_error_message_box(
763 "The compressed capture file appears to be damaged or corrupt.\n",
764 err_info != NULL ? err_info : "no information supplied");
769 simple_error_message_box(
770 "An error occurred while reading the"
771 " capture file: %s.", wtap_strerror(err));
774 return CF_READ_ERROR;
781 cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
784 volatile int newly_displayed_packets = 0;
787 gboolean create_proto_tree;
791 /* Compile the current display filter.
792 * We assume this will not fail since cf->dfilter is only set in
793 * cf_filter IFF the filter was valid.
795 compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
796 g_assert(!cf->dfilter || (compiled && dfcode));
798 /* Get the union of the flags for all tap listeners. */
799 tap_flags = union_of_tap_listener_flags();
801 (dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
805 packet_list_check_end();
806 /* Don't freeze/thaw the list when doing live capture */
807 /*packet_list_freeze();*/
809 /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: %u new: %u", cf->count, to_read);*/
811 epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
814 gint64 data_offset = 0;
817 cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
819 while (to_read != 0) {
820 wtap_cleareof(cf->wth);
821 if (!wtap_read(cf->wth, err, &err_info, &data_offset)) {
824 if (cf->state == FILE_READ_ABORTED) {
825 /* Well, the user decided to exit Wireshark. Break out of the
826 loop, and let the code below (which is called even if there
827 aren't any packets left to read) exit. */
830 if (read_packet(cf, dfcode, &edt, (column_info *) cinfo, data_offset) != -1) {
831 newly_displayed_packets++;
836 CATCH(OutOfMemoryError) {
837 simple_message_box(ESD_TYPE_ERROR, NULL,
838 "More information and workarounds can be found at\n"
839 "https://wiki.wireshark.org/KnownBugs/OutOfMemory",
840 "Sorry, but Wireshark has run out of memory and has to terminate now.");
842 /* Could we close the current capture and free up memory from that? */
843 return CF_READ_ABORTED;
845 /* we have to terminate, as we cannot recover from the memory error */
851 /* Update the file encapsulation; it might have changed based on the
852 packets we've read. */
853 cf->lnk_t = wtap_file_encap(cf->wth);
855 /* Cleanup and release all dfilter resources */
856 if (dfcode != NULL) {
857 dfilter_free(dfcode);
860 epan_dissect_cleanup(&edt);
862 /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: count %u state: %u err: %u",
863 cf->count, cf->state, *err);*/
865 /* Don't freeze/thaw the list when doing live capture */
866 /*packet_list_thaw();*/
867 /* With the new packet list the first packet
868 * isn't automatically selected.
870 if (!cf->current_frame)
871 packet_list_select_first_row();
873 /* moving to the end of the packet list - if the user requested so and
874 we have some new packets. */
875 if (newly_displayed_packets && auto_scroll_live && cf->count != 0)
876 packet_list_moveto_end();
878 if (cf->state == FILE_READ_ABORTED) {
879 /* Well, the user decided to exit Wireshark. Return CF_READ_ABORTED
880 so that our caller can kill off the capture child process;
881 this will cause an EOF on the pipe from the child, so
882 "cf_finish_tail()" will be called, and it will clean up
884 return CF_READ_ABORTED;
885 } else if (*err != 0) {
886 /* We got an error reading the capture file.
887 XXX - pop up a dialog box instead? */
888 if (err_info != NULL) {
889 g_warning("Error \"%s\" while reading \"%s\" (\"%s\")",
890 wtap_strerror(*err), cf->filename, err_info);
893 g_warning("Error \"%s\" while reading \"%s\"",
894 wtap_strerror(*err), cf->filename);
896 return CF_READ_ERROR;
902 cf_fake_continue_tail(capture_file *cf) {
903 cf->state = FILE_READ_DONE;
907 cf_finish_tail(capture_file *cf, int *err)
914 gboolean create_proto_tree;
918 /* Compile the current display filter.
919 * We assume this will not fail since cf->dfilter is only set in
920 * cf_filter IFF the filter was valid.
922 compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
923 g_assert(!cf->dfilter || (compiled && dfcode));
925 /* Get the union of the flags for all tap listeners. */
926 tap_flags = union_of_tap_listener_flags();
927 cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
929 (dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
931 if (cf->wth == NULL) {
933 return CF_READ_ERROR;
936 packet_list_check_end();
937 /* Don't freeze/thaw the list when doing live capture */
938 /*packet_list_freeze();*/
940 epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
942 while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
943 if (cf->state == FILE_READ_ABORTED) {
944 /* Well, the user decided to abort the read. Break out of the
945 loop, and let the code below (which is called even if there
946 aren't any packets left to read) exit. */
949 read_packet(cf, dfcode, &edt, cinfo, data_offset);
952 /* Cleanup and release all dfilter resources */
953 if (dfcode != NULL) {
954 dfilter_free(dfcode);
957 epan_dissect_cleanup(&edt);
959 /* Don't freeze/thaw the list when doing live capture */
960 /*packet_list_thaw();*/
962 if (cf->state == FILE_READ_ABORTED) {
963 /* Well, the user decided to abort the read. We're only called
964 when the child capture process closes the pipe to us (meaning
965 it's probably exited), so we can just close the capture
966 file; we return CF_READ_ABORTED so our caller can do whatever
967 is appropriate when that happens. */
969 return CF_READ_ABORTED;
972 if (auto_scroll_live && cf->count != 0)
973 packet_list_moveto_end();
975 /* We're done reading sequentially through the file. */
976 cf->state = FILE_READ_DONE;
978 /* We're done reading sequentially through the file; close the
979 sequential I/O side, to free up memory it requires. */
980 wtap_sequential_close(cf->wth);
982 /* Allow the protocol dissectors to free up memory that they
983 * don't need after the sequential run-through of the packets. */
984 postseq_cleanup_all_protocols();
986 /* Update the file encapsulation; it might have changed based on the
987 packets we've read. */
988 cf->lnk_t = wtap_file_encap(cf->wth);
990 /* Update the details in the file-set dialog, as the capture file
991 * has likely grown since we first stat-ed it */
992 fileset_update_file(cf->filename);
995 /* We got an error reading the capture file.
996 XXX - pop up a dialog box? */
997 if (err_info != NULL) {
998 g_warning("Error \"%s\" while reading \"%s\" (\"%s\")",
999 wtap_strerror(*err), cf->filename, err_info);
1002 g_warning("Error \"%s\" while reading \"%s\"",
1003 wtap_strerror(*err), cf->filename);
1005 return CF_READ_ERROR;
1010 #endif /* HAVE_LIBPCAP */
1013 cf_get_display_name(capture_file *cf)
1017 /* Return a name to use in displays */
1018 if (!cf->is_tempfile) {
1019 /* Get the last component of the file name, and use that. */
1021 displayname = g_filename_display_basename(cf->filename);
1023 displayname=g_strdup("(No file)");
1026 /* The file we read is a temporary file from a live capture or
1027 a merge operation; we don't mention its name, but, if it's
1028 from a capture, give the source of the capture. */
1030 displayname = g_strdup(cf->source);
1032 displayname = g_strdup("(Untitled)");
1038 void cf_set_tempfile_source(capture_file *cf, gchar *source) {
1044 cf->source = g_strdup(source);
1046 cf->source = g_strdup("");
1050 const gchar *cf_get_tempfile_source(capture_file *cf) {
1058 /* XXX - use a macro instead? */
1060 cf_get_packet_count(capture_file *cf)
1065 /* XXX - use a macro instead? */
1067 cf_is_tempfile(capture_file *cf)
1069 return cf->is_tempfile;
1072 void cf_set_tempfile(capture_file *cf, gboolean is_tempfile)
1074 cf->is_tempfile = is_tempfile;
1078 /* XXX - use a macro instead? */
1079 void cf_set_drops_known(capture_file *cf, gboolean drops_known)
1081 cf->drops_known = drops_known;
1084 /* XXX - use a macro instead? */
1085 void cf_set_drops(capture_file *cf, guint32 drops)
1090 /* XXX - use a macro instead? */
1091 gboolean cf_get_drops_known(capture_file *cf)
1093 return cf->drops_known;
1096 /* XXX - use a macro instead? */
1097 guint32 cf_get_drops(capture_file *cf)
1102 void cf_set_rfcode(capture_file *cf, dfilter_t *rfcode)
1104 cf->rfcode = rfcode;
1108 add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
1109 epan_dissect_t *edt, dfilter_t *dfcode, column_info *cinfo,
1110 struct wtap_pkthdr *phdr, const guint8 *buf, gboolean add_to_packet_list)
1114 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1115 &cf->ref, cf->prev_dis);
1116 cf->prev_cap = fdata;
1118 if (dfcode != NULL) {
1119 epan_dissect_prime_dfilter(edt, dfcode);
1122 /* Dissect the frame. */
1123 epan_dissect_run_with_taps(edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, buf), fdata, cinfo);
1125 /* If we don't have a display filter, set "passed_dfilter" to 1. */
1126 if (dfcode != NULL) {
1127 fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, edt) ? 1 : 0;
1129 if (fdata->flags.passed_dfilter) {
1130 /* This frame passed the display filter but it may depend on other
1131 * (potentially not displayed) frames. Find those frames and mark them
1134 g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
1137 fdata->flags.passed_dfilter = 1;
1139 if (fdata->flags.passed_dfilter || fdata->flags.ref_time)
1140 cf->displayed_count++;
1142 if (add_to_packet_list) {
1143 /* We fill the needed columns from new_packet_list */
1144 row = packet_list_append(cinfo, fdata);
1147 if (fdata->flags.passed_dfilter || fdata->flags.ref_time)
1149 frame_data_set_after_dissect(fdata, &cf->cum_bytes);
1150 cf->prev_dis = fdata;
1152 /* If we haven't yet seen the first frame, this is it.
1154 XXX - we must do this before we add the row to the display,
1155 as, if the display's GtkCList's selection mode is
1156 GTK_SELECTION_BROWSE, when the first entry is added to it,
1157 "cf_select_packet()" will be called, and it will fetch the row
1158 data for the 0th row, and will get a null pointer rather than
1159 "fdata", as "gtk_clist_append()" won't yet have returned and
1160 thus "gtk_clist_set_row_data()" won't yet have been called.
1162 We thus need to leave behind bread crumbs so that
1163 "cf_select_packet()" can find this frame. See the comment
1164 in "cf_select_packet()". */
1165 if (cf->first_displayed == 0)
1166 cf->first_displayed = fdata->num;
1168 /* This is the last frame we've seen so far. */
1169 cf->last_displayed = fdata->num;
1172 epan_dissect_reset(edt);
1176 /* read in a new packet */
1177 /* returns the row of the new packet in the packet list or -1 if not displayed */
1179 read_packet(capture_file *cf, dfilter_t *dfcode, epan_dissect_t *edt,
1180 column_info *cinfo, gint64 offset)
1182 struct wtap_pkthdr *phdr = wtap_phdr(cf->wth);
1183 const guint8 *buf = wtap_buf_ptr(cf->wth);
1190 /* Add this packet's link-layer encapsulation type to cf->linktypes, if
1191 it's not already there.
1192 XXX - yes, this is O(N), so if every packet had a different
1193 link-layer encapsulation type, it'd be O(N^2) to read the file, but
1194 there are probably going to be a small number of encapsulation types
1196 cf_add_encapsulation_type(cf, phdr->pkt_encap);
1198 /* The frame number of this packet is one more than the count of
1199 frames in the file so far. */
1200 framenum = cf->count + 1;
1202 frame_data_init(&fdlocal, framenum, phdr, offset, cf->cum_bytes);
1206 epan_dissect_t rf_edt;
1208 epan_dissect_init(&rf_edt, cf->epan, TRUE, FALSE);
1209 epan_dissect_prime_dfilter(&rf_edt, cf->rfcode);
1210 epan_dissect_run(&rf_edt, cf->cd_t, phdr, frame_tvbuff_new(&fdlocal, buf), &fdlocal, NULL);
1211 passed = dfilter_apply_edt(cf->rfcode, &rf_edt);
1212 epan_dissect_cleanup(&rf_edt);
1216 /* This does a shallow copy of fdlocal, which is good enough. */
1217 fdata = frame_data_sequence_add(cf->frames, &fdlocal);
1220 if (phdr->opt_comment != NULL)
1221 cf->packet_comment_count++;
1222 cf->f_datalen = offset + fdlocal.cap_len;
1224 if (!cf->redissecting) {
1225 row = add_packet_to_packet_list(fdata, cf, edt, dfcode,
1226 cinfo, phdr, buf, TRUE);
1234 cf_merge_files(char **out_filenamep, int in_file_count,
1235 char *const *in_filenames, int file_type, gboolean do_append)
1237 merge_in_file_t *in_files, *in_file;
1242 int open_err, read_err, write_err, close_err;
1243 gchar *err_info, *write_err_info = NULL;
1246 gboolean got_read_error = FALSE, got_write_error = FALSE;
1248 progdlg_t *progbar = NULL;
1250 gint64 f_len, file_pos;
1252 GTimeVal start_time;
1253 gchar status_str[100];
1254 gint64 progbar_nextstep;
1255 gint64 progbar_quantum;
1256 gchar *display_basename;
1257 int selected_frame_type;
1258 gboolean fake_interface_ids = FALSE;
1260 /* open the input files */
1261 if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
1262 &open_err, &err_info, &err_fileno)) {
1264 cf_open_failure_alert_box(in_filenames[err_fileno], open_err, err_info,
1269 if (*out_filenamep != NULL) {
1270 out_filename = *out_filenamep;
1271 out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
1275 out_fd = create_tempfile(&tmpname, "wireshark");
1278 out_filename = g_strdup(tmpname);
1279 *out_filenamep = out_filename;
1283 merge_close_in_files(in_file_count, in_files);
1285 cf_open_failure_alert_box(out_filename, open_err, NULL, TRUE, file_type);
1289 selected_frame_type = merge_select_frame_type(in_file_count, in_files);
1291 /* If we are trying to merge a number of libpcap files with different encapsulation types
1292 * change the output file type to pcapng and create SHB and IDB:s for the new file use the
1293 * interface index stored in in_files per file to change the phdr before writing the datablock.
1294 * XXX should it be an option to convert to pcapng?
1296 * We need something similar when merging pcapng files possibly with an option to say
1297 * the same interface(s) used in all in files. SHBs comments should be merged together.
1299 if ((selected_frame_type == WTAP_ENCAP_PER_PACKET)&&(file_type == WTAP_FILE_TYPE_SUBTYPE_PCAP)) {
1300 /* Write output in pcapng format */
1301 wtapng_section_t *shb_hdr;
1302 wtapng_iface_descriptions_t *idb_inf, *idb_inf_merge_file;
1303 wtapng_if_descr_t int_data, *file_int_data;
1304 GString *comment_gstr;
1306 fake_interface_ids = TRUE;
1307 /* Create SHB info */
1308 shb_hdr = wtap_file_get_shb_info(in_files[0].wth);
1309 comment_gstr = g_string_new("");
1310 g_string_append_printf(comment_gstr, "%s \n",shb_hdr->opt_comment);
1311 g_string_append_printf(comment_gstr, "File created by merging: \n");
1312 file_type = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
1314 for (i = 0; i < in_file_count; i++) {
1315 g_string_append_printf(comment_gstr, "File%d: %s \n",i+1,in_files[i].filename);
1317 shb_hdr->section_length = -1;
1319 shb_hdr->opt_comment = g_string_free(comment_gstr, FALSE); /* NULL if not available */
1320 shb_hdr->shb_hardware = NULL; /* NULL if not available, UTF-8 string containing the */
1321 /* description of the hardware used to create this section. */
1322 shb_hdr->shb_os = NULL; /* NULL if not available, UTF-8 string containing the name */
1323 /* of the operating system used to create this section. */
1324 shb_hdr->shb_user_appl = g_strdup("Wireshark"); /* NULL if not available, UTF-8 string containing the name */
1325 /* of the application used to create this section. */
1327 /* create fake IDB info */
1328 idb_inf = g_new(wtapng_iface_descriptions_t,1);
1329 /* TODO make this the number of DIFFERENT encapsulation types
1330 * check that snaplength is the same too?
1332 idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
1334 for (i = 0; i < in_file_count; i++) {
1335 idb_inf_merge_file = wtap_file_get_idb_info(in_files[i].wth);
1336 /* read the interface data from the in file to our combined interfca data */
1337 file_int_data = &g_array_index (idb_inf_merge_file->interface_data, wtapng_if_descr_t, 0);
1338 int_data.wtap_encap = file_int_data->wtap_encap;
1339 int_data.time_units_per_second = file_int_data->time_units_per_second;
1340 int_data.link_type = file_int_data->link_type;
1341 int_data.snap_len = file_int_data->snap_len;
1342 int_data.if_name = g_strdup(file_int_data->if_name);
1343 int_data.opt_comment = NULL;
1344 int_data.if_description = NULL;
1345 int_data.if_speed = 0;
1346 int_data.if_tsresol = 6;
1347 int_data.if_filter_str = NULL;
1348 int_data.bpf_filter_len = 0;
1349 int_data.if_filter_bpf_bytes = NULL;
1350 int_data.if_os = NULL;
1351 int_data.if_fcslen = -1;
1352 int_data.num_stat_entries = 0; /* Number of ISB:s */
1353 int_data.interface_statistics = NULL;
1355 g_array_append_val(idb_inf->interface_data, int_data);
1356 g_free(idb_inf_merge_file);
1358 /* Set fake interface Id in per file data */
1359 in_files[i].interface_id = i;
1362 pdh = wtap_dump_fdopen_ng(out_fd, file_type,
1363 selected_frame_type,
1364 merge_max_snapshot_length(in_file_count, in_files),
1365 FALSE /* compressed */, shb_hdr, idb_inf /* wtapng_iface_descriptions_t *idb_inf */, &open_err);
1369 merge_close_in_files(in_file_count, in_files);
1371 cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
1378 pdh = wtap_dump_fdopen(out_fd, file_type,
1379 selected_frame_type,
1380 merge_max_snapshot_length(in_file_count, in_files),
1381 FALSE /* compressed */, &open_err);
1384 merge_close_in_files(in_file_count, in_files);
1386 cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
1392 /* Get the sum of the sizes of all the files. */
1394 for (i = 0; i < in_file_count; i++)
1395 f_len += in_files[i].size;
1397 /* Update the progress bar when it gets to this value. */
1398 progbar_nextstep = 0;
1399 /* When we reach the value that triggers a progress bar update,
1400 bump that value by this amount. */
1401 progbar_quantum = f_len/N_PROGBAR_UPDATES;
1402 /* Progress so far. */
1406 g_get_current_time(&start_time);
1408 /* do the merge (or append) */
1411 in_file = merge_append_read_packet(in_file_count, in_files, &read_err,
1414 in_file = merge_read_packet(in_file_count, in_files, &read_err,
1416 if (in_file == NULL) {
1421 if (read_err != 0) {
1422 /* I/O error reading from in_file */
1423 got_read_error = TRUE;
1427 /* Get the sum of the data offsets in all of the files. */
1429 for (i = 0; i < in_file_count; i++)
1430 data_offset += in_files[i].data_offset;
1432 /* Create the progress bar if necessary.
1433 We check on every iteration of the loop, so that it takes no
1434 longer than the standard time to create it (otherwise, for a
1435 large file, we might take considerably longer than that standard
1436 time in order to get to the next progress bar step). */
1437 if (progbar == NULL) {
1438 progbar = delayed_create_progress_dlg(NULL, "Merging", "files",
1439 FALSE, &stop_flag, &start_time, progbar_val);
1442 /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1443 when we update it, we have to run the GTK+ main loop to get it
1444 to repaint what's pending, and doing so may involve an "ioctl()"
1445 to see if there's any pending input from an X server, and doing
1446 that for every packet can be costly, especially on a big file. */
1447 if (data_offset >= progbar_nextstep) {
1448 /* Get the sum of the seek positions in all of the files. */
1450 for (i = 0; i < in_file_count; i++)
1451 file_pos += wtap_read_so_far(in_files[i].wth);
1452 progbar_val = (gfloat) file_pos / (gfloat) f_len;
1453 if (progbar_val > 1.0f) {
1454 /* Some file probably grew while we were reading it.
1455 That "shouldn't happen", so we'll just clip the progress
1459 if (progbar != NULL) {
1460 g_snprintf(status_str, sizeof(status_str),
1461 "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
1462 file_pos / 1024, f_len / 1024);
1463 update_progress_dlg(progbar, progbar_val, status_str);
1465 progbar_nextstep += progbar_quantum;
1469 /* Well, the user decided to abort the merge. */
1473 /* If we have WTAP_ENCAP_PER_PACKET and the infiles are of type
1474 * WTAP_FILE_TYPE_SUBTYPE_PCAP, we need to set the interface id
1475 * in the paket header = the interface index we used in the IDBs
1476 * interface description for this file(encapsulation type).
1478 if (fake_interface_ids) {
1479 struct wtap_pkthdr *phdr;
1481 phdr = wtap_phdr(in_file->wth);
1482 phdr->interface_id = in_file->interface_id;
1483 phdr->presence_flags = phdr->presence_flags | WTAP_HAS_INTERFACE_ID;
1485 if (!wtap_dump(pdh, wtap_phdr(in_file->wth),
1486 wtap_buf_ptr(in_file->wth), &write_err, &write_err_info)) {
1487 got_write_error = TRUE;
1492 /* We're done merging the files; destroy the progress bar if it was created. */
1493 if (progbar != NULL)
1494 destroy_progress_dlg(progbar);
1496 merge_close_in_files(in_file_count, in_files);
1497 if (!got_write_error) {
1498 if (!wtap_dump_close(pdh, &write_err))
1499 got_write_error = TRUE;
1502 * We already got a write error; no need to report another
1503 * write error on close.
1505 * Don't overwrite the earlier write error.
1507 (void)wtap_dump_close(pdh, &close_err);
1510 if (got_read_error) {
1512 * Find the file on which we got the error, and report the error.
1514 for (i = 0; i < in_file_count; i++) {
1515 if (in_files[i].state == GOT_ERROR) {
1516 /* Put up a message box noting that a read failed somewhere along
1518 display_basename = g_filename_display_basename(in_files[i].filename);
1521 case WTAP_ERR_SHORT_READ:
1522 simple_error_message_box(
1523 "The capture file %s appears to have been cut short"
1524 " in the middle of a packet.", display_basename);
1527 case WTAP_ERR_BAD_FILE:
1528 simple_error_message_box(
1529 "The capture file %s appears to be damaged or corrupt.\n(%s)",
1530 display_basename, err_info);
1534 case WTAP_ERR_DECOMPRESS:
1535 simple_error_message_box(
1536 "The compressed capture file %s appears to be damaged or corrupt.\n"
1537 "(%s)", display_basename,
1538 err_info != NULL ? err_info : "no information supplied");
1543 simple_error_message_box(
1544 "An error occurred while reading the"
1545 " capture file %s: %s.",
1546 display_basename, wtap_strerror(read_err));
1549 g_free(display_basename);
1554 if (got_write_error) {
1555 /* Put up an alert box for the write error. */
1556 if (write_err < 0) {
1557 /* Wiretap error. */
1558 switch (write_err) {
1560 case WTAP_ERR_UNWRITABLE_ENCAP:
1562 * This is a problem with the particular frame we're writing and
1563 * the file type and subtype we're writing; note that, and report
1564 * the frame number and file type/subtype.
1566 display_basename = g_filename_display_basename(in_file ? in_file->filename : "UNKNOWN");
1567 simple_error_message_box(
1568 "Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file.",
1569 in_file ? in_file->packet_num : 0, display_basename,
1570 wtap_file_type_subtype_string(file_type));
1571 g_free(display_basename);
1574 case WTAP_ERR_PACKET_TOO_LARGE:
1576 * This is a problem with the particular frame we're writing and
1577 * the file type and subtype we're writing; note that, and report
1578 * the frame number and file type/subtype.
1580 display_basename = g_filename_display_basename(in_file ? in_file->filename : "UNKNOWN");
1581 simple_error_message_box(
1582 "Frame %u of \"%s\" is too large for a \"%s\" file.",
1583 in_file ? in_file->packet_num : 0, display_basename,
1584 wtap_file_type_subtype_string(file_type));
1585 g_free(display_basename);
1588 case WTAP_ERR_UNWRITABLE_REC_TYPE:
1590 * This is a problem with the particular record we're writing and
1591 * the file type and subtype we're writing; note that, and report
1592 * the record number and file type/subtype.
1594 display_basename = g_filename_display_basename(in_file ? in_file->filename : "UNKNOWN");
1595 simple_error_message_box(
1596 "Record %u of \"%s\" has a record type that can't be saved in a \"%s\" file.",
1597 in_file ? in_file->packet_num : 0, display_basename,
1598 wtap_file_type_subtype_string(file_type));
1599 g_free(display_basename);
1602 case WTAP_ERR_UNWRITABLE_REC_DATA:
1604 * This is a problem with the particular record we're writing and
1605 * the file type and subtype we're writing; note that, and report
1606 * the frame number and file type/subtype.
1608 display_basename = g_filename_display_basename(in_file ? in_file->filename : "UNKNOWN");
1609 simple_error_message_box(
1610 "Record %u of \"%s\" has data that can't be saved in a \"%s\" file.\n(%s)",
1611 in_file ? in_file->packet_num : 0, display_basename,
1612 wtap_file_type_subtype_string(file_type),
1613 write_err_info != NULL ? write_err_info : "no information supplied");
1614 g_free(write_err_info);
1615 g_free(display_basename);
1619 display_basename = g_filename_display_basename(out_filename);
1620 simple_error_message_box(
1621 "An error occurred while writing to the file \"%s\": %s.",
1622 out_filename, wtap_strerror(write_err));
1623 g_free(display_basename);
1628 write_failure_alert_box(out_filename, write_err);
1632 if (got_read_error || got_write_error || stop_flag) {
1633 /* Callers aren't expected to treat an error or an explicit abort
1634 differently - we put up error dialogs ourselves, so they don't
1642 cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force)
1644 const char *filter_new = dftext ? dftext : "";
1645 const char *filter_old = cf->dfilter ? cf->dfilter : "";
1648 GTimeVal start_time;
1650 /* if new filter equals old one, do nothing unless told to do so */
1651 if (!force && strcmp(filter_new, filter_old) == 0) {
1657 if (dftext == NULL) {
1658 /* The new filter is an empty filter (i.e., display all packets).
1659 * so leave dfcode==NULL
1663 * We have a filter; make a copy of it (as we'll be saving it),
1664 * and try to compile it.
1666 dftext = g_strdup(dftext);
1667 if (!dfilter_compile(dftext, &dfcode, &err_msg)) {
1668 /* The attempt failed; report an error. */
1669 simple_message_box(ESD_TYPE_ERROR, NULL,
1670 "See the help for a description of the display filter syntax.",
1671 "\"%s\" isn't a valid display filter: %s",
1679 if (dfcode == NULL) {
1680 /* Yes - free the filter text, and set it to null. */
1686 /* We have a valid filter. Replace the current filter. */
1687 g_free(cf->dfilter);
1688 cf->dfilter = dftext;
1689 g_get_current_time(&start_time);
1692 /* Now rescan the packet list, applying the new filter, but not
1693 throwing away information constructed on a previous pass. */
1694 if (dftext == NULL) {
1695 rescan_packets(cf, "Resetting", "Filter", FALSE);
1697 rescan_packets(cf, "Filtering", dftext, FALSE);
1700 /* Cleanup and release all dfilter resources */
1701 dfilter_free(dfcode);
1707 cf_reftime_packets(capture_file *cf)
1709 ref_time_packets(cf);
1713 cf_redissect_packets(capture_file *cf)
1715 if (cf->state != FILE_CLOSED) {
1716 rescan_packets(cf, "Reprocessing", "all packets", TRUE);
1721 cf_read_record_r(capture_file *cf, const frame_data *fdata,
1722 struct wtap_pkthdr *phdr, Buffer *buf)
1726 gchar *display_basename;
1728 #ifdef WANT_PACKET_EDITOR
1729 /* if fdata->file_off == -1 it means packet was edited, and we must find data inside edited_frames tree */
1730 if (G_UNLIKELY(fdata->file_off == -1)) {
1731 const modified_frame_data *frame = (const modified_frame_data *) g_tree_lookup(cf->edited_frames, GINT_TO_POINTER(fdata->num));
1734 simple_error_message_box("fdata->file_off == -1, but can't find modified frame.");
1738 *phdr = frame->phdr;
1739 ws_buffer_assure_space(buf, frame->phdr.caplen);
1740 memcpy(ws_buffer_start_ptr(buf), frame->pd, frame->phdr.caplen);
1745 if (!wtap_seek_read(cf->wth, fdata->file_off, phdr, buf, &err, &err_info)) {
1746 display_basename = g_filename_display_basename(cf->filename);
1749 case WTAP_ERR_BAD_FILE:
1750 simple_error_message_box("An error occurred while reading from the file \"%s\": %s.\n(%s)",
1751 display_basename, wtap_strerror(err),
1752 err_info != NULL ? err_info : "no information supplied");
1757 simple_error_message_box(
1758 "An error occurred while reading from the file \"%s\": %s.",
1759 display_basename, wtap_strerror(err));
1762 g_free(display_basename);
1769 cf_read_record(capture_file *cf, frame_data *fdata)
1771 return cf_read_record_r(cf, fdata, &cf->phdr, &cf->buf);
1774 /* Rescan the list of packets, reconstructing the CList.
1776 "action" describes why we're doing this; it's used in the progress
1779 "action_item" describes what we're doing; it's used in the progress
1782 "redissect" is TRUE if we need to make the dissectors reconstruct
1783 any state information they have (because a preference that affects
1784 some dissector has changed, meaning some dissector might construct
1785 its state differently from the way it was constructed the last time). */
1787 rescan_packets(capture_file *cf, const char *action, const char *action_item, gboolean redissect)
1789 /* Rescan packets new packet list */
1792 progdlg_t *progbar = NULL;
1795 frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
1796 int selected_frame_num, preceding_frame_num, following_frame_num, prev_frame_num;
1797 gboolean selected_frame_seen;
1799 GTimeVal start_time;
1800 gchar status_str[100];
1801 int progbar_nextstep;
1802 int progbar_quantum;
1806 gboolean create_proto_tree;
1808 gboolean add_to_packet_list = FALSE;
1810 guint32 frames_count;
1812 /* Compile the current display filter.
1813 * We assume this will not fail since cf->dfilter is only set in
1814 * cf_filter IFF the filter was valid.
1816 compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
1817 g_assert(!cf->dfilter || (compiled && dfcode));
1819 /* Get the union of the flags for all tap listeners. */
1820 tap_flags = union_of_tap_listener_flags();
1821 cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
1823 (dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
1825 reset_tap_listeners();
1826 /* Which frame, if any, is the currently selected frame?
1827 XXX - should the selected frame or the focus frame be the "current"
1828 frame, that frame being the one from which "Find Frame" searches
1830 selected_frame = cf->current_frame;
1832 /* Mark frame num as not found */
1833 selected_frame_num = -1;
1835 /* Freeze the packet list while we redo it, so we don't get any
1836 screen updates while it happens. */
1837 packet_list_freeze();
1840 /* We need to re-initialize all the state information that protocols
1841 keep, because some preference that controls a dissector has changed,
1842 which might cause the state information to be constructed differently
1843 by that dissector. */
1845 /* We might receive new packets while redissecting, and we don't
1846 want to dissect those before their time. */
1847 cf->redissecting = TRUE;
1849 /* 'reset' dissection session */
1850 epan_free(cf->epan);
1851 cf->epan = ws_epan_new(cf);
1852 cf->cinfo.epan = cf->epan;
1854 /* We need to redissect the packets so we have to discard our old
1855 * packet list store. */
1856 packet_list_clear();
1857 add_to_packet_list = TRUE;
1860 /* We don't yet know which will be the first and last frames displayed. */
1861 cf->first_displayed = 0;
1862 cf->last_displayed = 0;
1864 /* We currently don't display any packets */
1865 cf->displayed_count = 0;
1867 /* Iterate through the list of frames. Call a routine for each frame
1868 to check whether it should be displayed and, if so, add it to
1869 the display list. */
1871 cf->prev_dis = NULL;
1872 cf->prev_cap = NULL;
1875 /* Update the progress bar when it gets to this value. */
1876 progbar_nextstep = 0;
1877 /* When we reach the value that triggers a progress bar update,
1878 bump that value by this amount. */
1879 progbar_quantum = cf->count/N_PROGBAR_UPDATES;
1880 /* Count of packets at which we've looked. */
1882 /* Progress so far. */
1886 g_get_current_time(&start_time);
1888 /* no previous row yet */
1889 prev_frame_num = -1;
1892 preceding_frame_num = -1;
1893 preceding_frame = NULL;
1894 following_frame_num = -1;
1895 following_frame = NULL;
1897 selected_frame_seen = FALSE;
1899 frames_count = cf->count;
1901 epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
1903 for (framenum = 1; framenum <= frames_count; framenum++) {
1904 fdata = frame_data_sequence_find(cf->frames, framenum);
1906 /* Create the progress bar if necessary.
1907 We check on every iteration of the loop, so that it takes no
1908 longer than the standard time to create it (otherwise, for a
1909 large file, we might take considerably longer than that standard
1910 time in order to get to the next progress bar step). */
1911 if (progbar == NULL)
1912 progbar = delayed_create_progress_dlg(cf->window, action, action_item, TRUE,
1913 &stop_flag, &start_time,
1916 /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1917 when we update it, we have to run the GTK+ main loop to get it
1918 to repaint what's pending, and doing so may involve an "ioctl()"
1919 to see if there's any pending input from an X server, and doing
1920 that for every packet can be costly, especially on a big file. */
1921 if (count >= progbar_nextstep) {
1922 /* let's not divide by zero. I should never be started
1923 * with count == 0, so let's assert that
1925 g_assert(cf->count > 0);
1926 progbar_val = (gfloat) count / frames_count;
1928 if (progbar != NULL) {
1929 g_snprintf(status_str, sizeof(status_str),
1930 "%4u of %u frames", count, frames_count);
1931 update_progress_dlg(progbar, progbar_val, status_str);
1934 progbar_nextstep += progbar_quantum;
1938 /* Well, the user decided to abort the filtering. Just stop.
1940 XXX - go back to the previous filter? Users probably just
1941 want not to wait for a filtering operation to finish;
1942 unless we cancel by having no filter, reverting to the
1943 previous filter will probably be even more expensive than
1944 continuing the filtering, as it involves going back to the
1945 beginning and filtering, and even with no filter we currently
1946 have to re-generate the entire clist, which is also expensive.
1948 I'm not sure what Network Monitor does, but it doesn't appear
1949 to give you an unfiltered display if you cancel. */
1956 /* Since all state for the frame was destroyed, mark the frame
1957 * as not visited, free the GSList referring to the state
1958 * data (the per-frame data itself was freed by
1959 * "init_dissection()"), and null out the GSList pointer. */
1960 frame_data_reset(fdata);
1961 frames_count = cf->count;
1964 /* Frame dependencies from the previous dissection/filtering are no longer valid. */
1965 fdata->flags.dependent_of_displayed = 0;
1967 if (!cf_read_record(cf, fdata))
1968 break; /* error reading the frame */
1970 /* If the previous frame is displayed, and we haven't yet seen the
1971 selected frame, remember that frame - it's the closest one we've
1972 yet seen before the selected frame. */
1973 if (prev_frame_num != -1 && !selected_frame_seen && prev_frame->flags.passed_dfilter) {
1974 preceding_frame_num = prev_frame_num;
1975 preceding_frame = prev_frame;
1978 add_packet_to_packet_list(fdata, cf, &edt, dfcode,
1980 ws_buffer_start_ptr(&cf->buf),
1981 add_to_packet_list);
1983 /* If this frame is displayed, and this is the first frame we've
1984 seen displayed after the selected frame, remember this frame -
1985 it's the closest one we've yet seen at or after the selected
1987 if (fdata->flags.passed_dfilter && selected_frame_seen && following_frame_num == -1) {
1988 following_frame_num = fdata->num;
1989 following_frame = fdata;
1991 if (fdata == selected_frame) {
1992 selected_frame_seen = TRUE;
1993 if (fdata->flags.passed_dfilter)
1994 selected_frame_num = fdata->num;
1997 /* Remember this frame - it'll be the previous frame
1998 on the next pass through the loop. */
1999 prev_frame_num = fdata->num;
2003 epan_dissect_cleanup(&edt);
2005 /* We are done redissecting the packet list. */
2006 cf->redissecting = FALSE;
2009 frames_count = cf->count;
2010 /* Clear out what remains of the visited flags and per-frame data
2013 XXX - that may cause various forms of bogosity when dissecting
2014 these frames, as they won't have been seen by this sequential
2015 pass, but the only alternative I see is to keep scanning them
2016 even though the user requested that the scan stop, and that
2017 would leave the user stuck with an Wireshark grinding on
2018 until it finishes. Should we just stick them with that? */
2019 for (; framenum <= frames_count; framenum++) {
2020 fdata = frame_data_sequence_find(cf->frames, framenum);
2021 frame_data_reset(fdata);
2025 /* We're done filtering the packets; destroy the progress bar if it
2027 if (progbar != NULL)
2028 destroy_progress_dlg(progbar);
2030 /* Unfreeze the packet list. */
2031 if (!add_to_packet_list)
2032 packet_list_recreate_visible_rows();
2034 /* Compute the time it took to filter the file */
2035 compute_elapsed(cf, &start_time);
2039 if (selected_frame_num == -1) {
2040 /* The selected frame didn't pass the filter. */
2041 if (selected_frame == NULL) {
2042 /* That's because there *was* no selected frame. Make the first
2043 displayed frame the current frame. */
2044 selected_frame_num = 0;
2046 /* Find the nearest displayed frame to the selected frame (whether
2047 it's before or after that frame) and make that the current frame.
2048 If the next and previous displayed frames are equidistant from the
2049 selected frame, choose the next one. */
2050 g_assert(following_frame == NULL ||
2051 following_frame->num >= selected_frame->num);
2052 g_assert(preceding_frame == NULL ||
2053 preceding_frame->num <= selected_frame->num);
2054 if (following_frame == NULL) {
2055 /* No frame after the selected frame passed the filter, so we
2056 have to select the last displayed frame before the selected
2058 selected_frame_num = preceding_frame_num;
2059 selected_frame = preceding_frame;
2060 } else if (preceding_frame == NULL) {
2061 /* No frame before the selected frame passed the filter, so we
2062 have to select the first displayed frame after the selected
2064 selected_frame_num = following_frame_num;
2065 selected_frame = following_frame;
2067 /* Frames before and after the selected frame passed the filter, so
2068 we'll select the previous frame */
2069 selected_frame_num = preceding_frame_num;
2070 selected_frame = preceding_frame;
2075 if (selected_frame_num == -1) {
2076 /* There are no frames displayed at all. */
2077 cf_unselect_packet(cf);
2079 /* Either the frame that was selected passed the filter, or we've
2080 found the nearest displayed frame to that frame. Select it, make
2081 it the focus row, and make it visible. */
2082 /* Set to invalid to force update of packet list and packet details */
2083 cf->current_row = -1;
2084 if (selected_frame_num == 0) {
2085 packet_list_select_first_row();
2087 if (!packet_list_select_row_from_data(selected_frame)) {
2088 /* We didn't find a row corresponding to this frame.
2089 This means that the frame isn't being displayed currently,
2090 so we can't select it. */
2091 simple_message_box(ESD_TYPE_INFO, NULL,
2092 "The capture file is probably not fully dissected.",
2093 "End of capture exceeded.");
2098 /* Cleanup and release all dfilter resources */
2099 dfilter_free(dfcode);
2104 * Scan trough all frame data and recalculate the ref time
2105 * without rereading the file.
2106 * XXX - do we need a progres bar or is this fast enough?
2109 ref_time_packets(capture_file *cf)
2116 cf->prev_dis = NULL;
2119 for (framenum = 1; framenum <= cf->count; framenum++) {
2120 fdata = frame_data_sequence_find(cf->frames, framenum);
2122 /* just add some value here until we know if it is being displayed or not */
2123 fdata->cum_bytes = cf->cum_bytes + fdata->pkt_len;
2129 /* If we don't have the time stamp of the first packet in the
2130 capture, it's because this is the first packet. Save the time
2131 stamp of this packet as the time stamp of the first packet. */
2132 if (cf->ref == NULL)
2134 /* if this frames is marked as a reference time frame, reset
2135 firstsec and firstusec to this frame */
2136 if (fdata->flags.ref_time)
2139 /* If we don't have the time stamp of the previous displayed packet,
2140 it's because this is the first displayed packet. Save the time
2141 stamp of this packet as the time stamp of the previous displayed
2143 if (cf->prev_dis == NULL) {
2144 cf->prev_dis = fdata;
2147 /* Get the time elapsed between the first packet and this packet. */
2148 fdata->frame_ref_num = (fdata != cf->ref) ? cf->ref->num : 0;
2149 nstime_delta(&rel_ts, &fdata->abs_ts, &cf->ref->abs_ts);
2151 /* If it's greater than the current elapsed time, set the elapsed time
2152 to it (we check for "greater than" so as not to be confused by
2153 time moving backwards). */
2154 if ((gint32)cf->elapsed_time.secs < rel_ts.secs
2155 || ((gint32)cf->elapsed_time.secs == rel_ts.secs && (gint32)cf->elapsed_time.nsecs < rel_ts.nsecs)) {
2156 cf->elapsed_time = rel_ts;
2159 /* If this frame is displayed, get the time elapsed between the
2160 previous displayed packet and this packet. */
2161 if ( fdata->flags.passed_dfilter ) {
2162 fdata->prev_dis_num = cf->prev_dis->num;
2163 cf->prev_dis = fdata;
2169 if ( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) ) {
2170 /* This frame either passed the display filter list or is marked as
2171 a time reference frame. All time reference frames are displayed
2172 even if they don't pass the display filter */
2173 if (fdata->flags.ref_time) {
2174 /* if this was a TIME REF frame we should reset the cum_bytes field */
2175 cf->cum_bytes = fdata->pkt_len;
2176 fdata->cum_bytes = cf->cum_bytes;
2178 /* increase cum_bytes with this packets length */
2179 cf->cum_bytes += fdata->pkt_len;
2192 process_specified_records(capture_file *cf, packet_range_t *range,
2193 const char *string1, const char *string2, gboolean terminate_is_stop,
2194 gboolean (*callback)(capture_file *, frame_data *,
2195 struct wtap_pkthdr *, const guint8 *, void *),
2196 void *callback_args)
2201 psp_return_t ret = PSP_FINISHED;
2203 progdlg_t *progbar = NULL;
2206 gboolean progbar_stop_flag;
2207 GTimeVal progbar_start_time;
2208 gchar progbar_status_str[100];
2209 int progbar_nextstep;
2210 int progbar_quantum;
2211 range_process_e process_this;
2212 struct wtap_pkthdr phdr;
2214 wtap_phdr_init(&phdr);
2215 ws_buffer_init(&buf, 1500);
2217 /* Update the progress bar when it gets to this value. */
2218 progbar_nextstep = 0;
2219 /* When we reach the value that triggers a progress bar update,
2220 bump that value by this amount. */
2221 progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2222 /* Count of packets at which we've looked. */
2224 /* Progress so far. */
2227 progbar_stop_flag = FALSE;
2228 g_get_current_time(&progbar_start_time);
2231 packet_range_process_init(range);
2233 /* Iterate through all the packets, printing the packets that
2234 were selected by the current display filter. */
2235 for (framenum = 1; framenum <= cf->count; framenum++) {
2236 fdata = frame_data_sequence_find(cf->frames, framenum);
2238 /* Create the progress bar if necessary.
2239 We check on every iteration of the loop, so that it takes no
2240 longer than the standard time to create it (otherwise, for a
2241 large file, we might take considerably longer than that standard
2242 time in order to get to the next progress bar step). */
2243 if (progbar == NULL)
2244 progbar = delayed_create_progress_dlg(cf->window, string1, string2,
2247 &progbar_start_time,
2250 /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2251 when we update it, we have to run the GTK+ main loop to get it
2252 to repaint what's pending, and doing so may involve an "ioctl()"
2253 to see if there's any pending input from an X server, and doing
2254 that for every packet can be costly, especially on a big file. */
2255 if (progbar_count >= progbar_nextstep) {
2256 /* let's not divide by zero. I should never be started
2257 * with count == 0, so let's assert that
2259 g_assert(cf->count > 0);
2260 progbar_val = (gfloat) progbar_count / cf->count;
2262 if (progbar != NULL) {
2263 g_snprintf(progbar_status_str, sizeof(progbar_status_str),
2264 "%4u of %u packets", progbar_count, cf->count);
2265 update_progress_dlg(progbar, progbar_val, progbar_status_str);
2268 progbar_nextstep += progbar_quantum;
2271 if (progbar_stop_flag) {
2272 /* Well, the user decided to abort the operation. Just stop,
2273 and arrange to return PSP_STOPPED to our caller, so they know
2274 it was stopped explicitly. */
2281 if (range != NULL) {
2282 /* do we have to process this packet? */
2283 process_this = packet_range_process_packet(range, fdata);
2284 if (process_this == range_process_next) {
2285 /* this packet uninteresting, continue with next one */
2287 } else if (process_this == range_processing_finished) {
2288 /* all interesting packets processed, stop the loop */
2293 /* Get the packet */
2294 if (!cf_read_record_r(cf, fdata, &phdr, &buf)) {
2295 /* Attempt to get the packet failed. */
2299 /* Process the packet */
2300 if (!callback(cf, fdata, &phdr, ws_buffer_start_ptr(&buf), callback_args)) {
2301 /* Callback failed. We assume it reported the error appropriately. */
2307 /* We're done printing the packets; destroy the progress bar if
2309 if (progbar != NULL)
2310 destroy_progress_dlg(progbar);
2312 wtap_phdr_cleanup(&phdr);
2313 ws_buffer_free(&buf);
2321 } retap_callback_args_t;
2324 retap_packet(capture_file *cf, frame_data *fdata,
2325 struct wtap_pkthdr *phdr, const guint8 *pd,
2328 retap_callback_args_t *args = (retap_callback_args_t *)argsp;
2330 epan_dissect_run_with_taps(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, args->cinfo);
2331 epan_dissect_reset(&args->edt);
2337 cf_retap_packets(capture_file *cf)
2339 packet_range_t range;
2340 retap_callback_args_t callback_args;
2341 gboolean construct_protocol_tree;
2342 gboolean filtering_tap_listeners;
2346 /* Presumably the user closed the capture file. */
2348 return CF_READ_ABORTED;
2351 /* Do we have any tap listeners with filters? */
2352 filtering_tap_listeners = have_filtering_tap_listeners();
2354 tap_flags = union_of_tap_listener_flags();
2356 /* If any tap listeners have filters, or require the protocol tree,
2357 construct the protocol tree. */
2358 construct_protocol_tree = filtering_tap_listeners ||
2359 (tap_flags & TL_REQUIRES_PROTO_TREE);
2361 /* If any tap listeners require the columns, construct them. */
2362 callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
2364 /* Reset the tap listeners. */
2365 reset_tap_listeners();
2367 epan_dissect_init(&callback_args.edt, cf->epan, construct_protocol_tree, FALSE);
2369 /* Iterate through the list of packets, dissecting all packets and
2370 re-running the taps. */
2371 packet_range_init(&range, cf);
2372 packet_range_process_init(&range);
2374 ret = process_specified_records(cf, &range, "Recalculating statistics on",
2375 "all packets", TRUE, retap_packet,
2378 epan_dissect_cleanup(&callback_args.edt);
2382 /* Completed successfully. */
2386 /* Well, the user decided to abort the refiltering.
2387 Return CF_READ_ABORTED so our caller knows they did that. */
2388 return CF_READ_ABORTED;
2391 /* Error while retapping. */
2392 return CF_READ_ERROR;
2395 g_assert_not_reached();
2400 print_args_t *print_args;
2401 gboolean print_header_line;
2402 char *header_line_buf;
2403 int header_line_buf_len;
2404 gboolean print_formfeed;
2405 gboolean print_separator;
2409 int num_visible_cols;
2412 } print_callback_args_t;
2415 print_packet(capture_file *cf, frame_data *fdata,
2416 struct wtap_pkthdr *phdr, const guint8 *pd,
2419 print_callback_args_t *args = (print_callback_args_t *)argsp;
2425 char bookmark_name[9+10+1]; /* "__frameNNNNNNNNNN__\0" */
2426 char bookmark_title[6+10+1]; /* "Frame NNNNNNNNNN__\0" */
2428 /* Fill in the column information if we're printing the summary
2430 if (args->print_args->print_summary) {
2431 col_custom_prime_edt(&args->edt, &cf->cinfo);
2432 epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
2433 epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
2435 epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
2437 if (args->print_formfeed) {
2438 if (!new_page(args->print_args->stream))
2441 if (args->print_separator) {
2442 if (!print_line(args->print_args->stream, 0, ""))
2448 * We generate bookmarks, if the output format supports them.
2449 * The name is "__frameN__".
2451 g_snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
2453 if (args->print_args->print_summary) {
2454 if (!args->print_args->print_col_headings)
2455 args->print_header_line = FALSE;
2456 if (args->print_header_line) {
2457 if (!print_line(args->print_args->stream, 0, args->header_line_buf))
2459 args->print_header_line = FALSE; /* we might not need to print any more */
2461 cp = &args->line_buf[0];
2463 for (i = 0; i < args->num_visible_cols; i++) {
2464 /* Find the length of the string for this column. */
2465 column_len = (int) strlen(cf->cinfo.col_data[args->visible_cols[i]]);
2466 if (args->col_widths[i] > column_len)
2467 column_len = args->col_widths[i];
2469 /* Make sure there's room in the line buffer for the column; if not,
2470 double its length. */
2471 line_len += column_len + 1; /* "+1" for space */
2472 if (line_len > args->line_buf_len) {
2473 cp_off = (int) (cp - args->line_buf);
2474 args->line_buf_len = 2 * line_len;
2475 args->line_buf = (char *)g_realloc(args->line_buf, args->line_buf_len + 1);
2476 cp = args->line_buf + cp_off;
2479 /* Right-justify the packet number column. */
2480 if (cf->cinfo.col_fmt[args->visible_cols[i]] == COL_NUMBER)
2481 g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], cf->cinfo.col_data[args->visible_cols[i]]);
2483 g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], cf->cinfo.col_data[args->visible_cols[i]]);
2485 if (i != args->num_visible_cols - 1)
2491 * Generate a bookmark, using the summary line as the title.
2493 if (!print_bookmark(args->print_args->stream, bookmark_name,
2497 if (!print_line(args->print_args->stream, 0, args->line_buf))
2501 * Generate a bookmark, using "Frame N" as the title, as we're not
2502 * printing the summary line.
2504 g_snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
2505 if (!print_bookmark(args->print_args->stream, bookmark_name,
2508 } /* if (print_summary) */
2510 if (args->print_args->print_dissections != print_dissections_none) {
2511 if (args->print_args->print_summary) {
2512 /* Separate the summary line from the tree with a blank line. */
2513 if (!print_line(args->print_args->stream, 0, ""))
2517 /* Print the information in that tree. */
2518 if (!proto_tree_print(args->print_args, &args->edt, NULL, args->print_args->stream))
2521 /* Print a blank line if we print anything after this (aka more than one packet). */
2522 args->print_separator = TRUE;
2524 /* Print a header line if we print any more packet summaries */
2525 if (args->print_args->print_col_headings)
2526 args->print_header_line = TRUE;
2529 if (args->print_args->print_hex) {
2530 if (args->print_args->print_summary || (args->print_args->print_dissections != print_dissections_none)) {
2531 if (!print_line(args->print_args->stream, 0, ""))
2534 /* Print the full packet data as hex. */
2535 if (!print_hex_data(args->print_args->stream, &args->edt))
2538 /* Print a blank line if we print anything after this (aka more than one packet). */
2539 args->print_separator = TRUE;
2541 /* Print a header line if we print any more packet summaries */
2542 if (args->print_args->print_col_headings)
2543 args->print_header_line = TRUE;
2544 } /* if (args->print_args->print_dissections != print_dissections_none) */
2546 epan_dissect_reset(&args->edt);
2548 /* do we want to have a formfeed between each packet from now on? */
2549 if (args->print_args->print_formfeed) {
2550 args->print_formfeed = TRUE;
2556 epan_dissect_reset(&args->edt);
2561 cf_print_packets(capture_file *cf, print_args_t *print_args)
2563 print_callback_args_t callback_args;
2566 int i, cp_off, column_len, line_len;
2567 int num_visible_col = 0, last_visible_col = 0, visible_col_count;
2571 gboolean proto_tree_needed;
2573 callback_args.print_args = print_args;
2574 callback_args.print_header_line = print_args->print_col_headings;
2575 callback_args.header_line_buf = NULL;
2576 callback_args.header_line_buf_len = 256;
2577 callback_args.print_formfeed = FALSE;
2578 callback_args.print_separator = FALSE;
2579 callback_args.line_buf = NULL;
2580 callback_args.line_buf_len = 256;
2581 callback_args.col_widths = NULL;
2582 callback_args.num_visible_cols = 0;
2583 callback_args.visible_cols = NULL;
2585 if (!print_preamble(print_args->stream, cf->filename, get_ws_vcs_version_info())) {
2586 destroy_print_stream(print_args->stream);
2587 return CF_PRINT_WRITE_ERROR;
2590 if (print_args->print_summary) {
2591 /* We're printing packet summaries. Allocate the header line buffer
2592 and get the column widths. */
2593 callback_args.header_line_buf = (char *)g_malloc(callback_args.header_line_buf_len + 1);
2595 /* Find the number of visible columns and the last visible column */
2596 for (i = 0; i < prefs.num_cols; i++) {
2598 clp = g_list_nth(prefs.col_list, i);
2599 if (clp == NULL) /* Sanity check, Invalid column requested */
2602 cfmt = (fmt_data *) clp->data;
2603 if (cfmt->visible) {
2605 last_visible_col = i;
2609 /* Find the widths for each of the columns - maximum of the
2610 width of the title and the width of the data - and construct
2611 a buffer with a line containing the column titles. */
2612 callback_args.num_visible_cols = num_visible_col;
2613 callback_args.col_widths = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2614 callback_args.visible_cols = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2615 cp = &callback_args.header_line_buf[0];
2617 visible_col_count = 0;
2618 for (i = 0; i < cf->cinfo.num_cols; i++) {
2620 clp = g_list_nth(prefs.col_list, i);
2621 if (clp == NULL) /* Sanity check, Invalid column requested */
2624 cfmt = (fmt_data *) clp->data;
2625 if (cfmt->visible == FALSE)
2628 /* Save the order of visible columns */
2629 callback_args.visible_cols[visible_col_count] = i;
2631 /* Don't pad the last column. */
2632 if (i == last_visible_col)
2633 callback_args.col_widths[visible_col_count] = 0;
2635 callback_args.col_widths[visible_col_count] = (gint) strlen(cf->cinfo.col_title[i]);
2636 data_width = get_column_char_width(get_column_format(i));
2637 if (data_width > callback_args.col_widths[visible_col_count])
2638 callback_args.col_widths[visible_col_count] = data_width;
2641 /* Find the length of the string for this column. */
2642 column_len = (int) strlen(cf->cinfo.col_title[i]);
2643 if (callback_args.col_widths[i] > column_len)
2644 column_len = callback_args.col_widths[visible_col_count];
2646 /* Make sure there's room in the line buffer for the column; if not,
2647 double its length. */
2648 line_len += column_len + 1; /* "+1" for space */
2649 if (line_len > callback_args.header_line_buf_len) {
2650 cp_off = (int) (cp - callback_args.header_line_buf);
2651 callback_args.header_line_buf_len = 2 * line_len;
2652 callback_args.header_line_buf = (char *)g_realloc(callback_args.header_line_buf,
2653 callback_args.header_line_buf_len + 1);
2654 cp = callback_args.header_line_buf + cp_off;
2657 /* Right-justify the packet number column. */
2658 /* if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2659 g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
2661 g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
2663 if (i != cf->cinfo.num_cols - 1)
2666 visible_col_count++;
2670 /* Now start out the main line buffer with the same length as the
2671 header line buffer. */
2672 callback_args.line_buf_len = callback_args.header_line_buf_len;
2673 callback_args.line_buf = (char *)g_malloc(callback_args.line_buf_len + 1);
2674 } /* if (print_summary) */
2676 /* Create the protocol tree, and make it visible, if we're printing
2677 the dissection or the hex data.
2678 XXX - do we need it if we're just printing the hex data? */
2680 callback_args.print_args->print_dissections != print_dissections_none ||
2681 callback_args.print_args->print_hex ||
2682 have_custom_cols(&cf->cinfo);
2683 epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
2685 /* Iterate through the list of packets, printing the packets we were
2687 ret = process_specified_records(cf, &print_args->range, "Printing",
2688 "selected packets", TRUE, print_packet,
2690 epan_dissect_cleanup(&callback_args.edt);
2691 g_free(callback_args.header_line_buf);
2692 g_free(callback_args.line_buf);
2693 g_free(callback_args.col_widths);
2694 g_free(callback_args.visible_cols);
2699 /* Completed successfully. */
2703 /* Well, the user decided to abort the printing.
2705 XXX - note that what got generated before they did that
2706 will get printed if we're piping to a print program; we'd
2707 have to write to a file and then hand that to the print
2708 program to make it actually not print anything. */
2712 /* Error while printing.
2714 XXX - note that what got generated before they did that
2715 will get printed if we're piping to a print program; we'd
2716 have to write to a file and then hand that to the print
2717 program to make it actually not print anything. */
2718 destroy_print_stream(print_args->stream);
2719 return CF_PRINT_WRITE_ERROR;
2722 if (!print_finale(print_args->stream)) {
2723 destroy_print_stream(print_args->stream);
2724 return CF_PRINT_WRITE_ERROR;
2727 if (!destroy_print_stream(print_args->stream))
2728 return CF_PRINT_WRITE_ERROR;
2736 } write_packet_callback_args_t;
2739 write_pdml_packet(capture_file *cf, frame_data *fdata,
2740 struct wtap_pkthdr *phdr, const guint8 *pd,
2743 write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
2745 /* Create the protocol tree, but don't fill in the column information. */
2746 epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
2748 /* Write out the information in that tree. */
2749 write_pdml_proto_tree(&args->edt, args->fh);
2751 epan_dissect_reset(&args->edt);
2753 return !ferror(args->fh);
2757 cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
2759 write_packet_callback_args_t callback_args;
2763 fh = ws_fopen(print_args->file, "w");
2765 return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2767 write_pdml_preamble(fh, cf->filename);
2770 return CF_PRINT_WRITE_ERROR;
2773 callback_args.fh = fh;
2774 epan_dissect_init(&callback_args.edt, cf->epan, TRUE, TRUE);
2776 /* Iterate through the list of packets, printing the packets we were
2778 ret = process_specified_records(cf, &print_args->range, "Writing PDML",
2779 "selected packets", TRUE,
2780 write_pdml_packet, &callback_args);
2782 epan_dissect_cleanup(&callback_args.edt);
2787 /* Completed successfully. */
2791 /* Well, the user decided to abort the printing. */
2795 /* Error while printing. */
2797 return CF_PRINT_WRITE_ERROR;
2800 write_pdml_finale(fh);
2803 return CF_PRINT_WRITE_ERROR;
2806 /* XXX - check for an error */
2813 write_psml_packet(capture_file *cf, frame_data *fdata,
2814 struct wtap_pkthdr *phdr, const guint8 *pd,
2817 write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
2819 /* Fill in the column information */
2820 col_custom_prime_edt(&args->edt, &cf->cinfo);
2821 epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
2822 epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
2824 /* Write out the column information. */
2825 write_psml_columns(&args->edt, args->fh);
2827 epan_dissect_reset(&args->edt);
2829 return !ferror(args->fh);
2833 cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
2835 write_packet_callback_args_t callback_args;
2839 gboolean proto_tree_needed;
2841 fh = ws_fopen(print_args->file, "w");
2843 return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2845 write_psml_preamble(&cf->cinfo, fh);
2848 return CF_PRINT_WRITE_ERROR;
2851 callback_args.fh = fh;
2853 /* Fill in the column information, only create the protocol tree
2854 if having custom columns. */
2855 proto_tree_needed = have_custom_cols(&cf->cinfo);
2856 epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
2858 /* Iterate through the list of packets, printing the packets we were
2860 ret = process_specified_records(cf, &print_args->range, "Writing PSML",
2861 "selected packets", TRUE,
2862 write_psml_packet, &callback_args);
2864 epan_dissect_cleanup(&callback_args.edt);
2869 /* Completed successfully. */
2873 /* Well, the user decided to abort the printing. */
2877 /* Error while printing. */
2879 return CF_PRINT_WRITE_ERROR;
2882 write_psml_finale(fh);
2885 return CF_PRINT_WRITE_ERROR;
2888 /* XXX - check for an error */
2895 write_csv_packet(capture_file *cf, frame_data *fdata,
2896 struct wtap_pkthdr *phdr, const guint8 *pd,
2899 write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
2901 /* Fill in the column information */
2902 col_custom_prime_edt(&args->edt, &cf->cinfo);
2903 epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
2904 epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
2906 /* Write out the column information. */
2907 write_csv_columns(&args->edt, args->fh);
2909 epan_dissect_reset(&args->edt);
2911 return !ferror(args->fh);
2915 cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
2917 write_packet_callback_args_t callback_args;
2918 gboolean proto_tree_needed;
2922 fh = ws_fopen(print_args->file, "w");
2924 return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2926 write_csv_column_titles(&cf->cinfo, fh);
2929 return CF_PRINT_WRITE_ERROR;
2932 callback_args.fh = fh;
2934 /* only create the protocol tree if having custom columns. */
2935 proto_tree_needed = have_custom_cols(&cf->cinfo);
2936 epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
2938 /* Iterate through the list of packets, printing the packets we were
2940 ret = process_specified_records(cf, &print_args->range, "Writing CSV",
2941 "selected packets", TRUE,
2942 write_csv_packet, &callback_args);
2944 epan_dissect_cleanup(&callback_args.edt);
2949 /* Completed successfully. */
2953 /* Well, the user decided to abort the printing. */
2957 /* Error while printing. */
2959 return CF_PRINT_WRITE_ERROR;
2962 /* XXX - check for an error */
2969 carrays_write_packet(capture_file *cf, frame_data *fdata,
2970 struct wtap_pkthdr *phdr,
2971 const guint8 *pd, void *argsp)
2973 write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
2975 epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
2976 write_carrays_hex_data(fdata->num, args->fh, &args->edt);
2977 epan_dissect_reset(&args->edt);
2979 return !ferror(args->fh);
2983 cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
2985 write_packet_callback_args_t callback_args;
2989 fh = ws_fopen(print_args->file, "w");
2992 return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2996 return CF_PRINT_WRITE_ERROR;
2999 callback_args.fh = fh;
3000 epan_dissect_init(&callback_args.edt, cf->epan, TRUE, TRUE);
3002 /* Iterate through the list of packets, printing the packets we were
3004 ret = process_specified_records(cf, &print_args->range,
3006 "selected packets", TRUE,
3007 carrays_write_packet, &callback_args);
3009 epan_dissect_cleanup(&callback_args.edt);
3013 /* Completed successfully. */
3016 /* Well, the user decided to abort the printing. */
3019 /* Error while printing. */
3021 return CF_PRINT_WRITE_ERROR;
3029 cf_find_packet_protocol_tree(capture_file *cf, const char *string,
3030 search_direction dir)
3034 mdata.string = string;
3035 mdata.string_len = strlen(string);
3036 return find_packet(cf, match_protocol_tree, &mdata, dir);
3040 cf_find_string_protocol_tree(capture_file *cf, proto_tree *tree, match_data *mdata)
3042 mdata->frame_matched = FALSE;
3043 mdata->string = convert_string_case(cf->sfilter, cf->case_type);
3044 mdata->string_len = strlen(mdata->string);
3046 /* Iterate through all the nodes looking for matching text */
3047 proto_tree_children_foreach(tree, match_subtree_text, mdata);
3048 return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
3052 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
3054 match_data *mdata = (match_data *)criterion;
3057 /* Load the frame's data. */
3058 if (!cf_read_record(cf, fdata)) {
3059 /* Attempt to get the packet failed. */
3063 /* Construct the protocol tree, including the displayed text */
3064 epan_dissect_init(&edt, cf->epan, TRUE, TRUE);
3065 /* We don't need the column information */
3066 epan_dissect_run(&edt, cf->cd_t, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
3068 /* Iterate through all the nodes, seeing if they have text that matches. */
3070 mdata->frame_matched = FALSE;
3071 proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
3072 epan_dissect_cleanup(&edt);
3073 return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
3077 match_subtree_text(proto_node *node, gpointer data)
3079 match_data *mdata = (match_data *) data;
3080 const gchar *string = mdata->string;
3081 size_t string_len = mdata->string_len;
3082 capture_file *cf = mdata->cf;
3083 field_info *fi = PNODE_FINFO(node);
3084 gchar label_str[ITEM_LABEL_LENGTH];
3091 /* dissection with an invisible proto tree? */
3094 if (mdata->frame_matched) {
3095 /* We already had a match; don't bother doing any more work. */
3099 /* Don't match invisible entries. */
3100 if (PROTO_ITEM_IS_HIDDEN(node))
3103 /* was a free format label produced? */
3105 label_ptr = fi->rep->representation;
3107 /* no, make a generic label */
3108 label_ptr = label_str;
3109 proto_item_fill_label(fi, label_str);
3112 /* Does that label match? */
3113 label_len = strlen(label_ptr);
3114 for (i = 0; i < label_len; i++) {
3115 c_char = label_ptr[i];
3117 c_char = toupper(c_char);
3118 if (c_char == string[c_match]) {
3120 if (c_match == string_len) {
3121 /* No need to look further; we have a match */
3122 mdata->frame_matched = TRUE;
3130 /* Recurse into the subtree, if it exists */
3131 if (node->first_child != NULL)
3132 proto_tree_children_foreach(node, match_subtree_text, mdata);
3136 cf_find_packet_summary_line(capture_file *cf, const char *string,
3137 search_direction dir)
3141 mdata.string = string;
3142 mdata.string_len = strlen(string);
3143 return find_packet(cf, match_summary_line, &mdata, dir);
3147 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
3149 match_data *mdata = (match_data *)criterion;
3150 const gchar *string = mdata->string;
3151 size_t string_len = mdata->string_len;
3153 const char *info_column;
3154 size_t info_column_len;
3155 match_result result = MR_NOTMATCHED;
3161 /* Load the frame's data. */
3162 if (!cf_read_record(cf, fdata)) {
3163 /* Attempt to get the packet failed. */
3167 /* Don't bother constructing the protocol tree */
3168 epan_dissect_init(&edt, cf->epan, FALSE, FALSE);
3169 /* Get the column information */
3170 epan_dissect_run(&edt, cf->cd_t, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata,
3173 /* Find the Info column */
3174 for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
3175 if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
3176 /* Found it. See if we match. */
3177 info_column = edt.pi.cinfo->col_data[colx];
3178 info_column_len = strlen(info_column);
3179 for (i = 0; i < info_column_len; i++) {
3180 c_char = info_column[i];
3182 c_char = toupper(c_char);
3183 if (c_char == string[c_match]) {
3185 if (c_match == string_len) {
3186 result = MR_MATCHED;
3195 epan_dissect_cleanup(&edt);
3202 } cbs_t; /* "Counted byte string" */
3206 * The current match_* routines only support ASCII case insensitivity and don't
3207 * convert UTF-8 inputs to UTF-16 for matching.
3209 * We could modify them to use the GLib Unicode routines or the International
3210 * Components for Unicode library but it's not apparent that we could do so
3211 * without consuming a lot more CPU and memory or that searching would be
3212 * significantly better.
3216 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size,
3217 search_direction dir)
3222 info.data_len = string_size;
3224 /* String or hex search? */
3226 /* String search - what type of string? */
3227 switch (cf->scs_type) {
3229 case SCS_NARROW_AND_WIDE:
3230 return find_packet(cf, match_narrow_and_wide, &info, dir);
3233 return find_packet(cf, match_narrow, &info, dir);
3236 return find_packet(cf, match_wide, &info, dir);
3239 g_assert_not_reached();
3243 return find_packet(cf, match_binary, &info, dir);
3247 match_narrow_and_wide(capture_file *cf, frame_data *fdata, void *criterion)
3249 cbs_t *info = (cbs_t *)criterion;
3250 const guint8 *ascii_text = info->data;
3251 size_t textlen = info->data_len;
3252 match_result result;
3259 /* Load the frame's data. */
3260 if (!cf_read_record(cf, fdata)) {
3261 /* Attempt to get the packet failed. */
3265 result = MR_NOTMATCHED;
3266 buf_len = fdata->cap_len;
3267 pd = ws_buffer_start_ptr(&cf->buf);
3269 while (i < buf_len) {
3272 c_char = toupper(c_char);
3273 if (c_char != '\0') {
3274 if (c_char == ascii_text[c_match]) {
3276 if (c_match == textlen) {
3277 result = MR_MATCHED;
3278 cf->search_pos = i; /* Save the position of the last character
3279 for highlighting the field. */
3284 g_assert(i>=c_match);
3285 i -= (guint32)c_match;
3295 match_narrow(capture_file *cf, frame_data *fdata, void *criterion)
3298 cbs_t *info = (cbs_t *)criterion;
3299 const guint8 *ascii_text = info->data;
3300 size_t textlen = info->data_len;
3301 match_result result;
3307 /* Load the frame's data. */
3308 if (!cf_read_record(cf, fdata)) {
3309 /* Attempt to get the packet failed. */
3313 result = MR_NOTMATCHED;
3314 buf_len = fdata->cap_len;
3315 pd = ws_buffer_start_ptr(&cf->buf);
3317 while (i < buf_len) {
3320 c_char = toupper(c_char);
3321 if (c_char == ascii_text[c_match]) {
3323 if (c_match == textlen) {
3324 result = MR_MATCHED;
3325 cf->search_pos = i; /* Save the position of the last character
3326 for highlighting the field. */
3331 g_assert(i>=c_match);
3332 i -= (guint32)c_match;
3342 match_wide(capture_file *cf, frame_data *fdata, void *criterion)
3344 cbs_t *info = (cbs_t *)criterion;
3345 const guint8 *ascii_text = info->data;
3346 size_t textlen = info->data_len;
3347 match_result result;
3354 /* Load the frame's data. */
3355 if (!cf_read_record(cf, fdata)) {
3356 /* Attempt to get the packet failed. */
3360 result = MR_NOTMATCHED;
3361 buf_len = fdata->cap_len;
3362 pd = ws_buffer_start_ptr(&cf->buf);
3364 while (i < buf_len) {
3367 c_char = toupper(c_char);
3368 if (c_char == ascii_text[c_match]) {
3370 if (c_match == textlen) {
3371 result = MR_MATCHED;
3372 cf->search_pos = i; /* Save the position of the last character
3373 for highlighting the field. */
3379 g_assert(i>=(c_match*2));
3380 i -= (guint32)c_match*2;
3389 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
3391 cbs_t *info = (cbs_t *)criterion;
3392 const guint8 *binary_data = info->data;
3393 size_t datalen = info->data_len;
3394 match_result result;
3400 /* Load the frame's data. */
3401 if (!cf_read_record(cf, fdata)) {
3402 /* Attempt to get the packet failed. */
3406 result = MR_NOTMATCHED;
3407 buf_len = fdata->cap_len;
3408 pd = ws_buffer_start_ptr(&cf->buf);
3410 while (i < buf_len) {
3411 if (pd[i] == binary_data[c_match]) {
3413 if (c_match == datalen) {
3414 result = MR_MATCHED;
3415 cf->search_pos = i; /* Save the position of the last character
3416 for highlighting the field. */
3421 g_assert(i>=c_match);
3422 i -= (guint32)c_match;
3431 cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode,
3432 search_direction dir)
3434 return find_packet(cf, match_dfilter, sfcode, dir);
3438 cf_find_packet_dfilter_string(capture_file *cf, const char *filter,
3439 search_direction dir)
3444 if (!dfilter_compile(filter, &sfcode, NULL)) {
3446 * XXX - this shouldn't happen, as the filter string is machine
3451 if (sfcode == NULL) {
3453 * XXX - this shouldn't happen, as the filter string is machine
3458 result = find_packet(cf, match_dfilter, sfcode, dir);
3459 dfilter_free(sfcode);
3464 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
3466 dfilter_t *sfcode = (dfilter_t *)criterion;
3468 match_result result;
3470 /* Load the frame's data. */
3471 if (!cf_read_record(cf, fdata)) {
3472 /* Attempt to get the packet failed. */
3476 epan_dissect_init(&edt, cf->epan, TRUE, FALSE);
3477 epan_dissect_prime_dfilter(&edt, sfcode);
3478 epan_dissect_run(&edt, cf->cd_t, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
3479 result = dfilter_apply_edt(sfcode, &edt) ? MR_MATCHED : MR_NOTMATCHED;
3480 epan_dissect_cleanup(&edt);
3485 cf_find_packet_marked(capture_file *cf, search_direction dir)
3487 return find_packet(cf, match_marked, NULL, dir);
3491 match_marked(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3493 return fdata->flags.marked ? MR_MATCHED : MR_NOTMATCHED;
3497 cf_find_packet_time_reference(capture_file *cf, search_direction dir)
3499 return find_packet(cf, match_time_reference, NULL, dir);
3503 match_time_reference(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3505 return fdata->flags.ref_time ? MR_MATCHED : MR_NOTMATCHED;
3509 find_packet(capture_file *cf,
3510 match_result (*match_function)(capture_file *, frame_data *, void *),
3511 void *criterion, search_direction dir)
3513 frame_data *start_fd;
3516 frame_data *new_fd = NULL;
3517 progdlg_t *progbar = NULL;
3522 GTimeVal start_time;
3523 gchar status_str[100];
3524 int progbar_nextstep;
3525 int progbar_quantum;
3527 match_result result;
3529 start_fd = cf->current_frame;
3530 if (start_fd != NULL) {
3531 /* Iterate through the list of packets, starting at the packet we've
3532 picked, calling a routine to run the filter on the packet, see if
3533 it matches, and stop if so. */
3535 framenum = start_fd->num;
3537 /* Update the progress bar when it gets to this value. */
3538 progbar_nextstep = 0;
3539 /* When we reach the value that triggers a progress bar update,
3540 bump that value by this amount. */
3541 progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3542 /* Progress so far. */
3546 g_get_current_time(&start_time);
3548 title = cf->sfilter?cf->sfilter:"";
3550 /* Create the progress bar if necessary.
3551 We check on every iteration of the loop, so that it takes no
3552 longer than the standard time to create it (otherwise, for a
3553 large file, we might take considerably longer than that standard
3554 time in order to get to the next progress bar step). */
3555 if (progbar == NULL)
3556 progbar = delayed_create_progress_dlg(cf->window, "Searching", title,
3557 FALSE, &stop_flag, &start_time, progbar_val);
3559 /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3560 when we update it, we have to run the GTK+ main loop to get it
3561 to repaint what's pending, and doing so may involve an "ioctl()"
3562 to see if there's any pending input from an X server, and doing
3563 that for every packet can be costly, especially on a big file. */
3564 if (count >= progbar_nextstep) {
3565 /* let's not divide by zero. I should never be started
3566 * with count == 0, so let's assert that
3568 g_assert(cf->count > 0);
3570 progbar_val = (gfloat) count / cf->count;
3572 if (progbar != NULL) {
3573 g_snprintf(status_str, sizeof(status_str),
3574 "%4u of %u packets", count, cf->count);
3575 update_progress_dlg(progbar, progbar_val, status_str);
3578 progbar_nextstep += progbar_quantum;
3582 /* Well, the user decided to abort the search. Go back to the
3583 frame where we started. */
3588 /* Go past the current frame. */
3589 if (dir == SD_BACKWARD) {
3590 /* Go on to the previous frame. */
3591 if (framenum == 1) {
3593 * XXX - other apps have a bit more of a detailed message
3594 * for this, and instead of offering "OK" and "Cancel",
3595 * they offer things such as "Continue" and "Cancel";
3596 * we need an API for popping up alert boxes with
3597 * {Verb} and "Cancel".
3600 if (prefs.gui_find_wrap)
3602 statusbar_push_temporary_msg("Search reached the beginning. Continuing at end.");
3603 framenum = cf->count; /* wrap around */
3607 statusbar_push_temporary_msg("Search reached the beginning.");
3608 framenum = start_fd->num; /* stay on previous packet */
3613 /* Go on to the next frame. */
3614 if (framenum == cf->count) {
3615 if (prefs.gui_find_wrap)
3617 statusbar_push_temporary_msg("Search reached the end. Continuing at beginning.");
3618 framenum = 1; /* wrap around */
3622 statusbar_push_temporary_msg("Search reached the end.");
3623 framenum = start_fd->num; /* stay on previous packet */
3628 fdata = frame_data_sequence_find(cf->frames, framenum);
3632 /* Is this packet in the display? */
3633 if (fdata->flags.passed_dfilter) {
3634 /* Yes. Does it match the search criterion? */
3635 result = (*match_function)(cf, fdata, criterion);
3636 if (result == MR_ERROR) {
3637 /* Error; our caller has reported the error. Go back to the frame
3638 where we started. */
3641 } else if (result == MR_MATCHED) {
3642 /* Yes. Go to the new frame. */
3648 if (fdata == start_fd) {
3649 /* We're back to the frame we were on originally, and that frame
3650 doesn't match the search filter. The search failed. */
3655 /* We're done scanning the packets; destroy the progress bar if it
3657 if (progbar != NULL)
3658 destroy_progress_dlg(progbar);
3661 if (new_fd != NULL) {
3662 /* Find and select */
3663 cf->search_in_progress = TRUE;
3664 found = packet_list_select_row_from_data(new_fd);
3665 cf->search_in_progress = FALSE;
3666 cf->search_pos = 0; /* Reset the position */
3668 /* We didn't find a row corresponding to this frame.
3669 This means that the frame isn't being displayed currently,
3670 so we can't select it. */
3671 simple_message_box(ESD_TYPE_INFO, NULL,
3672 "The capture file is probably not fully dissected.",
3673 "End of capture exceeded.");
3676 return TRUE; /* success */
3678 return FALSE; /* failure */
3682 cf_goto_frame(capture_file *cf, guint fnumber)
3686 fdata = frame_data_sequence_find(cf->frames, fnumber);
3688 if (fdata == NULL) {
3689 /* we didn't find a packet with that packet number */
3690 statusbar_push_temporary_msg("There is no packet number %u.", fnumber);
3691 return FALSE; /* we failed to go to that packet */
3693 if (!fdata->flags.passed_dfilter) {
3694 /* that packet currently isn't displayed */
3695 /* XXX - add it to the set of displayed packets? */
3696 statusbar_push_temporary_msg("Packet number %u isn't displayed.", fnumber);
3697 return FALSE; /* we failed to go to that packet */
3700 if (!packet_list_select_row_from_data(fdata)) {
3701 /* We didn't find a row corresponding to this frame.
3702 This means that the frame isn't being displayed currently,
3703 so we can't select it. */
3704 simple_message_box(ESD_TYPE_INFO, NULL,
3705 "The capture file is probably not fully dissected.",
3706 "End of capture exceeded.");
3709 return TRUE; /* we got to that packet */
3713 cf_goto_top_frame(void)
3715 /* Find and select */
3716 packet_list_select_first_row();
3717 return TRUE; /* we got to that packet */
3721 cf_goto_bottom_frame(void)
3723 /* Find and select */
3724 packet_list_select_last_row();
3725 return TRUE; /* we got to that packet */
3729 * Go to frame specified by currently selected protocol tree item.
3732 cf_goto_framenum(capture_file *cf)
3734 header_field_info *hfinfo;
3737 if (cf->finfo_selected) {
3738 hfinfo = cf->finfo_selected->hfinfo;
3740 if (hfinfo->type == FT_FRAMENUM) {
3741 framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
3743 return cf_goto_frame(cf, framenum);
3750 /* Select the packet on a given row. */
3752 cf_select_packet(capture_file *cf, int row)
3754 epan_dissect_t *old_edt;
3757 /* Get the frame data struct pointer for this frame */
3758 fdata = packet_list_get_row_data(row);
3760 if (fdata == NULL) {
3761 /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
3762 the first entry is added to it by "real_insert_row()", that row
3763 is selected (see "real_insert_row()", in "ui/gtk/gtkclist.c", in both
3764 our version and the vanilla GTK+ version).
3766 This means that a "select-row" signal is emitted; this causes
3767 "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
3770 "cf_select_packet()" fetches, above, the data associated with the
3771 row that was selected; however, as "gtk_clist_append()", which
3772 called "real_insert_row()", hasn't yet returned, we haven't yet
3773 associated any data with that row, so we get back a null pointer.
3775 We can't assume that there's only one frame in the frame list,
3776 either, as we may be filtering the display.
3778 We therefore assume that, if "row" is 0, i.e. the first row
3779 is being selected, and "cf->first_displayed" equals
3780 "cf->last_displayed", i.e. there's only one frame being
3781 displayed, that frame is the frame we want.
3783 This means we have to set "cf->first_displayed" and
3784 "cf->last_displayed" before adding the row to the
3785 GtkCList; see the comment in "add_packet_to_packet_list()". */
3787 if (row == 0 && cf->first_displayed == cf->last_displayed)
3788 fdata = frame_data_sequence_find(cf->frames, cf->first_displayed);
3791 /* If fdata _still_ isn't set simply give up. */
3792 if (fdata == NULL) {
3796 /* Get the data in that frame. */
3797 if (!cf_read_record (cf, fdata)) {
3801 /* Record that this frame is the current frame. */
3802 cf->current_frame = fdata;
3803 cf->current_row = row;
3806 /* Create the logical protocol tree. */
3807 /* We don't need the columns here. */
3808 cf->edt = epan_dissect_new(cf->epan, TRUE, TRUE);
3810 tap_build_interesting(cf->edt);
3811 epan_dissect_run(cf->edt, cf->cd_t, &cf->phdr, frame_tvbuff_new_buffer(cf->current_frame, &cf->buf),
3812 cf->current_frame, NULL);
3814 dfilter_macro_build_ftv_cache(cf->edt->tree);
3816 cf_callback_invoke(cf_cb_packet_selected, cf);
3818 if (old_edt != NULL)
3819 epan_dissect_free(old_edt);
3823 /* Unselect the selected packet, if any. */
3825 cf_unselect_packet(capture_file *cf)
3827 epan_dissect_t *old_edt = cf->edt;
3831 /* No packet is selected. */
3832 cf->current_frame = NULL;
3833 cf->current_row = 0;
3835 cf_callback_invoke(cf_cb_packet_unselected, cf);
3837 /* No protocol tree means no selected field. */
3838 cf_unselect_field(cf);
3840 /* Destroy the epan_dissect_t for the unselected packet. */
3841 if (old_edt != NULL)
3842 epan_dissect_free(old_edt);
3845 /* Unset the selected protocol tree field, if any. */
3847 cf_unselect_field(capture_file *cf)
3849 cf->finfo_selected = NULL;
3851 cf_callback_invoke(cf_cb_field_unselected, cf);
3855 * Mark a particular frame.
3858 cf_mark_frame(capture_file *cf, frame_data *frame)
3860 if (! frame->flags.marked) {
3861 frame->flags.marked = TRUE;
3862 if (cf->count > cf->marked_count)
3868 * Unmark a particular frame.
3871 cf_unmark_frame(capture_file *cf, frame_data *frame)
3873 if (frame->flags.marked) {
3874 frame->flags.marked = FALSE;
3875 if (cf->marked_count > 0)
3881 * Ignore a particular frame.
3884 cf_ignore_frame(capture_file *cf, frame_data *frame)
3886 if (! frame->flags.ignored) {
3887 frame->flags.ignored = TRUE;
3888 if (cf->count > cf->ignored_count)
3889 cf->ignored_count++;
3894 * Un-ignore a particular frame.
3897 cf_unignore_frame(capture_file *cf, frame_data *frame)
3899 if (frame->flags.ignored) {
3900 frame->flags.ignored = FALSE;
3901 if (cf->ignored_count > 0)
3902 cf->ignored_count--;
3907 * Read the comment in SHB block
3911 cf_read_shb_comment(capture_file *cf)
3913 wtapng_section_t *shb_inf;
3914 const gchar *temp_str;
3916 /* Get info from SHB */
3917 shb_inf = wtap_file_get_shb_info(cf->wth);
3918 if (shb_inf == NULL)
3920 temp_str = shb_inf->opt_comment;
3928 cf_update_capture_comment(capture_file *cf, gchar *comment)
3930 wtapng_section_t *shb_inf;
3932 /* Get info from SHB */
3933 shb_inf = wtap_file_get_shb_info(cf->wth);
3935 /* See if the comment has changed or not */
3936 if (shb_inf && shb_inf->opt_comment) {
3937 if (strcmp(shb_inf->opt_comment, comment) == 0) {
3946 /* The comment has changed, let's update it */
3947 wtap_write_shb_comment(cf->wth, comment);
3948 /* Mark the file as having unsaved changes */
3949 cf->unsaved_changes = TRUE;
3953 cf_get_user_packet_comment(capture_file *cf, const frame_data *fd)
3955 if (cf->frames_user_comments)
3956 return (const char *)g_tree_lookup(cf->frames_user_comments, fd);
3963 cf_get_comment(capture_file *cf, const frame_data *fd)
3967 /* fetch user comment */
3968 if (fd->flags.has_user_comment)
3969 return g_strdup(cf_get_user_packet_comment(cf, fd));
3971 /* fetch phdr comment */
3972 if (fd->flags.has_phdr_comment) {
3973 struct wtap_pkthdr phdr; /* Packet header */
3974 Buffer buf; /* Packet data */
3976 wtap_phdr_init(&phdr);
3977 ws_buffer_init(&buf, 1500);
3979 if (!cf_read_record_r(cf, fd, &phdr, &buf))
3980 { /* XXX, what we can do here? */ }
3982 comment = phdr.opt_comment;
3983 wtap_phdr_cleanup(&phdr);
3984 ws_buffer_free(&buf);
3991 frame_cmp(gconstpointer a, gconstpointer b, gpointer user_data _U_)
3993 const frame_data *fdata1 = (const frame_data *) a;
3994 const frame_data *fdata2 = (const frame_data *) b;
3996 return (fdata1->num < fdata2->num) ? -1 :
3997 (fdata1->num > fdata2->num) ? 1 :
4002 cf_set_user_packet_comment(capture_file *cf, frame_data *fd, const gchar *new_comment)
4004 char *pkt_comment = cf_get_comment(cf, fd);
4006 /* Check if the comment has changed */
4007 if (!g_strcmp0(pkt_comment, new_comment)) {
4008 g_free(pkt_comment);
4011 g_free(pkt_comment);
4014 cf->packet_comment_count--;
4017 cf->packet_comment_count++;
4019 fd->flags.has_user_comment = TRUE;
4021 if (!cf->frames_user_comments)
4022 cf->frames_user_comments = g_tree_new_full(frame_cmp, NULL, NULL, g_free);
4024 /* insert new packet comment */
4025 g_tree_replace(cf->frames_user_comments, fd, g_strdup(new_comment));
4027 expert_update_comment_count(cf->packet_comment_count);
4029 /* OK, we have unsaved changes. */
4030 cf->unsaved_changes = TRUE;
4035 * What types of comments does this capture file have?
4038 cf_comment_types(capture_file *cf)
4040 guint32 comment_types = 0;
4042 if (cf_read_shb_comment(cf) != NULL)
4043 comment_types |= WTAP_COMMENT_PER_SECTION;
4044 if (cf->packet_comment_count != 0)
4045 comment_types |= WTAP_COMMENT_PER_PACKET;
4046 return comment_types;
4049 #ifdef WANT_PACKET_EDITOR
4051 g_direct_compare_func(gconstpointer a, gconstpointer b, gpointer user_data _U_)
4062 modified_frame_data_free(gpointer data)
4064 modified_frame_data *mfd = (modified_frame_data *)data;
4071 * Give a frame new, edited data.
4074 cf_set_frame_edited(capture_file *cf, frame_data *fd,
4075 struct wtap_pkthdr *phdr, guint8 *pd)
4077 modified_frame_data *mfd = (modified_frame_data *)g_malloc(sizeof(modified_frame_data));
4082 if (cf->edited_frames == NULL)
4083 cf->edited_frames = g_tree_new_full(g_direct_compare_func, NULL, NULL,
4084 modified_frame_data_free);
4085 g_tree_insert(cf->edited_frames, GINT_TO_POINTER(fd->num), mfd);
4088 /* Mark the file as having unsaved changes */
4089 cf->unsaved_changes = TRUE;
4097 } save_callback_args_t;
4100 * Save a capture to a file, in a particular format, saving either
4101 * all packets, all currently-displayed packets, or all marked packets.
4103 * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
4104 * up a message box for the failure.
4107 save_record(capture_file *cf, frame_data *fdata,
4108 struct wtap_pkthdr *phdr, const guint8 *pd,
4111 save_callback_args_t *args = (save_callback_args_t *)argsp;
4112 struct wtap_pkthdr hdr;
4115 gchar *display_basename;
4116 const char *pkt_comment;
4118 if (fdata->flags.has_user_comment)
4119 pkt_comment = cf_get_user_packet_comment(cf, fdata);
4121 pkt_comment = phdr->opt_comment;
4123 /* init the wtap header for saving */
4124 /* TODO: reuse phdr */
4125 /* XXX - these are the only flags that correspond to data that we have
4126 in the frame_data structure and that matter on a per-packet basis.
4128 For WTAP_HAS_CAP_LEN, either the file format has separate "captured"
4129 and "on the wire" lengths, or it doesn't.
4131 For WTAP_HAS_DROP_COUNT, Wiretap doesn't actually supply the value
4134 For WTAP_HAS_PACK_FLAGS, we currently don't save the FCS length
4135 from the packet flags. */
4136 hdr.rec_type = phdr->rec_type;
4137 hdr.presence_flags = 0;
4138 if (fdata->flags.has_ts)
4139 hdr.presence_flags |= WTAP_HAS_TS;
4140 if (phdr->presence_flags & WTAP_HAS_INTERFACE_ID)
4141 hdr.presence_flags |= WTAP_HAS_INTERFACE_ID;
4142 if (phdr->presence_flags & WTAP_HAS_PACK_FLAGS)
4143 hdr.presence_flags |= WTAP_HAS_PACK_FLAGS;
4144 hdr.ts.secs = fdata->abs_ts.secs;
4145 hdr.ts.nsecs = fdata->abs_ts.nsecs;
4146 hdr.caplen = phdr->caplen;
4147 hdr.len = phdr->len;
4148 hdr.pkt_encap = fdata->lnk_t;
4150 hdr.interface_id = phdr->interface_id; /* identifier of the interface. */
4152 hdr.pack_flags = phdr->pack_flags;
4153 hdr.opt_comment = g_strdup(pkt_comment);
4156 hdr.pseudo_header = phdr->pseudo_header;
4159 hdr.pack_flags = /* XXX - 0 for now (any value for "we don't have it"?) */
4161 /* and save the packet */
4162 if (!wtap_dump(args->pdh, &hdr, pd, &err, &err_info)) {
4164 /* Wiretap error. */
4167 case WTAP_ERR_UNWRITABLE_ENCAP:
4169 * This is a problem with the particular frame we're writing and
4170 * the file type and subtype we're writing; note that, and report
4171 * the frame number and file type/subtype.
4173 simple_error_message_box(
4174 "Frame %u has a network type that can't be saved in a \"%s\" file.",
4175 fdata->num, wtap_file_type_subtype_string(args->file_type));
4178 case WTAP_ERR_PACKET_TOO_LARGE:
4180 * This is a problem with the particular frame we're writing and
4181 * the file type and subtype we're writing; note that, and report
4182 * the frame number and file type/subtype.
4184 simple_error_message_box(
4185 "Frame %u is larger than Wireshark supports in a \"%s\" file.",
4186 fdata->num, wtap_file_type_subtype_string(args->file_type));
4189 case WTAP_ERR_UNWRITABLE_REC_TYPE:
4191 * This is a problem with the particular record we're writing and
4192 * the file type and subtype we're writing; note that, and report
4193 * the record number and file type/subtype.
4195 simple_error_message_box(
4196 "Record %u has a record type that can't be saved in a \"%s\" file.",
4197 fdata->num, wtap_file_type_subtype_string(args->file_type));
4200 case WTAP_ERR_UNWRITABLE_REC_DATA:
4202 * This is a problem with the particular frame we're writing and
4203 * the file type and subtype we're writing; note that, and report
4204 * the frame number and file type/subtype.
4206 simple_error_message_box(
4207 "Record %u has data that can't be saved in a \"%s\" file.\n(%s)",
4208 fdata->num, wtap_file_type_subtype_string(args->file_type),
4209 err_info != NULL ? err_info : "no information supplied");
4214 display_basename = g_filename_display_basename(args->fname);
4215 simple_error_message_box(
4216 "An error occurred while writing to the file \"%s\": %s.",
4217 display_basename, wtap_strerror(err));
4218 g_free(display_basename);
4223 write_failure_alert_box(args->fname, err);
4228 g_free(hdr.opt_comment);
4233 * Can this capture file be written out in any format using Wiretap
4234 * rather than by copying the raw data?
4237 cf_can_write_with_wiretap(capture_file *cf)
4239 /* We don't care whether we support the comments in this file or not;
4240 if we can't, we'll offer the user the option of discarding the
4242 return wtap_dump_can_write(cf->linktypes, 0);
4246 * Should we let the user do a save?
4250 * the file has unsaved changes, and we can save it in some
4251 * format through Wiretap
4255 * the file is a temporary file and has no unsaved changes (so
4256 * that "saving" it just means copying it).
4258 * XXX - we shouldn't allow files to be edited if they can't be saved,
4259 * so cf->unsaved_changes should be true only if the file can be saved.
4261 * We don't care whether we support the comments in this file or not;
4262 * if we can't, we'll offer the user the option of discarding the
4266 cf_can_save(capture_file *cf)
4268 if (cf->unsaved_changes && wtap_dump_can_write(cf->linktypes, 0)) {
4269 /* Saved changes, and we can write it out with Wiretap. */
4273 if (cf->is_tempfile && !cf->unsaved_changes) {
4275 * Temporary file with no unsaved changes, so we can just do a
4281 /* Nothing to save. */
4286 * Should we let the user do a "save as"?
4290 * we can save it in some format through Wiretap
4294 * the file is a temporary file and has no unsaved changes (so
4295 * that "saving" it just means copying it).
4297 * XXX - we shouldn't allow files to be edited if they can't be saved,
4298 * so cf->unsaved_changes should be true only if the file can be saved.
4300 * We don't care whether we support the comments in this file or not;
4301 * if we can't, we'll offer the user the option of discarding the
4305 cf_can_save_as(capture_file *cf)
4307 if (wtap_dump_can_write(cf->linktypes, 0)) {
4308 /* We can write it out with Wiretap. */
4312 if (cf->is_tempfile && !cf->unsaved_changes) {
4314 * Temporary file with no unsaved changes, so we can just do a
4320 /* Nothing to save. */
4325 * Does this file have unsaved data?
4328 cf_has_unsaved_data(capture_file *cf)
4331 * If this is a temporary file, or a file with unsaved changes, it
4334 return cf->is_tempfile || cf->unsaved_changes;
4338 * Quick scan to find packet offsets.
4340 static cf_read_status_t
4341 rescan_file(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
4343 const struct wtap_pkthdr *phdr;
4348 progdlg_t *progbar = NULL;
4352 GTimeVal start_time;
4353 gchar status_str[100];
4354 gint64 progbar_nextstep;
4355 gint64 progbar_quantum;
4360 int displayed_once = 0;
4363 /* Close the old handle. */
4364 wtap_close(cf->wth);
4366 /* Open the new file. */
4367 /* XXX: this will go through all open_routines for a matching one. But right
4368 now rescan_file() is only used when a file is being saved to a different
4369 format than the original, and the user is not given a choice of which
4370 reader to use (only which format to save it in), so doing this makes
4372 cf->wth = wtap_open_offline(fname, WTAP_TYPE_AUTO, err, &err_info, TRUE);
4373 if (cf->wth == NULL) {
4374 cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
4375 return CF_READ_ERROR;
4378 /* We're scanning a file whose contents should be the same as what
4379 we had before, so we don't discard dissection state etc.. */
4382 /* Set the file name because we need it to set the follow stream filter.
4383 XXX - is that still true? We need it for other reasons, though,
4385 cf->filename = g_strdup(fname);
4387 /* Indicate whether it's a permanent or temporary file. */
4388 cf->is_tempfile = is_tempfile;
4390 /* No user changes yet. */
4391 cf->unsaved_changes = FALSE;
4393 cf->cd_t = wtap_file_type_subtype(cf->wth);
4394 cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
4396 cf->snap = wtap_snapshot_length(cf->wth);
4397 if (cf->snap == 0) {
4398 /* Snapshot length not known. */
4399 cf->has_snap = FALSE;
4400 cf->snap = WTAP_MAX_PACKET_SIZE;
4402 cf->has_snap = TRUE;
4404 name_ptr = g_filename_display_basename(cf->filename);
4406 cf_callback_invoke(cf_cb_file_rescan_started, cf);
4408 /* Record whether the file is compressed.
4409 XXX - do we know this at open time? */
4410 cf->iscompressed = wtap_iscompressed(cf->wth);
4412 /* Find the size of the file. */
4413 size = wtap_file_size(cf->wth, NULL);
4415 /* Update the progress bar when it gets to this value. */
4416 progbar_nextstep = 0;
4417 /* When we reach the value that triggers a progress bar update,
4418 bump that value by this amount. */
4420 progbar_quantum = size/N_PROGBAR_UPDATES;
4421 if (progbar_quantum < MIN_QUANTUM)
4422 progbar_quantum = MIN_QUANTUM;
4424 progbar_quantum = 0;
4427 g_get_current_time(&start_time);
4430 phdr = wtap_phdr(cf->wth);
4431 while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
4433 fdata = frame_data_sequence_find(cf->frames, framenum);
4434 fdata->file_off = data_offset;
4437 file_pos = wtap_read_so_far(cf->wth);
4439 /* Create the progress bar if necessary.
4440 * Check whether it should be created or not every MIN_NUMBER_OF_PACKET
4442 if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)) {
4443 progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
4444 progbar = delayed_create_progress_dlg(cf->window, "Rescanning", name_ptr,
4445 TRUE, &stop_flag, &start_time, progbar_val);
4448 /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
4449 when we update it, we have to run the GTK+ main loop to get it
4450 to repaint what's pending, and doing so may involve an "ioctl()"
4451 to see if there's any pending input from an X server, and doing
4452 that for every packet can be costly, especially on a big file. */
4453 if (file_pos >= progbar_nextstep) {
4454 if (progbar != NULL) {
4455 progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
4456 /* update the packet bar content on the first run or frequently on very large files */
4458 if (progbar_quantum > 500000 || displayed_once == 0) {
4459 if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->count != 0) {
4461 packets_bar_update();
4464 #endif /* HAVE_LIBPCAP */
4465 update_progress_dlg(progbar, progbar_val, status_str);
4467 progbar_nextstep += progbar_quantum;
4472 /* Well, the user decided to abort the rescan. Sadly, as this
4473 isn't a reread, recovering is difficult, so we'll just
4474 close the current capture. */
4478 /* Add this packet's link-layer encapsulation type to cf->linktypes, if
4479 it's not already there.
4480 XXX - yes, this is O(N), so if every packet had a different
4481 link-layer encapsulation type, it'd be O(N^2) to read the file, but
4482 there are probably going to be a small number of encapsulation types
4484 cf_add_encapsulation_type(cf, phdr->pkt_encap);
4487 /* Free the display name */
4490 /* We're done reading the file; destroy the progress bar if it was created. */
4491 if (progbar != NULL)
4492 destroy_progress_dlg(progbar);
4494 /* We're done reading sequentially through the file. */
4495 cf->state = FILE_READ_DONE;
4497 /* Close the sequential I/O side, to free up memory it requires. */
4498 wtap_sequential_close(cf->wth);
4500 /* compute the time it took to load the file */
4501 compute_elapsed(cf, &start_time);
4503 /* Set the file encapsulation type now; we don't know what it is until
4504 we've looked at all the packets, as we don't know until then whether
4505 there's more than one type (and thus whether it's
4506 WTAP_ENCAP_PER_PACKET). */
4507 cf->lnk_t = wtap_file_encap(cf->wth);
4509 cf_callback_invoke(cf_cb_file_rescan_finished, cf);
4512 /* Our caller will give up at this point. */
4513 return CF_READ_ABORTED;
4517 /* Put up a message box noting that the read failed somewhere along
4518 the line. Don't throw out the stuff we managed to read, though,
4522 case WTAP_ERR_UNSUPPORTED:
4523 simple_error_message_box(
4524 "The capture file contains record data that Wireshark doesn't support.\n(%s)",
4525 err_info != NULL ? err_info : "no information supplied");
4529 case WTAP_ERR_SHORT_READ:
4530 simple_error_message_box(
4531 "The capture file appears to have been cut short"
4532 " in the middle of a packet.");
4535 case WTAP_ERR_BAD_FILE:
4536 simple_error_message_box(
4537 "The capture file appears to be damaged or corrupt.\n(%s)",
4538 err_info != NULL ? err_info : "no information supplied");
4542 case WTAP_ERR_DECOMPRESS:
4543 simple_error_message_box(
4544 "The compressed capture file appears to be damaged or corrupt.\n"
4546 err_info != NULL ? err_info : "no information supplied");
4551 simple_error_message_box(
4552 "An error occurred while reading the"
4553 " capture file: %s.", wtap_strerror(*err));
4556 return CF_READ_ERROR;
4562 cf_save_records(capture_file *cf, const char *fname, guint save_format,
4563 gboolean compressed, gboolean discard_comments,
4564 gboolean dont_reopen)
4567 gchar *fname_new = NULL;
4570 addrinfo_lists_t *addr_lists;
4574 gchar *display_basename;
4581 save_callback_args_t callback_args;
4583 cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
4585 addr_lists = get_addrinfo_list();
4587 if (save_format == cf->cd_t && compressed == cf->iscompressed
4588 && !discard_comments && !cf->unsaved_changes
4589 && !(addr_lists && wtap_dump_has_name_resolution(save_format))) {
4590 /* We're saving in the format it's already in, and we're
4591 not discarding comments, and there are no changes we have
4592 in memory that aren't saved to the file, and we have no name
4593 resolution blocks to write, so we can just move or copy the raw data. */
4595 if (cf->is_tempfile) {
4596 /* The file being saved is a temporary file from a live
4597 capture, so it doesn't need to stay around under that name;
4598 first, try renaming the capture buffer file to the new name.
4599 This acts as a "safe save", in that, if the file already
4600 exists, the existing file will be removed only if the rename
4603 Sadly, on Windows, as we have the current capture file
4604 open, even MoveFileEx() with MOVEFILE_REPLACE_EXISTING
4605 (to cause the rename to remove an existing target), as
4606 done by ws_stdio_rename() (ws_rename() is #defined to
4607 be ws_stdio_rename() on Windows) will fail.
4609 According to the MSDN documentation for CreateFile(), if,
4610 when we open a capture file, we were to directly do a CreateFile(),
4611 opening with FILE_SHARE_DELETE|FILE_SHARE_READ, and then
4612 convert it to a file descriptor with _open_osfhandle(),
4613 that would allow the file to be renamed out from under us.
4615 However, that doesn't work in practice. Perhaps the problem
4616 is that the process doing the rename is the process that
4617 has the file open. */
4619 if (ws_rename(cf->filename, fname) == 0) {
4620 /* That succeeded - there's no need to copy the source file. */
4621 how_to_save = SAVE_WITH_MOVE;
4623 if (errno == EXDEV) {
4624 /* They're on different file systems, so we have to copy the
4626 how_to_save = SAVE_WITH_COPY;
4628 /* The rename failed, but not because they're on different
4629 file systems - put up an error message. (Or should we
4630 just punt and try to copy? The only reason why I'd
4631 expect the rename to fail and the copy to succeed would
4632 be if we didn't have permission to remove the file from
4633 the temporary directory, and that might be fixable - but
4634 is it worth requiring the user to go off and fix it?) */
4635 cf_rename_failure_alert_box(fname, errno);
4640 how_to_save = SAVE_WITH_COPY;
4643 /* It's a permanent file, so we should copy it, and not remove the
4645 how_to_save = SAVE_WITH_COPY;
4648 if (how_to_save == SAVE_WITH_COPY) {
4649 /* Copy the file, if we haven't moved it. If we're overwriting
4650 an existing file, we do it with a "safe save", by writing
4651 to a new file and, if the write succeeds, renaming the
4652 new file on top of the old file. */
4653 if (file_exists(fname)) {
4654 fname_new = g_strdup_printf("%s~", fname);
4655 if (!copy_file_binary_mode(cf->filename, fname_new))
4658 if (!copy_file_binary_mode(cf->filename, fname))
4663 /* Either we're saving in a different format or we're saving changes,
4664 such as added, modified, or removed comments, that haven't yet
4665 been written to the underlying file; we can't do that by copying
4666 or moving the capture file, we have to do it by writing the packets
4669 wtapng_section_t *shb_hdr = NULL;
4670 wtapng_iface_descriptions_t *idb_inf = NULL;
4673 shb_hdr = wtap_file_get_shb_info(cf->wth);
4674 idb_inf = wtap_file_get_idb_info(cf->wth);
4676 /* Determine what file encapsulation type we should use. */
4677 encap = wtap_dump_file_encap_type(cf->linktypes);
4679 if (file_exists(fname)) {
4680 /* We're overwriting an existing file; write out to a new file,
4681 and, if that succeeds, rename the new file on top of the
4682 old file. That makes this a "safe save", so that we don't
4683 lose the old file if we have a problem writing out the new
4684 file. (If the existing file is the current capture file,
4685 we *HAVE* to do that, otherwise we're overwriting the file
4686 from which we're reading the packets that we're writing!) */
4687 fname_new = g_strdup_printf("%s~", fname);
4688 pdh = wtap_dump_open_ng(fname_new, save_format, encap, cf->snap,
4689 compressed, shb_hdr, idb_inf, &err);
4691 pdh = wtap_dump_open_ng(fname, save_format, encap, cf->snap,
4692 compressed, shb_hdr, idb_inf, &err);
4698 cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4702 /* Add address resolution */
4703 wtap_dump_set_addrinfo_list(pdh, addr_lists);
4705 /* Iterate through the list of packets, processing all the packets. */
4706 callback_args.pdh = pdh;
4707 callback_args.fname = fname;
4708 callback_args.file_type = save_format;
4709 switch (process_specified_records(cf, NULL, "Saving", "packets",
4710 TRUE, save_record, &callback_args)) {
4713 /* Completed successfully. */
4717 /* The user decided to abort the saving.
4718 If we're writing to a temporary file, remove it.
4719 XXX - should we do so even if we're not writing to a
4721 wtap_dump_close(pdh, &err);
4722 if (fname_new != NULL)
4723 ws_unlink(fname_new);
4724 cf_callback_invoke(cf_cb_file_save_stopped, NULL);
4725 return CF_WRITE_ABORTED;
4728 /* Error while saving.
4729 If we're writing to a temporary file, remove it. */
4730 if (fname_new != NULL)
4731 ws_unlink(fname_new);
4732 wtap_dump_close(pdh, &err);
4736 if (!wtap_dump_close(pdh, &err)) {
4737 cf_close_failure_alert_box(fname, err);
4741 how_to_save = SAVE_WITH_WTAP;
4744 if (fname_new != NULL) {
4745 /* We wrote out to fname_new, and should rename it on top of
4746 fname. fname_new is now closed, so that should be possible even
4747 on Windows. However, on Windows, we first need to close whatever
4748 file descriptors we have open for fname. */
4750 wtap_fdclose(cf->wth);
4752 /* Now do the rename. */
4753 if (ws_rename(fname_new, fname) == -1) {
4754 /* Well, the rename failed. */
4755 cf_rename_failure_alert_box(fname, errno);
4757 /* Attempt to reopen the random file descriptor using the
4758 current file's filename. (At this point, the sequential
4759 file descriptor is closed.) */
4760 if (!wtap_fdreopen(cf->wth, cf->filename, &err)) {
4761 /* Oh, well, we're screwed. */
4762 display_basename = g_filename_display_basename(cf->filename);
4763 simple_error_message_box(
4764 file_open_error_message(err, FALSE), display_basename);
4765 g_free(display_basename);
4772 cf_callback_invoke(cf_cb_file_save_finished, NULL);
4773 cf->unsaved_changes = FALSE;
4776 switch (how_to_save) {
4778 case SAVE_WITH_MOVE:
4779 /* We just moved the file, so the wtap structure refers to the
4780 new file, and all the information other than the filename
4781 and the "is temporary" status applies to the new file; just
4783 g_free(cf->filename);
4784 cf->filename = g_strdup(fname);
4785 cf->is_tempfile = FALSE;
4786 cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
4789 case SAVE_WITH_COPY:
4790 /* We just copied the file, s all the information other than
4791 the wtap structure, the filename, and the "is temporary"
4792 status applies to the new file; just update that. */
4793 wtap_close(cf->wth);
4794 /* Although we're just "copying" and then opening the copy, it will
4795 try all open_routine readers to open the copy, so we need to
4796 reset the cfile's open_type. */
4797 cf->open_type = WTAP_TYPE_AUTO;
4798 cf->wth = wtap_open_offline(fname, WTAP_TYPE_AUTO, &err, &err_info, TRUE);
4799 if (cf->wth == NULL) {
4800 cf_open_failure_alert_box(fname, err, err_info, FALSE, 0);
4803 g_free(cf->filename);
4804 cf->filename = g_strdup(fname);
4805 cf->is_tempfile = FALSE;
4807 cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
4810 case SAVE_WITH_WTAP:
4811 /* Open and read the file we saved to.
4813 XXX - this is somewhat of a waste; we already have the
4814 packets, all this gets us is updated file type information
4815 (which we could just stuff into "cf"), and having the new
4816 file be the one we have opened and from which we're reading
4817 the data, and it means we have to spend time opening and
4818 reading the file, which could be a significant amount of
4819 time if the file is large.
4821 If the capture-file-writing code were to return the
4822 seek offset of each packet it writes, we could save that
4823 in the frame_data structure for the frame, and just open
4824 the file without reading it again...
4826 ...as long as, for gzipped files, the process of writing
4827 out the file *also* generates the information needed to
4828 support fast random access to the compressed file. */
4829 /* rescan_file will cause us to try all open_routines, so
4830 reset cfile's open_type */
4831 cf->open_type = WTAP_TYPE_AUTO;
4832 if (rescan_file(cf, fname, FALSE, &err) != CF_READ_OK) {
4833 /* The rescan failed; just close the file. Either
4834 a dialog was popped up for the failure, so the
4835 user knows what happened, or they stopped the
4836 rescan, in which case they know what happened. */
4842 /* If we were told to discard the comments, do so. */
4843 if (discard_comments) {
4844 /* Remove SHB comment, if any. */
4845 wtap_write_shb_comment(cf->wth, NULL);
4847 /* remove all user comments */
4848 for (framenum = 1; framenum <= cf->count; framenum++) {
4849 fdata = frame_data_sequence_find(cf->frames, framenum);
4851 fdata->flags.has_phdr_comment = FALSE;
4852 fdata->flags.has_user_comment = FALSE;
4855 if (cf->frames_user_comments) {
4856 g_tree_destroy(cf->frames_user_comments);
4857 cf->frames_user_comments = NULL;
4860 cf->packet_comment_count = 0;
4866 if (fname_new != NULL) {
4867 /* We were trying to write to a temporary file; get rid of it if it
4868 exists. (We don't care whether this fails, as, if it fails,
4869 there's not much we can do about it. I guess if it failed for
4870 a reason other than "it doesn't exist", we could report an
4871 error, so the user knows there's a junk file that they might
4872 want to clean up.) */
4873 ws_unlink(fname_new);
4876 cf_callback_invoke(cf_cb_file_save_failed, NULL);
4877 return CF_WRITE_ERROR;
4881 cf_export_specified_packets(capture_file *cf, const char *fname,
4882 packet_range_t *range, guint save_format,
4883 gboolean compressed)
4885 gchar *fname_new = NULL;
4888 save_callback_args_t callback_args;
4889 wtapng_section_t *shb_hdr;
4890 wtapng_iface_descriptions_t *idb_inf;
4893 cf_callback_invoke(cf_cb_file_export_specified_packets_started, (gpointer)fname);
4895 packet_range_process_init(range);
4897 /* We're writing out specified packets from the specified capture
4898 file to another file. Even if all captured packets are to be
4899 written, don't special-case the operation - read each packet
4900 and then write it out if it's one of the specified ones. */
4902 shb_hdr = wtap_file_get_shb_info(cf->wth);
4903 idb_inf = wtap_file_get_idb_info(cf->wth);
4905 /* Determine what file encapsulation type we should use. */
4906 encap = wtap_dump_file_encap_type(cf->linktypes);
4908 if (file_exists(fname)) {
4909 /* We're overwriting an existing file; write out to a new file,
4910 and, if that succeeds, rename the new file on top of the
4911 old file. That makes this a "safe save", so that we don't
4912 lose the old file if we have a problem writing out the new
4913 file. (If the existing file is the current capture file,
4914 we *HAVE* to do that, otherwise we're overwriting the file
4915 from which we're reading the packets that we're writing!) */
4916 fname_new = g_strdup_printf("%s~", fname);
4917 pdh = wtap_dump_open_ng(fname_new, save_format, encap, cf->snap,
4918 compressed, shb_hdr, idb_inf, &err);
4920 pdh = wtap_dump_open_ng(fname, save_format, encap, cf->snap,
4921 compressed, shb_hdr, idb_inf, &err);
4927 cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4931 /* Add address resolution */
4932 wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
4934 /* Iterate through the list of packets, processing the packets we were
4937 XXX - we've already called "packet_range_process_init(range)", but
4938 "process_specified_records()" will do it again. Fortunately,
4939 that's harmless in this case, as we haven't done anything to
4940 "range" since we initialized it. */
4941 callback_args.pdh = pdh;
4942 callback_args.fname = fname;
4943 callback_args.file_type = save_format;
4944 switch (process_specified_records(cf, range, "Writing", "specified records",
4945 TRUE, save_record, &callback_args)) {
4948 /* Completed successfully. */
4952 /* The user decided to abort the saving.
4953 If we're writing to a temporary file, remove it.
4954 XXX - should we do so even if we're not writing to a
4956 wtap_dump_close(pdh, &err);
4957 if (fname_new != NULL)
4958 ws_unlink(fname_new);
4959 cf_callback_invoke(cf_cb_file_export_specified_packets_stopped, NULL);
4960 return CF_WRITE_ABORTED;
4964 /* Error while saving.
4965 If we're writing to a temporary file, remove it. */
4966 if (fname_new != NULL)
4967 ws_unlink(fname_new);
4968 wtap_dump_close(pdh, &err);
4972 if (!wtap_dump_close(pdh, &err)) {
4973 cf_close_failure_alert_box(fname, err);
4977 if (fname_new != NULL) {
4978 /* We wrote out to fname_new, and should rename it on top of
4979 fname; fname is now closed, so that should be possible even
4980 on Windows. Do the rename. */
4981 if (ws_rename(fname_new, fname) == -1) {
4982 /* Well, the rename failed. */
4983 cf_rename_failure_alert_box(fname, errno);
4988 cf_callback_invoke(cf_cb_file_export_specified_packets_finished, NULL);
4992 if (fname_new != NULL) {
4993 /* We were trying to write to a temporary file; get rid of it if it
4994 exists. (We don't care whether this fails, as, if it fails,
4995 there's not much we can do about it. I guess if it failed for
4996 a reason other than "it doesn't exist", we could report an
4997 error, so the user knows there's a junk file that they might
4998 want to clean up.) */
4999 ws_unlink(fname_new);
5002 cf_callback_invoke(cf_cb_file_export_specified_packets_failed, NULL);
5003 return CF_WRITE_ERROR;
5007 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
5008 gboolean for_writing, int file_type)
5010 gchar *display_basename;
5013 /* Wiretap error. */
5014 display_basename = g_filename_display_basename(filename);
5017 case WTAP_ERR_NOT_REGULAR_FILE:
5018 simple_error_message_box(
5019 "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
5023 case WTAP_ERR_RANDOM_OPEN_PIPE:
5024 /* Seen only when opening a capture file for reading. */
5025 simple_error_message_box(
5026 "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.\n"
5027 "To capture from a pipe or FIFO use wireshark -i -",
5031 case WTAP_ERR_FILE_UNKNOWN_FORMAT:
5032 /* Seen only when opening a capture file for reading. */
5033 simple_error_message_box(
5034 "The file \"%s\" isn't a capture file in a format Wireshark understands.",
5038 case WTAP_ERR_UNSUPPORTED:
5039 /* Seen only when opening a capture file for reading. */
5040 simple_error_message_box(
5041 "The file \"%s\" contains record data that Wireshark doesn't support.\n",
5044 err_info != NULL ? err_info : "no information supplied");
5048 case WTAP_ERR_CANT_WRITE_TO_PIPE:
5049 /* Seen only when opening a capture file for writing. */
5050 simple_error_message_box(
5051 "The file \"%s\" is a pipe, and %s capture files can't be "
5052 "written to a pipe.",
5053 display_basename, wtap_file_type_subtype_string(file_type));
5056 case WTAP_ERR_UNWRITABLE_FILE_TYPE:
5057 /* Seen only when opening a capture file for writing. */
5058 simple_error_message_box(
5059 "Wireshark doesn't support writing capture files in that format.");
5062 case WTAP_ERR_UNWRITABLE_ENCAP:
5063 /* Seen only when opening a capture file for writing. */
5064 simple_error_message_box("Wireshark can't save this capture in that format.");
5067 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
5069 simple_error_message_box(
5070 "Wireshark can't save this capture in that format.");
5072 simple_error_message_box(
5073 "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
5078 case WTAP_ERR_BAD_FILE:
5079 /* Seen only when opening a capture file for reading. */
5080 simple_error_message_box(
5081 "The file \"%s\" appears to be damaged or corrupt.\n"
5084 err_info != NULL ? err_info : "no information supplied");
5088 case WTAP_ERR_CANT_OPEN:
5090 simple_error_message_box(
5091 "The file \"%s\" could not be created for some unknown reason.",
5094 simple_error_message_box(
5095 "The file \"%s\" could not be opened for some unknown reason.",
5100 case WTAP_ERR_SHORT_READ:
5101 simple_error_message_box(
5102 "The file \"%s\" appears to have been cut short"
5103 " in the middle of a packet or other data.",
5107 case WTAP_ERR_SHORT_WRITE:
5108 simple_error_message_box(
5109 "A full header couldn't be written to the file \"%s\".",
5113 case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
5114 simple_error_message_box(
5115 "This file type cannot be written as a compressed file.");
5118 case WTAP_ERR_DECOMPRESS:
5119 simple_error_message_box(
5120 "The compressed file \"%s\" appears to be damaged or corrupt.\n"
5121 "(%s)", display_basename,
5122 err_info != NULL ? err_info : "no information supplied");
5127 simple_error_message_box(
5128 "The file \"%s\" could not be %s: %s.",
5130 for_writing ? "created" : "opened",
5131 wtap_strerror(err));
5134 g_free(display_basename);
5137 open_failure_alert_box(filename, err, for_writing);
5142 * XXX - whether we mention the source pathname, the target pathname,
5143 * or both depends on the error and on what we find if we look for
5144 * one or both of them.
5147 cf_rename_failure_alert_box(const char *filename, int err)
5149 gchar *display_basename;
5151 display_basename = g_filename_display_basename(filename);
5155 /* XXX - should check whether the source exists and, if not,
5156 report it as the problem and, if so, report the destination
5158 simple_error_message_box("The path to the file \"%s\" doesn't exist.",
5163 /* XXX - if we're doing a rename after a safe save, we should
5164 probably say something else. */
5165 simple_error_message_box("You don't have permission to move the capture file to \"%s\".",
5170 /* XXX - this should probably mention both the source and destination
5172 simple_error_message_box("The file \"%s\" could not be moved: %s.",
5173 display_basename, wtap_strerror(err));
5176 g_free(display_basename);
5179 /* Check for write errors - if the file is being written to an NFS server,
5180 a write error may not show up until the file is closed, as NFS clients
5181 might not send writes to the server until the "write()" call finishes,
5182 so that the write may fail on the server but the "write()" may succeed. */
5184 cf_close_failure_alert_box(const char *filename, int err)
5186 gchar *display_basename;
5189 /* Wiretap error. */
5190 display_basename = g_filename_display_basename(filename);
5193 case WTAP_ERR_CANT_CLOSE:
5194 simple_error_message_box(
5195 "The file \"%s\" couldn't be closed for some unknown reason.",
5199 case WTAP_ERR_SHORT_WRITE:
5200 simple_error_message_box(
5201 "Not all the packets could be written to the file \"%s\".",
5206 simple_error_message_box(
5207 "An error occurred while closing the file \"%s\": %s.",
5208 display_basename, wtap_strerror(err));
5211 g_free(display_basename);
5214 We assume that a close error from the OS is really a write error. */
5215 write_failure_alert_box(filename, err);
5219 /* Reload the current capture file. */
5221 cf_reload(capture_file *cf) {
5223 gboolean is_tempfile;
5226 /* If the file could be opened, "cf_open()" calls "cf_close()"
5227 to get rid of state for the old capture file before filling in state
5228 for the new capture file. "cf_close()" will remove the file if
5229 it's a temporary file; we don't want that to happen (for one thing,
5230 it'd prevent subsequent reopens from working). Remember whether it's
5231 a temporary file, mark it as not being a temporary file, and then
5232 reopen it as the type of file it was.
5234 Also, "cf_close()" will free "cf->filename", so we must make
5235 a copy of it first. */
5236 filename = g_strdup(cf->filename);
5237 is_tempfile = cf->is_tempfile;
5238 cf->is_tempfile = FALSE;
5239 if (cf_open(cf, filename, cf->open_type, is_tempfile, &err) == CF_OK) {
5240 switch (cf_read(cf, TRUE)) {
5244 /* Just because we got an error, that doesn't mean we were unable
5245 to read any of the file; we handle what we could get from the
5249 case CF_READ_ABORTED:
5250 /* The user bailed out of re-reading the capture file; the
5251 capture file has been closed - just free the capture file name
5252 string and return (without changing the last containing
5258 /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
5259 Instead, the file was left open, so we should restore "cf->is_tempfile"
5262 XXX - change the menu? Presumably "cf_open()" will do that;
5263 make sure it does! */
5264 cf->is_tempfile = is_tempfile;
5266 /* "cf_open()" made a copy of the file name we handed it, so
5267 we should free up our copy. */
5277 * indent-tabs-mode: nil
5280 * ex: set shiftwidth=2 tabstop=8 expandtab:
5281 * :indentSize=2:tabSize=8:noTabs=true: