#endif
#include <epan/epan.h>
+#include <epan/expert.h>
#include <epan/filesystem.h>
#include "color.h"
#include <epan/column.h>
#include <epan/packet.h>
#include <epan/column-utils.h>
-#include "packet-range.h"
-#include "print.h"
#include "file.h"
#include "fileset.h"
-#include "tempfile.h"
+#include "frame_tvbuff.h"
+#include "wsutil/tempfile.h"
#include "merge.h"
#include <epan/prefs.h>
#include "ui/progress_dlg.h"
#include "ui/ui_util.h"
+#include "version_info.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 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);
and fill in the information for this file. */
cf_close(cf);
+ /* XXX - we really want to initialize this after we've read all
+ the packets, so we know how much we'll ultimately need. */
+ buffer_init(&cf->buf, 1500);
+
/* Cleanup all data structures used for dissection. */
cleanup_dissection();
/* Initialize all data structures used for dissection. */
/*
* Add an encapsulation type to cf->linktypes.
*/
-void
+static void
cf_add_encapsulation_type(capture_file *cf, int encap)
{
guint i;
/* ...which means we have no changes to that file to save. */
cf->unsaved_changes = FALSE;
+ /* Free up the packet buffer. */
+ buffer_free(&cf->buf);
+
dfilter_free(cf->rfcode);
cf->rfcode = NULL;
if (cf->frames != NULL) {
if (size >= 0) {
progbar_quantum = size/N_PROGBAR_UPDATES;
if (progbar_quantum < MIN_QUANTUM)
- progbar_quantum = MIN_QUANTUM;
+ progbar_quantum = MIN_QUANTUM;
}else
progbar_quantum = 0;
- /* Progress so far. */
- progbar_val = 0.0f;
while ((wtap_read(cf->wth, &err, &err_info, &data_offset))) {
if (size >= 0) {
- count++;
- file_pos = wtap_read_so_far(cf->wth);
-
- /* 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);
- }
-
- /* 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 */
+ count++;
+ file_pos = wtap_read_so_far(cf->wth);
+
+ /* 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);
+ }
+
+ /* 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);
- }
- progbar_nextstep += progbar_quantum;
- }
+ update_progress_dlg(progbar, progbar_val, status_str);
+ }
+ 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;
+ /* 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);
- }
+ }
}
CATCH(OutOfMemoryError) {
simple_message_box(ESD_TYPE_ERROR, NULL,
while (to_read != 0) {
wtap_cleareof(cf->wth);
if (!wtap_read(cf->wth, err, &err_info, &data_offset)) {
- break;
+ 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;
+ /* 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++;
+ newly_displayed_packets++;
}
to_read--;
}
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, gboolean create_proto_tree, column_info *cinfo,
- struct wtap_pkthdr *phdr, const guchar *buf,
- gboolean add_to_packet_list)
+ struct wtap_pkthdr *phdr, const guint8 *buf, gboolean add_to_packet_list)
{
epan_dissect_t edt;
gint row = -1;
epan_dissect_prime_dfilter(&edt, dfcode);
}
- epan_dissect_run_with_taps(&edt, phdr, buf, fdata, cinfo);
+ epan_dissect_run_with_taps(&edt, phdr, frame_tvbuff_new(fdata, buf), fdata, cinfo);
/* If we don't have a display filter, set "passed_dfilter" to 1. */
if (dfcode != NULL) {
* (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;
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);
+ const guint8 *buf = wtap_buf_ptr(cf->wth);
frame_data fdlocal;
guint32 framenum;
frame_data *fdata;
epan_dissect_t edt;
epan_dissect_init(&edt, TRUE, FALSE);
epan_dissect_prime_dfilter(&edt, cf->rfcode);
- epan_dissect_run(&edt, phdr, buf, &fdlocal, NULL);
+ epan_dissect_run(&edt, phdr, frame_tvbuff_new(&fdlocal, buf), &fdlocal, NULL);
passed = dfilter_apply_edt(cf->rfcode, &edt);
epan_dissect_cleanup(&edt);
}
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");
gboolean
cf_read_frame_r(capture_file *cf, frame_data *fdata,
- struct wtap_pkthdr *phdr, guint8 *pd)
+ struct wtap_pkthdr *phdr, Buffer *buf)
{
int err;
gchar *err_info;
}
*phdr = frame->phdr;
- memcpy(pd, frame->pd, fdata->cap_len);
+ buffer_assure_space(buf, frame->phdr.caplen);
+ memcpy(buffer_start_ptr(buf), frame->pd, frame->phdr.caplen);
return TRUE;
}
#endif
- if (!wtap_seek_read(cf->wth, fdata->file_off, phdr, pd,
+ if (!wtap_seek_read(cf->wth, fdata->file_off, phdr, buf,
fdata->cap_len, &err, &err_info)) {
display_basename = g_filename_display_basename(cf->filename);
switch (err) {
gboolean
cf_read_frame(capture_file *cf, frame_data *fdata)
{
- return cf_read_frame_r(cf, fdata, &cf->phdr, cf->pd);
+ return cf_read_frame_r(cf, fdata, &cf->phdr, &cf->buf);
}
/* Rescan the list of packets, reconstructing the CList.
* 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 = prev_frame;
}
add_packet_to_packet_list(fdata, cf, dfcode, create_proto_tree,
- cinfo, &cf->phdr, cf->pd,
+ cinfo, &cf->phdr,
+ buffer_start_ptr(&cf->buf),
add_to_packet_list);
/* If this frame is displayed, and this is the first frame we've
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);
}
}
{
guint32 framenum;
frame_data *fdata;
- guint8 pd[WTAP_MAX_PACKET_SIZE+1];
+ Buffer buf;
psp_return_t ret = PSP_FINISHED;
progdlg_t *progbar = NULL;
range_process_e process_this;
struct wtap_pkthdr phdr;
+ buffer_init(&buf, 1500);
+
/* Update the progress bar when it gets to this value. */
progbar_nextstep = 0;
/* When we reach the value that triggers a progress bar update,
}
/* Get the packet */
- if (!cf_read_frame_r(cf, fdata, &phdr, pd)) {
+ if (!cf_read_frame_r(cf, fdata, &phdr, &buf)) {
/* Attempt to get the packet failed. */
ret = PSP_FAILED;
break;
}
/* Process the packet */
- if (!callback(cf, fdata, &phdr, pd, callback_args)) {
+ if (!callback(cf, fdata, &phdr, buffer_start_ptr(&buf), callback_args)) {
/* Callback failed. We assume it reported the error appropriately. */
ret = PSP_FAILED;
break;
if (progbar != NULL)
destroy_progress_dlg(progbar);
+ buffer_free(&buf);
+
return ret;
}
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);
- epan_dissect_run_with_taps(&edt, phdr, pd, fdata, args->cinfo);
+ epan_dissect_run_with_taps(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, args->cinfo);
epan_dissect_cleanup(&edt);
return TRUE;
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;
information. */
if (args->print_args->print_summary) {
col_custom_prime_edt(&edt, &cf->cinfo);
- epan_dissect_run(&edt, phdr, pd, fdata, &cf->cinfo);
+ epan_dissect_run(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
} else
- epan_dissect_run(&edt, phdr, pd, fdata, NULL);
+ epan_dissect_run(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
if (args->print_formfeed) {
if (!new_page(args->print_args->stream))
g_snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
if (args->print_args->print_summary) {
+ if (!args->print_args->print_col_headings)
+ args->print_header_line = FALSE;
if (args->print_header_line) {
if (!print_line(args->print_args->stream, 0, args->header_line_buf))
goto fail;
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;
}
args->print_separator = TRUE;
/* Print a header line if we print any more packet summaries */
- args->print_header_line = TRUE;
+ if (args->print_args->print_col_headings)
+ args->print_header_line = TRUE;
}
if (args->print_args->print_hex) {
args->print_separator = TRUE;
/* Print a header line if we print any more packet summaries */
- args->print_header_line = TRUE;
+ if (args->print_args->print_col_headings)
+ args->print_header_line = TRUE;
} /* if (args->print_args->print_dissections != print_dissections_none) */
epan_dissect_cleanup(&edt);
fmt_data *cfmt;
callback_args.print_args = print_args;
- callback_args.print_header_line = TRUE;
+ callback_args.print_header_line = print_args->print_col_headings;
callback_args.header_line_buf = NULL;
callback_args.header_line_buf_len = 256;
callback_args.print_formfeed = FALSE;
callback_args.num_visible_cols = 0;
callback_args.visible_cols = NULL;
- if (!print_preamble(print_args->stream, cf->filename)) {
+ if (!print_preamble(print_args->stream, cf->filename, wireshark_svnversion)) {
destroy_print_stream(print_args->stream);
return CF_PRINT_WRITE_ERROR;
}
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. */
epan_dissect_init(&edt, TRUE, TRUE);
- epan_dissect_run(&edt, phdr, pd, fdata, NULL);
+ epan_dissect_run(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
/* Write out the information in that tree. */
proto_tree_write_pdml(&edt, fh);
struct wtap_pkthdr *phdr, const guint8 *pd,
void *argsp)
{
- FILE *fh = argsp;
+ FILE *fh = (FILE *)argsp;
epan_dissect_t edt;
gboolean proto_tree_needed;
proto_tree_needed = have_custom_cols(&cf->cinfo);
epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
col_custom_prime_edt(&edt, &cf->cinfo);
- epan_dissect_run(&edt, phdr, pd, fdata, &cf->cinfo);
+ epan_dissect_run(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
/* Write out the information in that tree. */
struct wtap_pkthdr *phdr, const guint8 *pd,
void *argsp)
{
- FILE *fh = argsp;
+ FILE *fh = (FILE *)argsp;
epan_dissect_t edt;
gboolean proto_tree_needed;
proto_tree_needed = have_custom_cols(&cf->cinfo);
epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
col_custom_prime_edt(&edt, &cf->cinfo);
- epan_dissect_run(&edt, phdr, pd, fdata, &cf->cinfo);
+ epan_dissect_run(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
/* Write out the information in that tree. */
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);
- epan_dissect_run(&edt, phdr, pd, fdata, NULL);
+ epan_dissect_run(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
proto_tree_write_carrays(fdata->num, fh, &edt);
epan_dissect_cleanup(&edt);
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. */
/* Construct the protocol tree, including the displayed text */
epan_dissect_init(&edt, TRUE, TRUE);
/* We don't need the column information */
- epan_dissect_run(&edt, &cf->phdr, cf->pd, fdata, NULL);
+ epan_dissect_run(&edt, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
/* Iterate through all the nodes, seeing if they have text that matches. */
mdata->cf = cf;
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;
/* Don't bother constructing the protocol tree */
epan_dissect_init(&edt, FALSE, FALSE);
/* Get the column information */
- epan_dissect_run(&edt, &cf->phdr, cf->pd, fdata, &cf->cinfo);
+ epan_dissect_run(&edt, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata,
+ &cf->cinfo);
/* Find the Info column */
for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
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;
guint32 buf_len;
+ guint8 *pd;
guint32 i;
guint8 c_char;
size_t c_match = 0;
result = MR_NOTMATCHED;
buf_len = fdata->cap_len;
+ pd = buffer_start_ptr(&cf->buf);
i = 0;
while (i < buf_len) {
- c_char = cf->pd[i];
+ c_char = pd[i];
if (cf->case_type)
c_char = toupper(c_char);
if (c_char != '\0') {
}
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;
+ guint8 *pd;
+ cbs_t *info = (cbs_t *)criterion;
const guint8 *ascii_text = info->data;
size_t textlen = info->data_len;
match_result result;
result = MR_NOTMATCHED;
buf_len = fdata->cap_len;
+ pd = buffer_start_ptr(&cf->buf);
i = 0;
while (i < buf_len) {
- c_char = cf->pd[i];
+ c_char = pd[i];
if (cf->case_type)
c_char = toupper(c_char);
if (c_char == ascii_text[c_match]) {
}
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;
guint32 buf_len;
+ guint8 *pd;
guint32 i;
guint8 c_char;
size_t c_match = 0;
result = MR_NOTMATCHED;
buf_len = fdata->cap_len;
+ pd = buffer_start_ptr(&cf->buf);
i = 0;
while (i < buf_len) {
- c_char = cf->pd[i];
+ c_char = pd[i];
if (cf->case_type)
c_char = toupper(c_char);
if (c_char == ascii_text[c_match]) {
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;
guint32 buf_len;
+ guint8 *pd;
guint32 i;
size_t c_match = 0;
result = MR_NOTMATCHED;
buf_len = fdata->cap_len;
+ pd = buffer_start_ptr(&cf->buf);
i = 0;
while (i < buf_len) {
- if (cf->pd[i] == binary_data[c_match]) {
+ if (pd[i] == binary_data[c_match]) {
c_match += 1;
if (c_match == datalen) {
result = MR_MATCHED;
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;
epan_dissect_init(&edt, TRUE, FALSE);
epan_dissect_prime_dfilter(&edt, sfcode);
- epan_dissect_run(&edt, &cf->phdr, cf->pd, fdata, NULL);
+ epan_dissect_run(&edt, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
result = dfilter_apply_edt(sfcode, &edt) ? MR_MATCHED : MR_NOTMATCHED;
epan_dissect_cleanup(&edt);
return 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,
- NULL);
+ epan_dissect_run(cf->edt, &cf->phdr, frame_tvbuff_new_buffer(cf->current_frame, &cf->buf),
+ cf->current_frame, NULL);
dfilter_macro_build_ftv_cache(cf->edt->tree);
cf->packet_comment_count++;
}
+ expert_update_comment_count(cf->packet_comment_count);
+
/* OK, we have unsaved changes. */
cf->unsaved_changes = TRUE;
}
/*
- * 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;
}
- /* No, we couldn't save it in any format. */
+ 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;
}
+/*
+ * 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.
*/
progbar_quantum = MIN_QUANTUM;
}else
progbar_quantum = 0;
- /* Progress so far. */
- progbar_val = 0.0f;
stop_flag = FALSE;
g_get_current_time(&start_time);
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;