#include "ui/progress_dlg.h"
#include "ui/ui_util.h"
+/* Needed for addrinfo */
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+# include <netdb.h>
+#endif
+
+#ifdef HAVE_WINSOCK2_H
+# include <winsock2.h>
+#endif
+
+#if defined(_WIN32) && defined(INET6)
+# include <ws2tcpip.h>
+#endif
+
#ifdef HAVE_LIBPCAP
gboolean auto_scroll_live;
#endif
static void cf_reset_state(capture_file *cf);
static int read_packet(capture_file *cf, dfilter_t *dfcode,
- epan_dissect_t *edt, column_info *cinfo, gint64 offset);
+ gboolean create_proto_tree, column_info *cinfo, gint64 offset);
static void rescan_packets(capture_file *cf, const char *action, const char *action_item, gboolean redissect);
static void match_subtree_text(proto_node *node, gpointer data);
static match_result match_summary_line(capture_file *cf, frame_data *fdata,
void *criterion);
-static match_result match_ascii_and_unicode(capture_file *cf, frame_data *fdata,
+static match_result match_narrow_and_wide(capture_file *cf, frame_data *fdata,
void *criterion);
-static match_result match_ascii(capture_file *cf, frame_data *fdata,
+static match_result match_narrow(capture_file *cf, frame_data *fdata,
void *criterion);
-static match_result match_unicode(capture_file *cf, frame_data *fdata,
+static match_result match_wide(capture_file *cf, frame_data *fdata,
void *criterion);
static match_result match_binary(capture_file *cf, frame_data *fdata,
void *criterion);
g_assert(cb_item != NULL);
while (cb_item != NULL) {
- cb = cb_item->data;
+ cb = (cf_callback_data_t *)cb_item->data;
cb->cb_fct(event, data, cb->user_data);
cb_item = g_list_next(cb_item);
}
{
cf_callback_data_t *cb;
- cb = g_malloc(sizeof(cf_callback_data_t));
+ cb = g_new(cf_callback_data_t,1);
cb->cb_fct = func;
cb->user_data = user_data;
GList *cb_item = cf_callbacks;
while (cb_item != NULL) {
- cb = cb_item->data;
+ cb = (cf_callback_data_t *)cb_item->data;
if (cb->cb_fct == func) {
cf_callbacks = g_list_remove(cf_callbacks, cb);
g_free(cb);
/*
* Add an encapsulation type to cf->linktypes.
*/
-void
+static void
cf_add_encapsulation_type(capture_file *cf, int encap)
{
guint i;
return progbar_val;
}
-static void
-epan_dissect_finish(epan_dissect_t *edt)
-{
- if (edt->tree)
- proto_tree_free(edt->tree);
-}
-
cf_read_status_t
cf_read(capture_file *cf, gboolean reloading)
{
int err;
gchar *err_info;
gchar *name_ptr;
- gint64 data_offset;
- gint64 file_pos;
progdlg_t *progbar = NULL;
gboolean stop_flag;
- gint64 size;
- float progbar_val;
GTimeVal start_time;
- gchar status_str[100];
- gint64 progbar_nextstep;
- volatile gint64 progbar_quantum;
dfilter_t *dfcode;
- column_info *cinfo;
- epan_dissect_t edt;
- gboolean create_proto_tree;
+ volatile gboolean create_proto_tree;
guint tap_flags;
- int count = 0;
-#ifdef HAVE_LIBPCAP
- int displayed_once = 0;
-#endif
gboolean compiled;
/* Compile the current display filter.
/* Get the union of the flags for all tap listeners. */
tap_flags = union_of_tap_listener_flags();
- cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
create_proto_tree =
(dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
- epan_dissect_init(&edt, create_proto_tree, FALSE);
- if (dfcode != NULL)
- epan_dissect_prime_dfilter(&edt, dfcode);
reset_tap_listeners();
XXX - do we know this at open time? */
cf->iscompressed = wtap_iscompressed(cf->wth);
- /* Find the size of the file. */
- size = wtap_file_size(cf->wth, NULL);
-
- /* Update the progress bar when it gets to this value. */
- progbar_nextstep = 0;
- /* When we reach the value that triggers a progress bar update,
- bump that value by this amount. */
- if (size >= 0) {
- progbar_quantum = size/N_PROGBAR_UPDATES;
- if (progbar_quantum < MIN_QUANTUM)
- progbar_quantum = MIN_QUANTUM;
- }else
- progbar_quantum = 0;
- /* Progress so far. */
- progbar_val = 0.0f;
-
/* The packet list window will be empty until the file is completly loaded */
packet_list_freeze();
stop_flag = FALSE;
g_get_current_time(&start_time);
- TRY
- while ((wtap_read(cf->wth, &err, &err_info, &data_offset))) {
+ TRY {
+#ifdef HAVE_LIBPCAP
+ int displayed_once = 0;
+#endif
+ int count = 0;
+
+ gint64 size;
+ gint64 file_pos;
+ gint64 data_offset;
+
+ gint64 progbar_quantum;
+ gint64 progbar_nextstep;
+ float progbar_val;
+ gchar status_str[100];
+
+ column_info *cinfo;
+
+ cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
+
+ /* Find the size of the file. */
+ size = wtap_file_size(cf->wth, NULL);
+
+ /* Update the progress bar when it gets to this value. */
+ progbar_nextstep = 0;
+ /* When we reach the value that triggers a progress bar update,
+ bump that value by this amount. */
if (size >= 0) {
- count++;
- file_pos = wtap_read_so_far(cf->wth);
+ progbar_quantum = size/N_PROGBAR_UPDATES;
+ if (progbar_quantum < MIN_QUANTUM)
+ progbar_quantum = MIN_QUANTUM;
+ }else
+ progbar_quantum = 0;
+ /* Progress so far. */
+ progbar_val = 0.0f;
- /* Create the progress bar if necessary.
- * Check whether it should be created or not every MIN_NUMBER_OF_PACKET
- */
- if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)) {
- progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
- if (reloading)
- progbar = delayed_create_progress_dlg(cf->window, "Reloading", name_ptr,
- TRUE, &stop_flag, &start_time, progbar_val);
- else
- progbar = delayed_create_progress_dlg(cf->window, "Loading", name_ptr,
- TRUE, &stop_flag, &start_time, progbar_val);
- }
+ while ((wtap_read(cf->wth, &err, &err_info, &data_offset))) {
+ if (size >= 0) {
+ count++;
+ file_pos = wtap_read_so_far(cf->wth);
- /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
- when we update it, we have to run the GTK+ main loop to get it
- to repaint what's pending, and doing so may involve an "ioctl()"
- to see if there's any pending input from an X server, and doing
- that for every packet can be costly, especially on a big file. */
- if (file_pos >= progbar_nextstep) {
- if (progbar != NULL) {
+ /* Create the progress bar if necessary.
+ * Check whether it should be created or not every MIN_NUMBER_OF_PACKET
+ */
+ if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)) {
progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
- /* update the packet bar content on the first run or frequently on very large files */
+ if (reloading)
+ progbar = delayed_create_progress_dlg(cf->window, "Reloading", name_ptr,
+ TRUE, &stop_flag, &start_time, progbar_val);
+ else
+ progbar = delayed_create_progress_dlg(cf->window, "Loading", name_ptr,
+ TRUE, &stop_flag, &start_time, progbar_val);
+ }
+
+ /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
+ when we update it, we have to run the GTK+ main loop to get it
+ to repaint what's pending, and doing so may involve an "ioctl()"
+ to see if there's any pending input from an X server, and doing
+ that for every packet can be costly, especially on a big file. */
+ if (file_pos >= progbar_nextstep) {
+ if (progbar != NULL) {
+ progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
+ /* update the packet bar content on the first run or frequently on very large files */
#ifdef HAVE_LIBPCAP
- if (progbar_quantum > 500000 || displayed_once == 0) {
- if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->count != 0) {
- displayed_once = 1;
- packets_bar_update();
+ if (progbar_quantum > 500000 || displayed_once == 0) {
+ if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->count != 0) {
+ displayed_once = 1;
+ packets_bar_update();
+ }
}
- }
#endif /* HAVE_LIBPCAP */
- update_progress_dlg(progbar, progbar_val, status_str);
+ update_progress_dlg(progbar, progbar_val, status_str);
+ }
+ progbar_nextstep += progbar_quantum;
}
- progbar_nextstep += progbar_quantum;
}
- }
- if (stop_flag) {
- /* Well, the user decided to abort the read. He/She will be warned and
- it might be enough for him/her to work with the already loaded
- packets.
- This is especially true for very large capture files, where you don't
- want to wait loading the whole file (which may last minutes or even
- hours even on fast machines) just to see that it was the wrong file. */
- break;
+ if (stop_flag) {
+ /* Well, the user decided to abort the read. He/She will be warned and
+ it might be enough for him/her to work with the already loaded
+ packets.
+ This is especially true for very large capture files, where you don't
+ want to wait loading the whole file (which may last minutes or even
+ hours even on fast machines) just to see that it was the wrong file. */
+ break;
+ }
+ read_packet(cf, dfcode, create_proto_tree, cinfo, data_offset);
}
- read_packet(cf, dfcode, &edt, cinfo, data_offset);
- }
+ }
CATCH(OutOfMemoryError) {
simple_message_box(ESD_TYPE_ERROR, NULL,
"Some infos / workarounds can be found at:\n"
#endif
}
ENDTRY;
- epan_dissect_finish(&edt);
/* Free the display name */
g_free(name_ptr);
}
cf_read_status_t
-cf_continue_tail(capture_file *cf, int to_read, int *err)
+cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
{
- gint64 data_offset = 0;
- gchar *err_info;
- int newly_displayed_packets = 0;
- dfilter_t *dfcode;
- column_info *cinfo;
- epan_dissect_t edt;
- gboolean create_proto_tree;
- guint tap_flags;
- gboolean compiled;
+ gchar *err_info;
+ int newly_displayed_packets = 0;
+ dfilter_t *dfcode;
+ volatile gboolean create_proto_tree;
+ guint tap_flags;
+ gboolean compiled;
/* Compile the current display filter.
* We assume this will not fail since cf->dfilter is only set in
/* Get the union of the flags for all tap listeners. */
tap_flags = union_of_tap_listener_flags();
- cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
create_proto_tree =
(dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
- epan_dissect_init(&edt, create_proto_tree, FALSE);
- if (dfcode != NULL)
- epan_dissect_prime_dfilter(&edt, dfcode);
*err = 0;
/*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: %u new: %u", cf->count, to_read);*/
- TRY
- while (to_read != 0) {
- wtap_cleareof(cf->wth);
- if (!wtap_read(cf->wth, err, &err_info, &data_offset)) {
- break;
- }
- if (cf->state == FILE_READ_ABORTED) {
- /* Well, the user decided to exit Wireshark. Break out of the
- loop, and let the code below (which is called even if there
- aren't any packets left to read) exit. */
- break;
- }
- if (read_packet(cf, dfcode, &edt, (column_info *) cinfo, data_offset) != -1) {
- newly_displayed_packets++;
+ TRY {
+ gint64 data_offset = 0;
+ column_info *cinfo;
+
+ cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
+
+ while (to_read != 0) {
+ wtap_cleareof(cf->wth);
+ if (!wtap_read(cf->wth, err, &err_info, &data_offset)) {
+ break;
+ }
+ if (cf->state == FILE_READ_ABORTED) {
+ /* Well, the user decided to exit Wireshark. Break out of the
+ loop, and let the code below (which is called even if there
+ aren't any packets left to read) exit. */
+ break;
+ }
+ if (read_packet(cf, dfcode, create_proto_tree, (column_info *) cinfo, data_offset) != -1) {
+ newly_displayed_packets++;
+ }
+ to_read--;
}
- to_read--;
}
CATCH(OutOfMemoryError) {
simple_message_box(ESD_TYPE_ERROR, NULL,
#endif
}
ENDTRY;
- epan_dissect_finish(&edt);
/* Update the file encapsulation; it might have changed based on the
packets we've read. */
dfilter_t *dfcode;
column_info *cinfo;
gboolean create_proto_tree;
- epan_dissect_t edt;
guint tap_flags;
gboolean compiled;
cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
create_proto_tree =
(dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
- epan_dissect_init(&edt, create_proto_tree, FALSE);
- if (dfcode != NULL)
- epan_dissect_prime_dfilter(&edt, dfcode);
if (cf->wth == NULL) {
cf_close(cf);
aren't any packets left to read) exit. */
break;
}
- read_packet(cf, dfcode, &edt, cinfo, data_offset);
+ read_packet(cf, dfcode, create_proto_tree, cinfo, data_offset);
}
- epan_dissect_finish(&edt);
/* Cleanup and release all dfilter resources */
if (dfcode != NULL) {
cf->rfcode = rfcode;
}
-static void
-find_and_mark_frame_depended_upon(gpointer data, gpointer user_data)
-{
- frame_data *dependent_fd;
- guint32 dependent_frame = GPOINTER_TO_UINT(data);
- capture_file *cf = (capture_file *)user_data;
-
- dependent_fd = frame_data_sequence_find(cf->frames, dependent_frame);
- dependent_fd->flags.dependent_of_displayed = 1;
-}
-
static int
add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
- dfilter_t *dfcode, epan_dissect_t *edt, column_info *cinfo,
+ dfilter_t *dfcode, gboolean create_proto_tree, column_info *cinfo,
struct wtap_pkthdr *phdr, const guchar *buf,
gboolean add_to_packet_list)
{
- gint row = -1;
+ epan_dissect_t edt;
+ gint row = -1;
frame_data_set_before_dissect(fdata, &cf->elapsed_time,
&first_ts, prev_dis, prev_cap);
prev_cap = fdata;
- epan_dissect_run_with_taps(edt, phdr, buf, fdata, cinfo);
+ /* Dissect the frame. */
+ epan_dissect_init(&edt, create_proto_tree, FALSE);
+
+ if (dfcode != NULL) {
+ epan_dissect_prime_dfilter(&edt, dfcode);
+ }
+
+ epan_dissect_run_with_taps(&edt, phdr, buf, fdata, cinfo);
/* If we don't have a display filter, set "passed_dfilter" to 1. */
if (dfcode != NULL) {
- fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, edt) ? 1 : 0;
+ fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, &edt) ? 1 : 0;
if (fdata->flags.passed_dfilter) {
/* This frame passed the display filter but it may depend on other
* (potentially not displayed) frames. Find those frames and mark them
* as depended upon.
*/
- g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf);
+ g_slist_foreach(edt.pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
}
} else
fdata->flags.passed_dfilter = 1;
if (add_to_packet_list) {
/* We fill the needed columns from new_packet_list */
- row = packet_list_append(cinfo, fdata, &edt->pi);
+ row = packet_list_append(cinfo, fdata, &edt.pi);
}
if (fdata->flags.passed_dfilter || fdata->flags.ref_time)
cf->last_displayed = fdata->num;
}
- epan_dissect_reset(edt);
+ epan_dissect_cleanup(&edt);
return row;
}
/* returns the row of the new packet in the packet list or -1 if not displayed */
static int
read_packet(capture_file *cf, dfilter_t *dfcode,
- epan_dissect_t *edt, column_info *cinfo, gint64 offset)
+ gboolean create_proto_tree, column_info *cinfo, gint64 offset)
{
struct wtap_pkthdr *phdr = wtap_phdr(cf->wth);
const guchar *buf = wtap_buf_ptr(cf->wth);
if (!cf->redissecting) {
row = add_packet_to_packet_list(fdata, cf, dfcode,
- edt, cinfo,
+ create_proto_tree, cinfo,
phdr, buf, TRUE);
}
}
wtapng_iface_descriptions_t *idb_inf, *idb_inf_merge_file;
wtapng_if_descr_t int_data, *file_int_data;
GString *comment_gstr;
- int i;
fake_interface_ids = TRUE;
/* Create SHB info */
- shb_hdr = wtap_file_get_shb_info(in_files[0].wth);
+ shb_hdr = wtap_file_get_shb_info(in_files[0].wth);
comment_gstr = g_string_new("");
g_string_append_printf(comment_gstr, "%s \n",shb_hdr->opt_comment);
g_string_append_printf(comment_gstr, "File created by merging: \n");
int progbar_quantum;
dfilter_t *dfcode;
column_info *cinfo;
- epan_dissect_t edt;
gboolean create_proto_tree;
guint tap_flags;
gboolean add_to_packet_list = FALSE;
cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
create_proto_tree =
(dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
- epan_dissect_init(&edt, create_proto_tree, FALSE);
- if (dfcode != NULL)
- epan_dissect_prime_dfilter(&edt, dfcode);
reset_tap_listeners();
/* Which frame, if any, is the currently selected frame?
* as not visited, free the GSList referring to the state
* data (the per-frame data itself was freed by
* "init_dissection()"), and null out the GSList pointer. */
- fdata->flags.visited = 0;
- frame_data_cleanup(fdata);
+ frame_data_reset(fdata);
frames_count = cf->count;
}
preceding_frame_num = prev_frame_num;
preceding_frame = prev_frame;
}
- add_packet_to_packet_list(fdata, cf, dfcode, &edt,
+ add_packet_to_packet_list(fdata, cf, dfcode, create_proto_tree,
cinfo, &cf->phdr, cf->pd,
add_to_packet_list);
prev_frame_num = fdata->num;
prev_frame = fdata;
}
- epan_dissect_finish(&edt);
/* We are done redissecting the packet list. */
cf->redissecting = FALSE;
until it finishes. Should we just stick them with that? */
for (; framenum <= frames_count; framenum++) {
fdata = frame_data_sequence_find(cf->frames, framenum);
- fdata->flags.visited = 0;
- frame_data_cleanup(fdata);
+ frame_data_reset(fdata);
}
}
struct wtap_pkthdr *phdr, const guint8 *pd,
void *argsp)
{
- retap_callback_args_t *args = argsp;
+ retap_callback_args_t *args = (retap_callback_args_t *)argsp;
epan_dissect_t edt;
epan_dissect_init(&edt, args->construct_protocol_tree, FALSE);
struct wtap_pkthdr *phdr, const guint8 *pd,
void *argsp)
{
- print_callback_args_t *args = argsp;
+ print_callback_args_t *args = (print_callback_args_t *)argsp;
epan_dissect_t edt;
int i;
char *cp;
if (line_len > args->line_buf_len) {
cp_off = (int) (cp - args->line_buf);
args->line_buf_len = 2 * line_len;
- args->line_buf = g_realloc(args->line_buf, args->line_buf_len + 1);
+ args->line_buf = (char *)g_realloc(args->line_buf, args->line_buf_len + 1);
cp = args->line_buf + cp_off;
}
if (print_args->print_summary) {
/* We're printing packet summaries. Allocate the header line buffer
and get the column widths. */
- callback_args.header_line_buf = g_malloc(callback_args.header_line_buf_len + 1);
+ callback_args.header_line_buf = (char *)g_malloc(callback_args.header_line_buf_len + 1);
/* Find the number of visible columns and the last visible column */
for (i = 0; i < prefs.num_cols; i++) {
if (line_len > callback_args.header_line_buf_len) {
cp_off = (int) (cp - callback_args.header_line_buf);
callback_args.header_line_buf_len = 2 * line_len;
- callback_args.header_line_buf = g_realloc(callback_args.header_line_buf,
+ callback_args.header_line_buf = (char *)g_realloc(callback_args.header_line_buf,
callback_args.header_line_buf_len + 1);
cp = callback_args.header_line_buf + cp_off;
}
/* Now start out the main line buffer with the same length as the
header line buffer. */
callback_args.line_buf_len = callback_args.header_line_buf_len;
- callback_args.line_buf = g_malloc(callback_args.line_buf_len + 1);
+ callback_args.line_buf = (char *)g_malloc(callback_args.line_buf_len + 1);
} /* if (print_summary) */
/* Iterate through the list of packets, printing the packets we were
struct wtap_pkthdr *phdr, const guint8 *pd,
void *argsp)
{
- FILE *fh = argsp;
+ FILE *fh = (FILE *)argsp;
epan_dissect_t edt;
/* Create the protocol tree, but don't fill in the column information. */
struct wtap_pkthdr *phdr, const guint8 *pd,
void *argsp)
{
- FILE *fh = argsp;
+ FILE *fh = (FILE *)argsp;
epan_dissect_t edt;
gboolean proto_tree_needed;
struct wtap_pkthdr *phdr, const guint8 *pd,
void *argsp)
{
- FILE *fh = argsp;
+ FILE *fh = (FILE *)argsp;
epan_dissect_t edt;
gboolean proto_tree_needed;
struct wtap_pkthdr *phdr,
const guint8 *pd, void *argsp)
{
- FILE *fh = argsp;
+ FILE *fh = (FILE *)argsp;
epan_dissect_t edt;
epan_dissect_init(&edt, TRUE, TRUE);
static match_result
match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
{
- match_data *mdata = criterion;
+ match_data *mdata = (match_data *)criterion;
epan_dissect_t edt;
/* Load the frame's data. */
static match_result
match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
{
- match_data *mdata = criterion;
+ match_data *mdata = (match_data *)criterion;
const gchar *string = mdata->string;
size_t string_len = mdata->string_len;
epan_dissect_t edt;
size_t data_len;
} cbs_t; /* "Counted byte string" */
+
+/*
+ * The current match_* routines only support ASCII case insensitivity and don't
+ * convert UTF-8 inputs to UTF-16 for matching.
+ *
+ * We could modify them to use the GLib Unicode routines or the International
+ * Components for Unicode library but it's not apparent that we could do so
+ * without consuming a lot more CPU and memory or that searching would be
+ * significantly better.
+ */
+
gboolean
cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size,
search_direction dir)
/* String search - what type of string? */
switch (cf->scs_type) {
- case SCS_ASCII_AND_UNICODE:
- return find_packet(cf, match_ascii_and_unicode, &info, dir);
+ case SCS_NARROW_AND_WIDE:
+ return find_packet(cf, match_narrow_and_wide, &info, dir);
- case SCS_ASCII:
- return find_packet(cf, match_ascii, &info, dir);
+ case SCS_NARROW:
+ return find_packet(cf, match_narrow, &info, dir);
- case SCS_UNICODE:
- return find_packet(cf, match_unicode, &info, dir);
+ case SCS_WIDE:
+ return find_packet(cf, match_wide, &info, dir);
default:
g_assert_not_reached();
}
static match_result
-match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
+match_narrow_and_wide(capture_file *cf, frame_data *fdata, void *criterion)
{
- cbs_t *info = criterion;
+ cbs_t *info = (cbs_t *)criterion;
const guint8 *ascii_text = info->data;
size_t textlen = info->data_len;
match_result result;
}
static match_result
-match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
+match_narrow(capture_file *cf, frame_data *fdata, void *criterion)
{
- cbs_t *info = criterion;
+ cbs_t *info = (cbs_t *)criterion;
const guint8 *ascii_text = info->data;
size_t textlen = info->data_len;
match_result result;
}
static match_result
-match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
+match_wide(capture_file *cf, frame_data *fdata, void *criterion)
{
- cbs_t *info = criterion;
+ cbs_t *info = (cbs_t *)criterion;
const guint8 *ascii_text = info->data;
size_t textlen = info->data_len;
match_result result;
static match_result
match_binary(capture_file *cf, frame_data *fdata, void *criterion)
{
- cbs_t *info = criterion;
+ cbs_t *info = (cbs_t *)criterion;
const guint8 *binary_data = info->data;
size_t datalen = info->data_len;
match_result result;
static match_result
match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
{
- dfilter_t *sfcode = criterion;
+ dfilter_t *sfcode = (dfilter_t *)criterion;
epan_dissect_t edt;
match_result result;
cf->edt = epan_dissect_new(TRUE, TRUE);
tap_build_interesting(cf->edt);
- epan_dissect_run(cf->edt, &cf->phdr, cf->pd, cf->current_frame,
+ epan_dissect_run(cf->edt, &cf->phdr, cf->pd, cf->current_frame,
NULL);
dfilter_macro_build_ftv_cache(cf->edt->tree);
}
/*
- * Does this capture file have any comments?
+ * What types of comments does this capture file have?
*/
-gboolean
-cf_has_comments(capture_file *cf)
+guint32
+cf_comment_types(capture_file *cf)
{
- return (cf_read_shb_comment(cf) != NULL || cf->packet_comment_count != 0);
+ guint32 comment_types = 0;
+
+ if (cf_read_shb_comment(cf) != NULL)
+ comment_types |= WTAP_COMMENT_PER_SECTION;
+ if (cf->packet_comment_count != 0)
+ comment_types |= WTAP_COMMENT_PER_PACKET;
+ return comment_types;
}
typedef struct {
struct wtap_pkthdr *phdr, const guint8 *pd,
void *argsp)
{
- save_callback_args_t *args = argsp;
+ save_callback_args_t *args = (save_callback_args_t *)argsp;
struct wtap_pkthdr hdr;
int err;
gchar *display_basename;
hdr.presence_flags |= WTAP_HAS_TS;
if (fdata->flags.has_if_id)
hdr.presence_flags |= WTAP_HAS_INTERFACE_ID;
+ if (fdata->flags.has_pack_flags)
+ hdr.presence_flags |= WTAP_HAS_PACK_FLAGS;
hdr.ts.secs = fdata->abs_ts.secs;
hdr.ts.nsecs = fdata->abs_ts.nsecs;
hdr.caplen = fdata->cap_len;
/* pcapng */
hdr.interface_id = fdata->interface_id; /* identifier of the interface. */
/* options */
+ hdr.pack_flags = fdata->pack_flags;
hdr.opt_comment = fdata->opt_comment; /* NULL if not available */
/* pseudo */
hdr.pseudo_header = phdr->pseudo_header;
gboolean
cf_can_write_with_wiretap(capture_file *cf)
{
- int ft;
-
- for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
- /* To save a file with Wiretap, Wiretap has to handle that format,
- and its code to handle that format must be able to write a file
- with this file's encapsulation types. */
- if (wtap_dump_can_write_encaps(ft, cf->linktypes)) {
- /* OK, we can write it out in this type. */
- return TRUE;
- }
+ /* We don't care whether we support the comments in this file or not;
+ if we can't, we'll offer the user the option of discarding the
+ comments. */
+ return wtap_dump_can_write(cf->linktypes, 0);
+}
+
+/*
+ * Should we let the user do a save?
+ *
+ * We should if:
+ *
+ * the file has unsaved changes, and we can save it in some
+ * format through Wiretap
+ *
+ * or
+ *
+ * the file is a temporary file and has no unsaved changes (so
+ * that "saving" it just means copying it).
+ *
+ * XXX - we shouldn't allow files to be edited if they can't be saved,
+ * so cf->unsaved_changes should be true only if the file can be saved.
+ *
+ * We don't care whether we support the comments in this file or not;
+ * if we can't, we'll offer the user the option of discarding the
+ * comments.
+ */
+gboolean
+cf_can_save(capture_file *cf)
+{
+ if (cf->unsaved_changes && wtap_dump_can_write(cf->linktypes, 0)) {
+ /* Saved changes, and we can write it out with Wiretap. */
+ return TRUE;
+ }
+
+ if (cf->is_tempfile && !cf->unsaved_changes) {
+ /*
+ * Temporary file with no unsaved changes, so we can just do a
+ * raw binary copy.
+ */
+ return TRUE;
+ }
+
+ /* Nothing to save. */
+ return FALSE;
+}
+
+/*
+ * Should we let the user do a "save as"?
+ *
+ * That's true if:
+ *
+ * we can save it in some format through Wiretap
+ *
+ * or
+ *
+ * the file is a temporary file and has no unsaved changes (so
+ * that "saving" it just means copying it).
+ *
+ * XXX - we shouldn't allow files to be edited if they can't be saved,
+ * so cf->unsaved_changes should be true only if the file can be saved.
+ *
+ * We don't care whether we support the comments in this file or not;
+ * if we can't, we'll offer the user the option of discarding the
+ * comments.
+ */
+gboolean
+cf_can_save_as(capture_file *cf)
+{
+ if (wtap_dump_can_write(cf->linktypes, 0)) {
+ /* We can write it out with Wiretap. */
+ return TRUE;
+ }
+
+ if (cf->is_tempfile && !cf->unsaved_changes) {
+ /*
+ * Temporary file with no unsaved changes, so we can just do a
+ * raw binary copy.
+ */
+ return TRUE;
}
- /* No, we couldn't save it in any format. */
+ /* Nothing to save. */
return FALSE;
}
+/*
+ * Does this file have unsaved data?
+ */
+gboolean
+cf_has_unsaved_data(capture_file *cf)
+{
+ /*
+ * If this is a temporary file, or a file with unsaved changes, it
+ * has unsaved data.
+ */
+ return cf->is_tempfile || cf->unsaved_changes;
+}
+
/*
* Quick scan to find packet offsets.
*/
gboolean compressed, gboolean discard_comments,
gboolean dont_reopen)
{
- gchar *fname_new = NULL;
- int err;
- gchar *err_info;
+ gchar *err_info;
+ gchar *fname_new = NULL;
+ wtap_dumper *pdh;
+ frame_data *fdata;
+ struct addrinfo *addrs;
+ guint framenum;
+ int err;
+#ifdef _WIN32
+ gchar *display_basename;
+#endif
enum {
SAVE_WITH_MOVE,
SAVE_WITH_COPY,
SAVE_WITH_WTAP
- } how_to_save;
- wtap_dumper *pdh;
+ } how_to_save;
save_callback_args_t callback_args;
-#ifdef _WIN32
- gchar *display_basename;
-#endif
- guint framenum;
- frame_data *fdata;
cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
+ addrs = get_addrinfo_list();
+
if (save_format == cf->cd_t && compressed == cf->iscompressed
- && !discard_comments && !cf->unsaved_changes) {
+ && !discard_comments && !cf->unsaved_changes
+ && !(addrs && addrs->ai_next &&
+ wtap_dump_has_name_resolution(save_format))) {
/* We're saving in the format it's already in, and we're
not discarding comments, and there are no changes we have
- in memory that aren't saved to the file, so we can just move
- or copy the raw data. */
+ in memory that aren't saved to the file, and we have no name
+ resolution blocks to write, so we can just move or copy the raw data. */
if (cf->is_tempfile) {
/* The file being saved is a temporary file from a live
}
/* Add address resolution */
- wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
+ wtap_dump_set_addrinfo_list(pdh, addrs);
/* Iterate through the list of packets, processing all the packets. */
callback_args.pdh = pdh;