#include <epan/addr_resolv.h>
#include "ui/util.h"
#include "clopts_common.h"
-#include "console_io.h"
#include "cmdarg_err.h"
#include "version_info.h"
#include <epan/plugins.h>
static int load_cap_file(capture_file *, char *, int, gboolean, int, gint64);
static gboolean process_packet(capture_file *cf, gint64 offset,
- struct wtap_pkthdr *whdr,
- const guchar *pd, gboolean filtering_tap_listeners, guint tap_flags);
+ struct wtap_pkthdr *whdr, const guchar *pd,
+ gboolean filtering_tap_listeners, guint tap_flags);
static void show_capture_file_io_error(const char *, int, gboolean);
static void show_print_file_io_error(int err);
static gboolean write_preamble(capture_file *cf);
struct string_elem *captypes;
GSList *list = NULL;
- captypes = g_malloc(sizeof(struct string_elem) * WTAP_NUM_FILE_TYPES);
+ captypes = g_new(struct string_elem, WTAP_NUM_FILE_TYPES);
fprintf(stderr, "tshark: The available capture file types for the \"-F\" flag are:\n");
for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
fprintf(output, " -I capture in monitor mode, if available\n");
#endif
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
- fprintf(output, " -B <buffer size> size of kernel buffer (def: 1MB)\n");
+ fprintf(output, " -B <buffer size> size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
#endif
fprintf(output, " -y <link type> link layer type (def: first appropriate)\n");
fprintf(output, " -D print list of interfaces and exit\n");
fprintf(output, "\n");
fprintf(output, "Processing:\n");
fprintf(output, " -2 perform a two-pass analysis\n");
- fprintf(output, " -R <read filter> packet filter in Wireshark display filter syntax\n");
+ fprintf(output, " -R <read filter> packet Read filter in Wireshark display filter syntax\n");
+ fprintf(output, " -Y <display filter> packet displaY filter in Wireshark display filter syntax\n");
fprintf(output, " -n disable all name resolutions (def: all enabled)\n");
fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mntC\"\n");
fprintf(output, " -d %s ...\n", decode_as_arg_template);
fprintf(output, "Usage: tshark -G [report]\n");
fprintf(output, "\n");
fprintf(output, "Glossary table reports:\n");
- fprintf(output, " -G [fields] dump glossary in original format and exit\n");
- fprintf(output, " -G fields2 dump glossary in format 2 and exit\n");
- fprintf(output, " -G fields3 dump glossary in format 3 and exit\n");
+ fprintf(output, " -G fields dump fields glossary and exit\n");
fprintf(output, " -G protocols dump protocols in registration database and exit\n");
fprintf(output, " -G values dump value, range, true/false strings and exit\n");
fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
fprintf(output, " -G defaultprefs dump default preferences and exit\n");
fprintf(output, " -G currentprefs dump current preferences and exit\n");
fprintf(output, "\n");
-
}
/*
volatile gboolean out_file_name_res = FALSE;
gchar *volatile cf_name = NULL;
gchar *rfilter = NULL;
+ gchar *dfilter = NULL;
#ifdef HAVE_PCAP_OPEN_DEAD
struct bpf_program fcode;
#endif
dfilter_t *rfcode = NULL;
+ dfilter_t *dfcode = NULL;
e_prefs *prefs_p;
char badopt;
- GLogLevelFlags log_flags;
+ int log_flags;
int optind_initial;
gchar *output_only = NULL;
#define OPTSTRING_I ""
#endif
-#define OPTSTRING "2a:" OPTSTRING_A "b:" OPTSTRING_B "c:C:d:De:E:f:F:gG:hH:i:" OPTSTRING_I "K:lLnN:o:O:pPqQr:R:s:S:t:T:u:vVw:W:xX:y:z:"
+#define OPTSTRING "2a:" OPTSTRING_A "b:" OPTSTRING_B "c:C:d:De:E:f:F:gG:hH:i:" OPTSTRING_I "K:lLnN:o:O:pPqQr:R:s:S:t:T:u:vVw:W:xX:y:Y:z:"
static const char optstring[] = OPTSTRING;
G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
g_log_set_handler(NULL,
- log_flags,
+ (GLogLevelFlags)log_flags,
tshark_log_handler, NULL /* user_data */);
g_log_set_handler(LOG_DOMAIN_MAIN,
- log_flags,
+ (GLogLevelFlags)log_flags,
tshark_log_handler, NULL /* user_data */);
#ifdef HAVE_LIBPCAP
g_log_set_handler(LOG_DOMAIN_CAPTURE,
- log_flags,
+ (GLogLevelFlags)log_flags,
tshark_log_handler, NULL /* user_data */);
g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
- log_flags,
+ (GLogLevelFlags)log_flags,
tshark_log_handler, NULL /* user_data */);
#endif
proto_initialize_all_prefixes();
if (argc == 2)
- proto_registrar_dump_fields(1);
+ proto_registrar_dump_fields();
else {
if (strcmp(argv[2], "fields") == 0)
- proto_registrar_dump_fields(1);
- else if (strcmp(argv[2], "fields2") == 0)
- proto_registrar_dump_fields(2);
- else if (strcmp(argv[2], "fields3") == 0)
- proto_registrar_dump_fields(3);
+ proto_registrar_dump_fields();
else if (strcmp(argv[2], "protocols") == 0)
proto_registrar_dump_protocols();
else if (strcmp(argv[2], "values") == 0)
break;
case 'X':
break;
+ case 'Y':
+ dfilter = optarg;
+ break;
case 'z':
/* We won't call the init function for the stat this soon
as it would disallow MATE's fields (which are registered
part of a tap filter. Instead, we just add the argument
to a list of stat arguments. */
if (!process_stat_cmd_arg(optarg)) {
+ if (strcmp("help", optarg)==0) {
+ fprintf(stderr, "tshark: The available statistics for the \"-z\" option are:\n");
+ list_stat_cmd_args();
+ return 0;
+ }
cmdarg_err("Invalid -z argument \"%s\".", optarg);
cmdarg_err_cont(" -z argument must be one of :");
list_stat_cmd_args();
return 1;
}
- /* If no capture filter or read filter has been specified, and there are
+ /* If no capture filter or display filter has been specified, and there are
still command-line arguments, treat them as the tokens of a capture
- filter (if no "-r" flag was specified) or a read filter (if a "-r"
+ filter (if no "-r" flag was specified) or a display filter (if a "-r"
flag was specified. */
if (optind < argc) {
if (cf_name != NULL) {
- if (rfilter != NULL) {
- cmdarg_err("Read filters were specified both with \"-R\" "
+ if (dfilter != NULL) {
+ cmdarg_err("Display filters were specified both with \"-d\" "
"and with additional command-line arguments.");
return 1;
}
- rfilter = get_args_as_string(argc, argv, optind);
+ dfilter = get_args_as_string(argc, argv, optind);
} else {
#ifdef HAVE_LIBPCAP
guint i;
}
}
+ if (rfilter != NULL && !perform_two_pass_analysis) {
+ /* Just a warning, so we don't return */
+ cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
+ }
+
#ifdef HAVE_LIBPCAP
if (list_link_layer_types) {
/* We're supposed to list the link-layer types for an interface;
return 1;
}
}
- /* Currently, we don't support read filters when capturing
+ /* Currently, we don't support read or display filters when capturing
and saving the packets. */
if (rfilter != NULL) {
cmdarg_err("Read filters aren't supported when capturing and saving the captured packets.");
return 1;
}
+ if (dfilter != NULL) {
+ cmdarg_err("Display filters aren't supported when capturing and saving the captured packets.");
+ return 1;
+ }
} else {
/* 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
if (pc != NULL) {
if (pcap_compile(pc, &fcode, rfilter, 0, 0) != -1) {
cmdarg_err_cont(
- " Note: That display filter code looks like a valid capture filter;");
+ " Note: That read filter code looks like a valid capture filter;");
cmdarg_err_cont(
" maybe you mixed them up?");
}
}
cfile.rfcode = rfcode;
+ if (dfilter != NULL) {
+ if (!dfilter_compile(dfilter, &dfcode)) {
+ cmdarg_err("%s", dfilter_error_msg);
+ epan_cleanup();
+#ifdef HAVE_PCAP_OPEN_DEAD
+ {
+ pcap_t *pc;
+
+ pc = pcap_open_dead(DLT_EN10MB, MIN_PACKET_SIZE);
+ if (pc != NULL) {
+ if (pcap_compile(pc, &fcode, dfilter, 0, 0) != -1) {
+ cmdarg_err_cont(
+ " Note: That display filter code looks like a valid capture filter;");
+ cmdarg_err_cont(
+ " maybe you mixed them up?");
+ }
+ pcap_close(pc);
+ }
+ }
+#endif
+ return 2;
+ }
+ }
+ cfile.dfcode = dfcode;
+
if (print_packet_info) {
/* If we're printing as text or PostScript, we have
to create a print stream. */
we're using a read filter on the packets;
+ we're using a display filter on the packets;
+
we're using any taps that need dissection. */
- do_dissection = print_packet_info || rfcode || tap_listeners_require_dissection();
+ do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
if (cf_name) {
/*
/* if we are in real-time mode, open the new file now */
if (do_dissection) {
/* Attempt to open the capture file and set up to read from it. */
- switch(cf_open(capture_opts->cf, capture_opts->save_file, is_tempfile, &err)) {
+ switch(cf_open((capture_file *)capture_opts->cf, capture_opts->save_file, is_tempfile, &err)) {
case CF_OK:
break;
case CF_ERROR:
int err;
gchar *err_info;
gint64 data_offset;
- capture_file *cf = capture_opts->cf;
+ capture_file *cf = (capture_file *)capture_opts->cf;
gboolean filtering_tap_listeners;
guint tap_flags;
frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
/* If we're going to print packet information, or we're going to
- run a read filter, or we're going to process taps, set up to
+ run a read filter, or display filter, or we're going to process taps, set up to
do a dissection and do so. */
if (do_dissection) {
if (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
/* Grab any resolved addresses */
host_name_lookup_process();
- /* If we're going to be applying a read filter, we'll need to
+ /* If we're going to be applying a filter, we'll need to
create a protocol tree against which to apply the filter. */
if (cf->rfcode)
create_proto_tree = TRUE;
if (passed) {
frame_data_set_after_dissect(&fdlocal, &cum_bytes);
- prev_dis_frame = fdlocal;
- prev_dis = &prev_dis_frame;
- frame_data_sequence_add(cf->frames, &fdlocal);
+ prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
+
+ g_slist_foreach(edt.pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
+
cf->count++;
+ } else {
+ /* if we don't add it to the frame_data_sequence, clean it up right now
+ * to avoid leaks */
+ frame_data_destroy(&fdlocal);
+ /* TODO, bug #8160 */
+ /*
+ prev_cap_frame = fdlocal;
+ prev_cap = &prev_cap_frame;
+ */
}
- prev_cap_frame = fdlocal;
- prev_cap = &prev_cap_frame;
-
if (do_dissection)
epan_dissect_cleanup(&edt);
/* Grab any resolved addresses */
host_name_lookup_process();
- if (cf->rfcode || print_details || filtering_tap_listeners ||
+ if (cf->dfcode || print_details || filtering_tap_listeners ||
(tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo))
create_proto_tree = TRUE;
else
("packet_details" is true). */
epan_dissect_init(&edt, create_proto_tree, print_packet_info && print_details);
- /* If we're running a read filter, prime the epan_dissect_t with that
+ /* If we're running a display filter, prime the epan_dissect_t with that
filter. */
- if (cf->rfcode)
- epan_dissect_prime_dfilter(&edt, cf->rfcode);
+ if (cf->dfcode)
+ epan_dissect_prime_dfilter(&edt, cf->dfcode);
col_custom_prime_edt(&edt, &cf->cinfo);
epan_dissect_run_with_taps(&edt, phdr, pd, fdata, cinfo);
- /* Run the read filter if we have one. */
- if (cf->rfcode)
- passed = dfilter_apply_edt(cf->rfcode, &edt);
+ /* Run the read/display filter if we have one. */
+ if (cf->dfcode)
+ passed = dfilter_apply_edt(cf->dfcode, &edt);
}
if (passed) {
if (do_dissection) {
epan_dissect_cleanup(&edt);
}
- return passed;
+ return passed || fdata->flags.dependent_of_displayed;
}
static int
filter, so, if we're writing to a capture file, write
this packet out. */
if (pdh != NULL) {
- if (!wtap_dump(pdh, &cf->phdr, wtap_buf_ptr(cf->wth), &err)) {
+ if (!wtap_dump(pdh, &cf->phdr, cf->pd, &err)) {
/* Error writing to a capture file */
switch (err) {
/* Grab any resolved addresses */
host_name_lookup_process();
- if (cf->rfcode || print_details || filtering_tap_listeners ||
+ if (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
(tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo))
create_proto_tree = TRUE;
else
("packet_details" is true). */
epan_dissect_init(&edt, create_proto_tree, print_packet_info && print_details);
- /* If we're running a read filter, prime the epan_dissect_t with that
+ /* If we're running a filter, prime the epan_dissect_t with that
filter. */
if (cf->rfcode)
epan_dissect_prime_dfilter(&edt, cf->rfcode);
+ if (cf->dfcode)
+ epan_dissect_prime_dfilter(&edt, cf->dfcode);
col_custom_prime_edt(&edt, &cf->cinfo);
epan_dissect_run_with_taps(&edt, whdr, pd, &fdata, cinfo);
- /* Run the read filter if we have one. */
+ /* Run the filters if we have them. */
if (cf->rfcode)
passed = dfilter_apply_edt(cf->rfcode, &edt);
+ if (passed && cf->dfcode)
+ passed = dfilter_apply_edt(cf->dfcode, &edt);
}
if (passed) {
frame_data_set_after_dissect(&fdata, &cum_bytes);
- prev_dis_frame = fdata;
- prev_dis = &prev_dis_frame;
/* Process this packet. */
if (print_packet_info) {
exit(2);
}
}
+
+ /* this must be set after print_packet() [bug #8160] */
+ prev_dis_frame = fdata;
+ prev_dis = &prev_dis_frame;
}
prev_cap_frame = fdata;
if (do_dissection) {
epan_dissect_cleanup(&edt);
- frame_data_cleanup(&fdata);
+ frame_data_destroy(&fdata);
}
return passed;
}
;
if (line_bufp == NULL) {
line_buf_len = new_line_buf_len;
- line_bufp = g_malloc(line_buf_len + 1);
+ line_bufp = (char *)g_malloc(line_buf_len + 1);
} else {
if (new_line_buf_len > line_buf_len) {
line_buf_len = new_line_buf_len;
- line_bufp = g_realloc(line_bufp, line_buf_len + 1);
+ line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
}
}
return line_bufp;
filename, g_strerror(err));
}
-/*
- * Print to the standard error. This is a command-line tool, so there's
- * no need to pop up a console.
- */
-void
-vfprintf_stderr(const char *fmt, va_list ap)
-{
- vfprintf(stderr, fmt, ap);
-}
-
-void
-fprintf_stderr(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf_stderr(fmt, ap);
- va_end(ap);
-}
-
/*
* Report an error in command-line arguments.
*/