#include <epan/conversation.h>
#include <epan/epan_dissect.h>
#include <epan/tap.h>
-#include "stat_menu.h"
-#include "tap_dfilter_dlg.h"
#include <epan/dissectors/packet-data.h>
#include <epan/dissectors/packet-ber.h>
#include <epan/timestamp.h>
#include <epan/dfilter/dfilter-macro.h>
-#include "file_util.h"
+#include <wsutil/file_util.h>
#include <epan/column-utils.h>
#include <epan/strutil.h>
-#include <epan/emem.h>
#ifdef HAVE_LIBPCAP
gboolean auto_scroll_live;
#define FRAME_DATA_CHUNK_SIZE 1024
-/* one callback for now, we could have a list later */
-static cf_callback_t cf_cb = NULL;
-static gpointer cf_cb_user_data = NULL;
+/* this callback mechanism should possibly be replaced by the g_signal_...() stuff (if I only would know how :-) */
+typedef struct {
+ cf_callback_t cb_fct;
+ gpointer user_data;
+} cf_callback_data_t;
-void
+static GList *cf_callbacks = NULL;
+
+static void
cf_callback_invoke(int event, gpointer data)
{
- g_assert(cf_cb != NULL);
- cf_cb(event, data, cf_cb_user_data);
+ cf_callback_data_t *cb;
+ GList *cb_item = cf_callbacks;
+
+ /* there should be at least one interested */
+ g_assert(cb_item != NULL);
+
+ while(cb_item != NULL) {
+ cb = cb_item->data;
+ cb->cb_fct(event, data, cb->user_data);
+ cb_item = g_list_next(cb_item);
+ }
}
void
cf_callback_add(cf_callback_t func, gpointer user_data)
{
- /* More than one callback listener is currently not implemented,
- but should be easy to do. */
- g_assert(cf_cb == NULL);
- cf_cb = func;
- cf_cb_user_data = user_data;
+ cf_callback_data_t *cb;
+
+ cb = g_malloc(sizeof(cf_callback_data_t));
+ cb->cb_fct = func;
+ cb->user_data = user_data;
+
+ cf_callbacks = g_list_append(cf_callbacks, cb);
}
void
-cf_callback_remove(cf_callback_t func _U_)
+cf_callback_remove(cf_callback_t func)
{
- g_assert(cf_cb != NULL);
- cf_cb = NULL;
- cf_cb_user_data = NULL;
+ cf_callback_data_t *cb;
+ GList *cb_item = cf_callbacks;
+
+ while(cb_item != NULL) {
+ cb = cb_item->data;
+ if(cb->cb_fct == func) {
+ cf_callbacks = g_list_remove(cf_callbacks, cb);
+ g_free(cb);
+ return;
+ }
+ cb_item = g_list_next(cb_item);
+ }
+
+ g_assert_not_reached();
}
void
if (cf->filename != NULL) {
/* If it's a temporary file, remove it. */
if (cf->is_tempfile)
- eth_unlink(cf->filename);
+ ws_unlink(cf->filename);
g_free(cf->filename);
cf->filename = NULL;
}
/* No frame selected, no field in that frame selected. */
cf->current_frame = NULL;
+ cf->current_row = 0;
cf->finfo_selected = NULL;
/* Clear the packet list. */
const gchar *name_ptr;
const char *errmsg;
char errmsg_errno[1024+1];
- gchar err_str[2048+1];
gint64 data_offset;
progdlg_t *volatile progbar = NULL;
gboolean stop_flag;
cum_bytes=0;
reset_tap_listeners();
- tap_dfilter_dlg_update();
cf_callback_invoke(cf_cb_file_read_start, cf);
cf->lnk_t = wtap_file_encap(cf->wth);
cf->current_frame = cf->first_displayed;
+ cf->current_row = 0;
+
packet_list_thaw();
cf_callback_invoke(cf_cb_file_read_finished, cf);
errmsg = errmsg_errno;
break;
}
- g_snprintf(err_str, sizeof err_str, errmsg);
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, err_str);
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", errmsg);
return CF_READ_ERROR;
} else
return CF_READ_OK;
/* This frame either passed the display filter list or is marked as
a time reference frame. All time reference frames are displayed
even if they dont pass the display filter */
- /* if this was a TIME REF frame we should reset the cul bytes field */
if(edt->pi.fd->flags.ref_time){
+ /* if this was a TIME REF frame we should reset the cul bytes field */
cum_bytes = fdata->pkt_len;
- fdata->cum_bytes = cum_bytes;
+ fdata->cum_bytes = cum_bytes;
+ } else {
+ /* increase cum_bytes with this packets length */
+ cum_bytes += fdata->pkt_len;
}
- /* increase cum_bytes with this packets length */
- cum_bytes += fdata->pkt_len;
-
epan_dissect_fill_in_columns(edt);
/* If we haven't yet seen the first frame, this is it.
fdata->col_expr.col_expr = cf->cinfo.col_expr.col_expr;
fdata->col_expr.col_expr_val = cf->cinfo.col_expr.col_expr_val;
-
+
row = packet_list_append(cf->cinfo.col_data, fdata);
/* colorize packet: first apply color filters
cf->count++;
cf->f_datalen = offset + phdr->caplen;
fdata->num = cf->count;
- row = add_packet_to_packet_list(fdata, cf, dfcode, pseudo_header, buf, TRUE);
+ if (!cf->redissecting) {
+ row = add_packet_to_packet_list(fdata, cf, dfcode, pseudo_header, buf, TRUE);
+ }
} else {
/* XXX - if we didn't have read filters, or if we could avoid
allocating the "frame_data" structure until we knew whether
int err_fileno;
int i;
char errmsg_errno[1024+1];
- gchar err_str[2048+1];
const char *errmsg;
gboolean got_read_error = FALSE, got_write_error = FALSE;
gint64 data_offset;
if (*out_filenamep != NULL) {
out_filename = *out_filenamep;
- out_fd = eth_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
+ out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
if (out_fd == -1)
open_err = errno;
} else {
merge_max_snapshot_length(in_file_count, in_files),
FALSE /* compressed */, &open_err);
if (pdh == NULL) {
- eth_close(out_fd);
+ ws_close(out_fd);
merge_close_in_files(in_file_count, in_files);
g_free(in_files);
cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
errmsg = errmsg_errno;
break;
}
- g_snprintf(err_str, sizeof err_str, errmsg, in_files[i].filename);
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, err_str);
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, errmsg, in_files[i].filename);
}
}
}
have to. */
return CF_ERROR;
} else
- return CF_READ_OK;
+ return CF_OK;
}
cf_status_t
which might cause the state information to be constructed differently
by that dissector. */
+ /* We might receive new packets while redissecting, and we don't
+ want to dissect those before their time. */
+ cf->redissecting = TRUE;
+
/* Initialize all data structures used for dissection. */
init_dissection();
}
prev_frame = fdata;
}
+ /* We are done redissecting the packet list. */
+ cf->redissecting = FALSE;
+
/* Re-sort the list using the previously selected order */
packet_list_set_sort_column();
/* Either the frame that was selected passed the filter, or we've
found the nearest displayed frame to that frame. Select it, make
it the focus row, and make it visible. */
+ if (selected_row == 0) {
+ /* Set to invalid to force update of packet list and packet details */
+ cf->current_row = -1;
+ }
packet_list_set_selected_row(selected_row);
}
do_columns ? &cf->cinfo : NULL)) {
case PSP_FINISHED:
/* Completed successfully. */
- return CF_OK;
+ return CF_READ_OK;
case PSP_STOPPED:
/* Well, the user decided to abort the refiltering.
FILE *fh;
psp_return_t ret;
- fh = eth_fopen(print_args->file, "w");
+ fh = ws_fopen(print_args->file, "w");
if (fh == NULL)
return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
{
FILE *fh = argsp;
epan_dissect_t *edt;
+ gboolean proto_tree_needed;
- /* Fill in the column information, but don't create the protocol tree. */
- edt = epan_dissect_new(FALSE, FALSE);
+ /* Fill in the column information, only create the protocol tree
+ if having custom columns. */
+ proto_tree_needed = have_custom_cols(&cf->cinfo);
+ edt = epan_dissect_new(proto_tree_needed, proto_tree_needed);
epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
epan_dissect_fill_in_columns(edt);
FILE *fh;
psp_return_t ret;
- fh = eth_fopen(print_args->file, "w");
+ fh = ws_fopen(print_args->file, "w");
if (fh == NULL)
return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
{
FILE *fh = argsp;
epan_dissect_t *edt;
+ gboolean proto_tree_needed;
- /* Fill in the column information, but don't create the protocol tree. */
- edt = epan_dissect_new(FALSE, FALSE);
+ /* Fill in the column information, only create the protocol tree
+ if having custom columns. */
+ proto_tree_needed = have_custom_cols(&cf->cinfo);
+ edt = epan_dissect_new(proto_tree_needed, proto_tree_needed);
epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
epan_dissect_fill_in_columns(edt);
FILE *fh;
psp_return_t ret;
- fh = eth_fopen(print_args->file, "w");
+ fh = ws_fopen(print_args->file, "w");
if (fh == NULL)
return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
static gboolean
write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
- union wtap_pseudo_header *pseudo_header _U_,
+ union wtap_pseudo_header *pseudo_header _U_,
const guint8 *pd, void *argsp)
{
FILE *fh = argsp;
FILE *fh;
psp_return_t ret;
- fh = eth_fopen(print_args->file, "w");
+ fh = ws_fopen(print_args->file, "w");
if (fh == NULL)
return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
/* Iterate through the list of packets, printing the packets we were
told to print. */
- ret = process_specified_packets(cf, &print_args->range,
+ ret = process_specified_packets(cf, &print_args->range,
"Writing C Arrays",
"selected packets", TRUE,
write_carrays_packet, fh);
gchar status_str[100];
int progbar_nextstep;
int progbar_quantum;
- int first, last;
gboolean sorted_by_frame_column;
XXX - we have to force the "column is writable" flag on, as it
might be off from the last frame that was dissected. */
col_set_writable(&cf->cinfo, TRUE);
- if (!check_col(&cf->cinfo, COL_CLS_TIME)) {
+ if (!check_col(&cf->cinfo, COL_CLS_TIME) &&
+ !check_col(&cf->cinfo, COL_ABS_TIME) &&
+ !check_col(&cf->cinfo, COL_ABS_DATE_TIME) &&
+ !check_col(&cf->cinfo, COL_REL_TIME) &&
+ !check_col(&cf->cinfo, COL_DELTA_TIME) &&
+ !check_col(&cf->cinfo, COL_DELTA_TIME_DIS)) {
/* No, there aren't any columns in that format, so we have no work
to do. */
return;
}
- first = cf->cinfo.col_first[COL_CLS_TIME];
- g_assert(first >= 0);
- last = cf->cinfo.col_last[COL_CLS_TIME];
/* Freeze the packet list while we redo it, so we don't get any
screen updates while it happens. */
if (row != -1) {
/* This packet is in the summary list, on row "row". */
- for (i = first; i <= last; i++) {
- if (cf->cinfo.fmt_matx[i][COL_CLS_TIME]) {
+ for (i = 0; i < cf->cinfo.num_cols; i++) {
+ if (col_has_time_fmt(&cf->cinfo, i)) {
/* This is one of the columns that shows the time in
"command-line-specified" format; update it. */
cf->cinfo.col_buf[i][0] = '\0';
- col_set_cls_time(fdata, &cf->cinfo, i);
+ col_set_fmt_time(fdata, &cf->cinfo, cf->cinfo.col_fmt[i], i);
packet_list_set_text(row, i, cf->cinfo.col_data[i]);
}
}
/* Set the column widths of those columns that show the time in
"command-line-specified" format. */
- for (i = first; i <= last; i++) {
- if (cf->cinfo.fmt_matx[i][COL_CLS_TIME]) {
- packet_list_set_cls_time_width(i);
+ for (i = 0; i < cf->cinfo.num_cols; i++) {
+ if (col_has_time_fmt(&cf->cinfo, i)) {
+ packet_list_set_time_width(cf->cinfo.col_fmt[i], i);
}
}
match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
{
cbs_t *info = criterion;
- const char *ascii_text = info->data;
+ const guint8 *ascii_text = info->data;
size_t textlen = info->data_len;
gboolean frame_matched;
guint32 buf_len;
match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
{
cbs_t *info = criterion;
- const char *ascii_text = info->data;
+ const guint8 *ascii_text = info->data;
size_t textlen = info->data_len;
gboolean frame_matched;
guint32 buf_len;
match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
{
cbs_t *info = criterion;
- const char *ascii_text = info->data;
+ const guint8 *ascii_text = info->data;
size_t textlen = info->data_len;
gboolean frame_matched;
guint32 buf_len;
/* Record that this frame is the current frame. */
cf->current_frame = fdata;
+ cf->current_row = row;
/* Create the logical protocol tree. */
if (cf->edt != NULL) {
/* No packet is selected. */
cf->current_frame = NULL;
+ cf->current_row = 0;
cf_callback_invoke(cf_cb_packet_unselected, cf);
capture, so it doesn't need to stay around under that name;
first, try renaming the capture buffer file to the new name. */
#ifndef _WIN32
- if (eth_rename(cf->filename, fname) == 0) {
+ if (ws_rename(cf->filename, fname) == 0) {
/* That succeeded - there's no need to copy the source file. */
from_filename = NULL;
do_copy = FALSE;
}
char *
-cf_read_error_message(int err, const gchar *err_info)
+cf_read_error_message(int err, gchar *err_info)
{
static char errmsg_errno[1024+1];
switch (err) {
case WTAP_ERR_UNSUPPORTED_ENCAP:
- g_snprintf(errmsg_errno, sizeof(errmsg_errno),
+ g_snprintf(errmsg_errno, sizeof(errmsg_errno),
"The file \"%%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
err_info);
- break;
+ g_free(err_info);
+ break;
case WTAP_ERR_BAD_RECORD:
g_snprintf(errmsg_errno, sizeof(errmsg_errno),
"An error occurred while reading from the file \"%%s\": %s.\n(%s)",
wtap_strerror(err), err_info);
+ g_free(err_info);
break;
default:
guint8 pd[65536];
/* Copy the raw bytes of the file. */
- from_fd = eth_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
+ from_fd = ws_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
if (from_fd < 0) {
open_failure_alert_box(from_filename, errno, FALSE);
goto done;
may open the file in text mode, not binary mode, but we want
to copy the raw bytes of the file, so we need the output file
to be open in binary mode. */
- to_fd = eth_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
+ to_fd = ws_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
if (to_fd < 0) {
open_failure_alert_box(to_filename, errno, TRUE);
- eth_close(from_fd);
+ ws_close(from_fd);
goto done;
}
- while ((nread = eth_read(from_fd, pd, sizeof pd)) > 0) {
- nwritten = eth_write(to_fd, pd, nread);
+ while ((nread = ws_read(from_fd, pd, sizeof pd)) > 0) {
+ nwritten = ws_write(to_fd, pd, nread);
if (nwritten < nread) {
if (nwritten < 0)
err = errno;
else
err = WTAP_ERR_SHORT_WRITE;
write_failure_alert_box(to_filename, err);
- eth_close(from_fd);
- eth_close(to_fd);
+ ws_close(from_fd);
+ ws_close(to_fd);
goto done;
}
}
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"An error occurred while reading from the file \"%s\": %s.",
from_filename, strerror(err));
- eth_close(from_fd);
- eth_close(to_fd);
+ ws_close(from_fd);
+ ws_close(to_fd);
goto done;
}
- eth_close(from_fd);
- if (eth_close(to_fd) < 0) {
+ ws_close(from_fd);
+ if (ws_close(to_fd) < 0) {
write_failure_alert_box(to_filename, errno);
goto done;
}