#include <glib.h>
#include <epan/epan.h>
#include <epan/filesystem.h>
-#include <epan/privileges.h>
-#include <wiretap/file_util.h>
+#include <wsutil/privileges.h>
#include "globals.h"
#include <epan/timestamp.h>
#endif /* _WIN32 */
#include "capture_sync.h"
#endif /* HAVE_LIBPCAP */
-#include "epan/emem.h"
#include "log.h"
#include <epan/funnel.h>
static gboolean print_packet_counts;
-static capture_options capture_opts;
+static capture_options global_capture_opts;
#ifdef SIGINFO
static gboolean infodelay; /* if TRUE, don't print capture info in SIGINFO handler */
capture_file cfile;
+/*
+ * Mark a particular frame.
+ * Copied from file.c
+ */
+void
+cf_mark_frame(capture_file *cf, frame_data *frame)
+{
+ if (! frame->flags.marked) {
+ frame->flags.marked = TRUE;
+ if (cf->count > cf->marked_count)
+ cf->marked_count++;
+ }
+}
+
+/*
+ * Unmark a particular frame.
+ * Copied from file.c
+ */
+void
+cf_unmark_frame(capture_file *cf, frame_data *frame)
+{
+ if (frame->flags.marked) {
+ frame->flags.marked = FALSE;
+ if (cf->marked_count > 0)
+ cf->marked_count--;
+ }
+}
+
static void list_capture_types(void) {
int i;
fprintf(output, " -h display this help and exit\n");
fprintf(output, " -v display version info and exit\n");
fprintf(output, " -o <name>:<value> ... override preference setting\n");
+ fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
}
/*
ftenum_t dissector_table_selector_type;
struct protocol_name_search user_protocol_name;
-/* The following code will allocate and copy the command-line options in a string pointed by decoded_param */
+ /* The following code will allocate and copy the command-line options in a string pointed by decoded_param */
g_assert(cl_param);
- decoded_param = g_malloc( sizeof(gchar) * (strlen(cl_param) + 1) ); /* Allocate enough space to have a working copy of the command-line parameter */
+ decoded_param = g_strdup(cl_param);
g_assert(decoded_param);
- strcpy(decoded_param, cl_param);
/* The lines below will parse this string (modifying it) to extract all
GLogLevelFlags log_flags;
int optind_initial;
-#define OPTSTRING_INIT "a:b:c:C:d:De:E:f:F:G:hi:lLnN:o:pqr:R:s:St:T:vVw:xX:y:z:"
+#define OPTSTRING_INIT "a:b:c:C:d:De:E:f:F:G:hi:K:lLnN:o:pqr:R:s:St:T:vVw:xX:y:z:"
#ifdef HAVE_LIBPCAP
#ifdef _WIN32
#define OPTSTRING_WIN32 "B:"
initialize_funnel_ops();
#ifdef HAVE_LIBPCAP
- capture_opts_init(&capture_opts, NULL /* cfile */);
+ capture_opts_init(&global_capture_opts, NULL /* cfile */);
#endif
timestamp_set_type(TS_RELATIVE);
If none of our build or other processes uses "-G" with no arguments,
we can just process it with the other arguments. */
if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
+ proto_initialize_all_prefixes();
+
if (argc == 2)
proto_registrar_dump_fields(1);
else {
case 'B': /* Buffer size */
#endif /* _WIN32 */
#ifdef HAVE_LIBPCAP
- status = capture_opts_add_opt(&capture_opts, opt, optarg, &start_capture);
+ status = capture_opts_add_opt(&global_capture_opts, opt, optarg, &start_capture);
if(status != 0) {
exit(status);
}
if (!add_decode_as(optarg))
exit(1);
break;
+#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
+ case 'K': /* Kerberos keytab file */
+ read_keytab_file(optarg);
+ break;
+#endif
case 'D': /* Print a list of capture devices and exit */
#ifdef HAVE_LIBPCAP
status = capture_opts_list_interfaces(FALSE);
rfilter = get_args_as_string(argc, argv, optind);
} else {
#ifdef HAVE_LIBPCAP
- if (capture_opts.has_cfilter) {
+ if (global_capture_opts.has_cfilter) {
cmdarg_err("Capture filters were specified both with \"-f\""
" and with additional command-line arguments");
exit(1);
}
- capture_opts.has_cfilter = TRUE;
- capture_opts.cfilter = get_args_as_string(argc, argv, optind);
+ global_capture_opts.has_cfilter = TRUE;
+ global_capture_opts.cfilter = get_args_as_string(argc, argv, optind);
#else
capture_option_specified = TRUE;
#endif
}
#ifdef HAVE_LIBPCAP
- if (!capture_opts.saving_to_file) {
+ if (!global_capture_opts.saving_to_file) {
/* We're not saving the capture to a file; if "-q" wasn't specified,
we should print packet information */
if (!quiet)
output, reject the request. At best, we could redirect that
to the standard error; we *can't* write both to the standard
output and have either of them be useful. */
- if (strcmp(capture_opts.save_file, "-") == 0 && print_packet_info) {
+ if (strcmp(global_capture_opts.save_file, "-") == 0 && print_packet_info) {
cmdarg_err("You can't write both raw packet data and dissected packets"
" to the standard output.");
exit(1);
support in capture files we read). */
#ifdef HAVE_LIBPCAP
if (cf_name != NULL) {
- if (capture_opts.has_cfilter) {
+ if (global_capture_opts.has_cfilter) {
cmdarg_err("Only read filters, not capture filters, "
"can be specified when reading a capture file.");
exit(1);
exit(1);
}
/* No - did they specify a ring buffer option? */
- if (capture_opts.multi_files_on) {
+ if (global_capture_opts.multi_files_on) {
cmdarg_err("Ring buffer requested, but a capture isn't being done.");
exit(1);
}
* "-r" was specified, so we're reading a capture file.
* Capture options don't apply here.
*/
- if (capture_opts.multi_files_on) {
+ if (global_capture_opts.multi_files_on) {
cmdarg_err("Multiple capture files requested, but "
"a capture isn't being done.");
exit(1);
}
- if (capture_opts.has_file_duration) {
+ if (global_capture_opts.has_file_duration) {
cmdarg_err("Switching capture files after a time interval was specified, but "
"a capture isn't being done.");
exit(1);
}
- if (capture_opts.has_ring_num_files) {
+ if (global_capture_opts.has_ring_num_files) {
cmdarg_err("A ring buffer of capture files was specified, but "
"a capture isn't being done.");
exit(1);
}
- if (capture_opts.has_autostop_files) {
+ if (global_capture_opts.has_autostop_files) {
cmdarg_err("A maximum number of capture files was specified, but "
"a capture isn't being done.");
exit(1);
* and byte count as well as a write file. Other autostop options remain valid
* only for a write file.
*/
- if (capture_opts.has_autostop_duration) {
+ if (global_capture_opts.has_autostop_duration) {
cmdarg_err("A maximum capture time was specified, but "
"a capture isn't being done.");
exit(1);
/*
* "-r" wasn't specified, so we're doing a live capture.
*/
- if (capture_opts.saving_to_file) {
+ if (global_capture_opts.saving_to_file) {
/* They specified a "-w" flag, so we'll be saving to a capture file. */
/* When capturing, we only support writing libpcap format. */
cmdarg_err("Live captures can only be saved in libpcap format.");
exit(1);
}
- if (capture_opts.multi_files_on) {
+ if (global_capture_opts.multi_files_on) {
/* Multiple-file mode doesn't work under certain conditions:
a) it doesn't work if you're writing to the standard output;
b) it doesn't work if you're writing to a pipe;
*/
- if (strcmp(capture_opts.save_file, "-") == 0) {
+ if (strcmp(global_capture_opts.save_file, "-") == 0) {
cmdarg_err("Multiple capture files requested, but "
"the capture is being written to the standard output.");
exit(1);
}
- if (capture_opts.output_to_pipe) {
+ if (global_capture_opts.output_to_pipe) {
cmdarg_err("Multiple capture files requested, but "
"the capture file is a pipe.");
exit(1);
}
- if (!capture_opts.has_autostop_filesize &&
- !capture_opts.has_file_duration) {
+ if (!global_capture_opts.has_autostop_filesize &&
+ !global_capture_opts.has_file_duration) {
cmdarg_err("Multiple capture files requested, but "
"no maximum capture file size or duration was specified.");
exit(1);
/* They didn't specify a "-w" flag, so we won't be saving to a
capture file. Check for options that only make sense if
we're saving to a file. */
- if (capture_opts.has_autostop_filesize) {
+ if (global_capture_opts.has_autostop_filesize) {
cmdarg_err("Maximum capture file size specified, but "
"capture isn't being saved to a file.");
exit(1);
}
- if (capture_opts.multi_files_on) {
+ if (global_capture_opts.multi_files_on) {
cmdarg_err("Multiple capture files requested, but "
"the capture isn't being saved to a file.");
exit(1);
for (i = 0; i < cfile.cinfo.num_cols; i++) {
cfile.cinfo.col_fmt[i] = get_column_format(i);
cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
+ if (cfile.cinfo.col_fmt[i] == COL_CUSTOM) {
+ cfile.cinfo.col_custom_field[i] = g_strdup(get_column_custom_field(i));
+ } else {
+ cfile.cinfo.col_custom_field[i] = NULL;
+ }
cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
NUM_COL_FMTS);
get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
else
cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
cfile.cinfo.col_fence[i] = 0;
- cfile.cinfo.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
- cfile.cinfo.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
+ cfile.cinfo.col_expr.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
+ cfile.cinfo.col_expr.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
}
for (i = 0; i < cfile.cinfo.num_cols; i++) {
}
#ifdef HAVE_LIBPCAP
- capture_opts_trim_snaplen(&capture_opts, MIN_PACKET_SIZE);
- capture_opts_trim_ring_num_files(&capture_opts);
+ capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
+ capture_opts_trim_ring_num_files(&global_capture_opts);
#endif
if (rfilter != NULL) {
/* Process the packets in the file */
#ifdef HAVE_LIBPCAP
- err = load_cap_file(&cfile, capture_opts.save_file, out_file_type,
- capture_opts.has_autostop_packets ? capture_opts.autostop_packets : 0,
- capture_opts.has_autostop_filesize ? capture_opts.autostop_filesize : 0);
+ err = load_cap_file(&cfile, global_capture_opts.save_file, out_file_type,
+ global_capture_opts.has_autostop_packets ? global_capture_opts.autostop_packets : 0,
+ global_capture_opts.has_autostop_filesize ? global_capture_opts.autostop_filesize : 0);
#else
err = load_cap_file(&cfile, NULL, out_file_type, 0, 0);
#endif
#endif
/* trim the interface name and exit if that failed */
- if (!capture_opts_trim_iface(&capture_opts,
+ if (!capture_opts_trim_iface(&global_capture_opts,
(prefs->capture_device) ? get_if_name(prefs->capture_device) : NULL)) {
exit(2);
}
/* if requested, list the link layer types and exit */
if (list_link_layer_types) {
- status = capture_opts_list_link_layer_types(&capture_opts, FALSE);
+ status = capture_opts_list_link_layer_types(&global_capture_opts, FALSE);
exit(status);
}
#endif /* SIGINFO */
#endif /* _WIN32 */
- capture_opts.state = CAPTURE_PREPARING;
+ global_capture_opts.state = CAPTURE_PREPARING;
/* Let the user know what interface was chosen. */
- capture_opts.iface_descr = get_interface_descriptive_name(capture_opts.iface);
- fprintf(stderr, "Capturing on %s\n", capture_opts.iface_descr);
+ global_capture_opts.iface_descr = get_interface_descriptive_name(global_capture_opts.iface);
+ fprintf(stderr, "Capturing on %s\n", global_capture_opts.iface_descr);
- ret = sync_pipe_start(&capture_opts);
+ ret = sync_pipe_start(&global_capture_opts);
if (!ret)
return FALSE;
{
}
-/* XXX - move the call to simple_dialog() out of capture_sync.c */
-#include "simple_dialog.h"
-
-/* capture_sync.c want's to tell us an error */
-gpointer simple_dialog(ESD_TYPE_E type _U_, gint btn_mask _U_,
- const gchar *msg_format, ...)
-{
- va_list ap;
-
- /* XXX - do we need to display buttons and alike? */
- va_start(ap, msg_format);
- fprintf(stderr, "tshark: ");
- vfprintf(stderr, msg_format, ap);
- fprintf(stderr, "\n");
- va_end(ap);
-
- return NULL;
-}
-
-
/* capture child detected an error */
void
capture_input_error_message(capture_options *capture_opts _U_, char *error_msg, char *secondary_error_msg)
g_free(capture_opts->save_file);
capture_opts->save_file = NULL;
return FALSE;
- break;
}
}
/* capture child detected any packet drops? */
void
-capture_input_drops(capture_options *capture_opts _U_, int dropped)
+capture_input_drops(capture_options *capture_opts _U_, guint32 dropped)
{
- if (print_packet_counts) {
- /* We're printing packet counts to stderr.
- Send a newline so that we move to the line after the packet count. */
- fprintf(stderr, "\n");
- }
-
- if(dropped != 0) {
- /* We're printing packet counts to stderr.
- Send a newline so that we move to the line after the packet count. */
- fprintf(stderr, "%u packet%s dropped\n", dropped, plurality(dropped, "", "s"));
- }
+ if (print_packet_counts) {
+ /* We're printing packet counts to stderr.
+ Send a newline so that we move to the line after the packet count. */
+ fprintf(stderr, "\n");
+ }
+
+ if (dropped != 0) {
+ /* We're printing packet counts to stderr.
+ Send a newline so that we move to the line after the packet count. */
+ fprintf(stderr, "%u packet%s dropped\n", dropped, plurality(dropped, "", "s"));
+ }
}
building it with Cygwin may make the problem go away). */
/* tell the capture child to stop */
- sync_pipe_stop(&capture_opts);
+ sync_pipe_stop(&global_capture_opts);
/* don't stop our own loop already here, otherwise status messages and
* cleanup wouldn't be done properly. The child will indicate the stop of
capture_cleanup(int signum _U_)
{
/* tell the capture child to stop */
- sync_pipe_stop(&capture_opts);
+ sync_pipe_stop(&global_capture_opts);
}
#endif /* _WIN32 */
#endif /* HAVE_LIBPCAP */
}
}
/* Stop reading if we have the maximum number of packets;
- * note that a zero max_packet_count will never be matched
- * (unless we roll over the packet number?)
+ * When the -c option has not been used, max_packet_count
+ * starts at 0, which practically means, never stop reading.
+ * (unless we roll over max_packet_count ?)
*/
- if(max_packet_count == cf->count || (max_byte_count != 0 && data_offset >= max_byte_count)) {
+ if( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
err = 0; /* This is not an error */
break;
}
case WTAP_ERR_UNSUPPORTED_ENCAP:
cmdarg_err("\"%s\" has a packet with a network type that TShark doesn't support.\n(%s)",
cf->filename, err_info);
+ g_free(err_info);
break;
case WTAP_ERR_CANT_READ:
case WTAP_ERR_BAD_RECORD:
cmdarg_err("\"%s\" appears to be damaged or corrupt.\n(%s)",
cf->filename, err_info);
+ g_free(err_info);
break;
default:
cf->elapsed_time = fdata->rel_ts;
}
+ /* If we don't have the time stamp of the previous displayed packet,
+ it's because this is the first packet that's being displayed. Save the time
+ stamp of this packet as the time stamp of the previous displayed
+ packet. */
+ if (nstime_is_unset(&prev_dis_ts))
+ prev_dis_ts = fdata->abs_ts;
+
/* Get the time elapsed between the previous displayed packet and
this packet. */
- if (nstime_is_unset(&prev_dis_ts))
- nstime_set_zero(&fdata->del_dis_ts);
- else
- nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
+ nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
/* Get the time elapsed between the previous captured packet and
this packet. */
}
passed = TRUE;
- if (cf->rfcode || verbose || num_tap_filters!=0)
+ if (cf->rfcode || verbose || num_tap_filters!=0 || have_custom_cols(&cf->cinfo))
create_proto_tree = TRUE;
else
create_proto_tree = FALSE;
if (cf->rfcode)
epan_dissect_prime_dfilter(edt, cf->rfcode);
+ col_custom_prime_edt(edt, &cf->cinfo);
+
tap_queue_init(edt);
/* We only need the columns if we're printing packet info but we're
* the same time, sort of like an "Update list of packets
* in real time" capture in Wireshark.)
*/
- if (capture_opts.iface != NULL)
+ if (global_capture_opts.iface != NULL)
continue;
#endif
column_len = strlen(cf->cinfo.col_data[i]);
va_list ap;
va_start(ap, fmt);
- fprintf(stderr, "tshark: ");
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
+ failure_message(fmt, ap);
va_end(ap);
}
fprintf(stderr, "\n");
va_end(ap);
}
-
-