|
|
|
/* tshark.c
|
|
|
|
*
|
|
|
|
* Text-mode variant of Wireshark, along the lines of tcpdump and snoop,
|
|
|
|
* by Gilbert Ramirez <gram@alumni.rice.edu> and Guy Harris <guy@alum.mit.edu>.
|
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#define WS_LOG_DOMAIN LOG_DOMAIN_MAIN
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <locale.h>
|
|
|
|
#include <limits.h>
|
|
|
|
|
|
|
|
#include <wsutil/ws_getopt.h>
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
# include <winsock2.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
|
|
|
#include <signal.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
|
|
|
#include <epan/exceptions.h>
|
|
|
|
#include <epan/epan.h>
|
|
|
|
|
|
|
|
#include <ws_exit_codes.h>
|
|
|
|
#include <wsutil/clopts_common.h>
|
|
|
|
#include <wsutil/cmdarg_err.h>
|
|
|
|
#include <ui/urls.h>
|
|
|
|
#include <wsutil/filesystem.h>
|
|
|
|
#include <wsutil/file_util.h>
|
|
|
|
#include <wsutil/socket.h>
|
|
|
|
#include <wsutil/privileges.h>
|
|
|
|
#include <wsutil/report_message.h>
|
|
|
|
#include <wsutil/please_report_bug.h>
|
|
|
|
#include <wsutil/wslog.h>
|
|
|
|
#include <wsutil/ws_assert.h>
|
|
|
|
#include <wsutil/strtoi.h>
|
|
|
|
#include <cli_main.h>
|
|
|
|
#include <wsutil/version_info.h>
|
|
|
|
#include <wiretap/wtap_opttypes.h>
|
|
|
|
|
|
|
|
#include "globals.h"
|
|
|
|
#include <epan/timestamp.h>
|
|
|
|
#include <epan/packet.h>
|
|
|
|
#ifdef HAVE_LUA
|
|
|
|
#include <epan/wslua/init_wslua.h>
|
|
|
|
#endif
|
|
|
|
#include "frame_tvbuff.h"
|
|
|
|
#include <epan/disabled_protos.h>
|
|
|
|
#include <epan/prefs.h>
|
|
|
|
#include <epan/column.h>
|
|
|
|
#include <epan/decode_as.h>
|
|
|
|
#include <epan/print.h>
|
|
|
|
#include <epan/addr_resolv.h>
|
|
|
|
#ifdef HAVE_LIBPCAP
|
|
|
|
#include "ui/capture_ui_utils.h"
|
|
|
|
#endif
|
|
|
|
#include "ui/taps.h"
|
|
|
|
#include "ui/util.h"
|
|
|
|
#include "ui/ws_ui_util.h"
|
|
|
|
#include "ui/decode_as_utils.h"
|
|
|
|
#include "wsutil/filter_files.h"
|
|
|
|
#include "ui/cli/tshark-tap.h"
|
|
|
|
#include "ui/cli/tap-exportobject.h"
|
|
|
|
#include "ui/tap_export_pdu.h"
|
|
|
|
#include "ui/dissect_opts.h"
|
|
|
|
#include "ui/ssl_key_export.h"
|
|
|
|
#include "ui/failure_message.h"
|
|
|
|
#if defined(HAVE_LIBSMI)
|
|
|
|
#include "epan/oids.h"
|
|
|
|
#endif
|
|
|
|
#include "epan/maxmind_db.h"
|
|
|
|
#include <epan/epan_dissect.h>
|
|
|
|
#include <epan/tap.h>
|
|
|
|
#include <epan/stat_tap_ui.h>
|
|
|
|
#include <epan/conversation_table.h>
|
Further refactor SRT stats.
Create "common" SRT tap data collection intended for all GUIs. Refactor/merge functionality of existing dissectors that have SRT support (AFP, DCERPC, Diameter, FC, GTP, LDAP, NCP, RPC, SCIS, SMB, and SMB2) for both TShark and GTK.
SMB and DCERPC "tap packet filtering" were different between TShark and GTK, so I went with GTK filter logic.
CAMEL "tap packet filtering" was different between TShark and GTK, so GTK filtering logic was pushed to the dissector and the TShark tap was left alone.
Change-Id: I7d6eaad0673fe628ef337f9165d7ed94f4a5e1cc
Reviewed-on: https://code.wireshark.org/review/8894
Petri-Dish: Michael Mann <mmann78@netscape.net>
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
8 years ago
|
|
|
#include <epan/srt_table.h>
|
|
|
|
#include <epan/rtd_table.h>
|
|
|
|
#include <epan/ex-opt.h>
|
|
|
|
#include <epan/exported_pdu.h>
|
|
|
|
#include <epan/secrets.h>
|
|
|
|
|
|
|
|
#include "capture_opts.h"
|
|
|
|
|
|
|
|
#include "capture/capture-pcap-util.h"
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBPCAP
|
|
|
|
#include "capture/capture_ifinfo.h"
|
|
|
|
#ifdef _WIN32
|
|
|
|
#include "capture/capture-wpcap.h"
|
|
|
|
#endif /* _WIN32 */
|
|
|
|
#include <capture/capture_session.h>
|
|
|
|
#include <capture/capture_sync.h>
|
|
|
|
#include <ui/capture_info.h>
|
|
|
|
#endif /* HAVE_LIBPCAP */
|
|
|
|
#include <epan/funnel.h>
|
|
|
|
|
|
|
|
#include <wsutil/str_util.h>
|
|
|
|
#include <wsutil/utf8_entities.h>
|
|
|
|
#include <wsutil/json_dumper.h>
|
|
|
|
#include <wsutil/wslog.h>
|
tshark: fix handling of "you're writing to a closed pipe" errors on Windows.
On Windows, a write to a pipe where the read side has been closed
apparently may return the Windows error ERROR_BROKEN_PIPE, which the
Visual Studio C library maps to EPIPE, or may return the Windows error
ERROR_NO_DATA, which the Visual Studio C library maps to EINVAL.
So, on Windows, for errors other than the ones for which we're reporting
a special error message, check for EINVAL with a *Windows* error of
ERROR_NO_DATA and, if that's what we have, don't print an error message;
otherwise, print an error message that reports a message based on the
Windows error (rather than a relatively uninformative "Invalid argument"
error).
This should fix issue #16192.
Clean up indentation while we're at it.
2 years ago
|
|
|
#ifdef _WIN32
|
|
|
|
#include <wsutil/win32-utils.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "extcap.h"
|
|
|
|
|
|
|
|
#ifdef HAVE_PLUGINS
|
|
|
|
#include <wsutil/codecs.h>
|
|
|
|
#include <wsutil/plugins.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Additional exit codes */
|
|
|
|
#define INVALID_EXPORT 2
|
|
|
|
#define INVALID_TAP 2
|
|
|
|
#define INVALID_CAPTURE 2
|
|
|
|
|
|
|
|
#define LONGOPT_EXPORT_OBJECTS LONGOPT_BASE_APPLICATION+1
|
|
|
|
#define LONGOPT_COLOR LONGOPT_BASE_APPLICATION+2
|
|
|
|
#define LONGOPT_NO_DUPLICATE_KEYS LONGOPT_BASE_APPLICATION+3
|
|
|
|
#define LONGOPT_ELASTIC_MAPPING_FILTER LONGOPT_BASE_APPLICATION+4
|
|
|
|
#define LONGOPT_EXPORT_TLS_SESSION_KEYS LONGOPT_BASE_APPLICATION+5
|
Clean up handling of --capture-comment.
Don't store the comments in a capture_options structure, because that's
available only if we're being built with capture support, and
--capture-comment can be used in TShark when reading a capture file and
writing another capture file, with no live capture taking place.
This means we don't handle that option in capture_opts_add_opt(); handle
it in the programs that support it.
Support writing multiple comments in dumpcap when capturing.
These changes also fix builds without pcap, and makes --capture-comment
work in Wireshark when a capture is started from the command line with
-k.
Update the help messages to indicate that --capture-comment adds a
capture comment, it doesn't change any comment (much less "the" comment,
as there isn't necessarily a single comment).
Update the man pages:
- not to presume that only pcapng files support file comments (even if
that's true now, it might not be true in the future);
- to note that multiple instances of --capture-comment are supported,
and that multiple comments will be written, whether capturing or reading
one file and writing another;
- clarify that Wireshark doesn't *discard* SHB comments other than the
first one, even though it only displays the first one;
2 years ago
|
|
|
#define LONGOPT_CAPTURE_COMMENT LONGOPT_BASE_APPLICATION+6
|
|
|
|
#define LONGOPT_HEXDUMP LONGOPT_BASE_APPLICATION+7
|
|
|
|
#define LONGOPT_SELECTED_FRAME LONGOPT_BASE_APPLICATION+8
|
|
|
|
|
|
|
|
capture_file cfile;
|
|
|
|
|
|
|
|
static guint32 cum_bytes;
|
|
|
|
static frame_data ref_frame;
|
|
|
|
static frame_data prev_dis_frame;
|
|
|
|
static frame_data prev_cap_frame;
|
|
|
|
|
|
|
|
static gboolean perform_two_pass_analysis;
|
|
|
|
static guint32 epan_auto_reset_count = 0;
|
|
|
|
static gboolean epan_auto_reset = FALSE;
|
|
|
|
|
|
|
|
static guint32 selected_frame_number = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The way the packet decode is to be written.
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
WRITE_NONE, /* dummy initial state */
|
|
|
|
WRITE_TEXT, /* summary or detail text */
|
|
|
|
WRITE_XML, /* PDML or PSML */
|
|
|
|
WRITE_FIELDS, /* User defined list of fields */
|
|
|
|
WRITE_JSON, /* JSON */
|
|
|
|
WRITE_JSON_RAW, /* JSON only raw hex */
|
|
|
|
WRITE_EK /* JSON bulk insert to Elasticsearch */
|
|
|
|
/* Add CSV and the like here */
|
|
|
|
} output_action_e;
|
|
|
|
|
|
|
|
static output_action_e output_action;
|
|
|
|
static gboolean do_dissection; /* TRUE if we have to dissect each packet */
|
|
|
|
static gboolean print_packet_info; /* TRUE if we're to print packet information */
|
|
|
|
static gboolean print_summary; /* TRUE if we're to print packet summary information */
|
|
|
|
static gboolean print_details; /* TRUE if we're to print packet details information */
|
|
|
|
static gboolean print_hex; /* TRUE if we're to print hex/ascii information */
|
|
|
|
static gboolean line_buffered;
|
|
|
|
static gboolean quiet = FALSE;
|
|
|
|
static gboolean really_quiet = FALSE;
|
|
|
|
static gchar* delimiter_char = " ";
|
|
|
|
static gboolean dissect_color = FALSE;
|
|
|
|
static guint hexdump_source_option = HEXDUMP_SOURCE_MULTI; /* Default - Enable legacy multi-source mode */
|
|
|
|
static guint hexdump_ascii_option = HEXDUMP_ASCII_INCLUDE; /* Default - Enable legacy undelimited ASCII dump */
|
|
|
|
|
|
|
|
static print_format_e print_format = PR_FMT_TEXT;
|
|
|
|
static print_stream_t *print_stream = NULL;
|
|
|
|
|
|
|
|
static char *output_file_name;
|
|
|
|
|
|
|
|
static output_fields_t* output_fields = NULL;
|
|
|
|
static wmem_map_t *protocolfilter = NULL;
|
|
|
|
|
|
|
|
static gboolean no_duplicate_keys = FALSE;
|
|
|
|
static proto_node_children_grouper_func node_children_grouper = proto_node_group_children_by_unique;
|
|
|
|
|
|
|
|
static json_dumper jdumper;
|
|
|
|
|
|
|
|
/* The line separator used between packets, changeable via the -S option */
|
|
|
|
static const char *separator = "";
|
|
|
|
|
Clean up handling of --capture-comment.
Don't store the comments in a capture_options structure, because that's
available only if we're being built with capture support, and
--capture-comment can be used in TShark when reading a capture file and
writing another capture file, with no live capture taking place.
This means we don't handle that option in capture_opts_add_opt(); handle
it in the programs that support it.
Support writing multiple comments in dumpcap when capturing.
These changes also fix builds without pcap, and makes --capture-comment
work in Wireshark when a capture is started from the command line with
-k.
Update the help messages to indicate that --capture-comment adds a
capture comment, it doesn't change any comment (much less "the" comment,
as there isn't necessarily a single comment).
Update the man pages:
- not to presume that only pcapng files support file comments (even if
that's true now, it might not be true in the future);
- to note that multiple instances of --capture-comment are supported,
and that multiple comments will be written, whether capturing or reading
one file and writing another;
- clarify that Wireshark doesn't *discard* SHB comments other than the
first one, even though it only displays the first one;
2 years ago
|
|
|
/* Per-file comments to be added to the output file. */
|
|
|
|
static GPtrArray *capture_comments = NULL;
|
|
|
|
|
|
|
|
static gboolean prefs_loaded = FALSE;
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBPCAP
|
|
|
|
/*
|
|
|
|
* TRUE if we're to print packet counts to keep track of captured packets.
|
|
|
|
*/
|
|
|
|
static gboolean print_packet_counts;
|
|
|
|
|
|
|
|
static capture_options global_capture_opts;
|
|
|
|
static capture_session global_capture_session;
|
|
|
|
static info_data_t global_info_data;
|
|
|
|
|
|
|
|
#ifdef SIGINFO
|
|
|
|
static gboolean infodelay; /* if TRUE, don't print capture info in SIGINFO handler */
|
|
|
|
static gboolean infoprint; /* if TRUE, print capture info after clearing infodelay */
|
|
|
|
#endif /* SIGINFO */
|
|
|
|
|
|
|
|
static gboolean capture(void);
|
|
|
|
static gboolean capture_input_new_file(capture_session *cap_session,
|
|
|
|
gchar *new_file);
|
|
|
|
static void capture_input_new_packets(capture_session *cap_session,
|
|
|
|
int to_read);
|
|
|
|
static void capture_input_drops(capture_session *cap_session, guint32 dropped,
|
|
|
|
const char* interface_name);
|
|
|
|
static void capture_input_error(capture_session *cap_session,
|
|
|
|
char *error_msg, char *secondary_error_msg);
|
|
|
|
static void capture_input_cfilter_error(capture_session *cap_session,
|
|
|
|
guint i, const char *error_message);
|
|
|
|
static void capture_input_closed(capture_session *cap_session, gchar *msg);
|
|
|
|
|
|
|
|
static void report_counts(void);
|
|
|
|
#ifdef _WIN32
|
|
|
|
static BOOL WINAPI capture_cleanup(DWORD);
|
|
|
|
#else /* _WIN32 */
|
|
|
|
static void capture_cleanup(int);
|
|
|
|
#ifdef SIGINFO
|
|
|
|
static void report_counts_siginfo(int);
|
|
|
|
#endif /* SIGINFO */
|
|
|
|
#endif /* _WIN32 */
|
|
|
|
#endif /* HAVE_LIBPCAP */
|
|
|
|
|
|
|
|
static void reset_epan_mem(capture_file *cf, epan_dissect_t *edt, gboolean tree, gboolean visual);
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
PROCESS_FILE_SUCCEEDED,
|
|
|
|
PROCESS_FILE_NO_FILE_PROCESSED,
|
|
|
|
PROCESS_FILE_ERROR,
|
|
|
|
PROCESS_FILE_INTERRUPTED
|
|
|
|
} process_file_status_t;
|
|
|
|
static process_file_status_t process_cap_file(capture_file *, char *, int, gboolean, int, gint64, int);
|
|
|
|
|
|
|
|
static gboolean process_packet_single_pass(capture_file *cf,
|
|
|
|
epan_dissect_t *edt, gint64 offset, wtap_rec *rec, Buffer *buf,
|
|
|
|
guint tap_flags);
|
tshark: fix handling of "you're writing to a closed pipe" errors on Windows.
On Windows, a write to a pipe where the read side has been closed
apparently may return the Windows error ERROR_BROKEN_PIPE, which the
Visual Studio C library maps to EPIPE, or may return the Windows error
ERROR_NO_DATA, which the Visual Studio C library maps to EINVAL.
So, on Windows, for errors other than the ones for which we're reporting
a special error message, check for EINVAL with a *Windows* error of
ERROR_NO_DATA and, if that's what we have, don't print an error message;
otherwise, print an error message that reports a message based on the
Windows error (rather than a relatively uninformative "Invalid argument"
error).
This should fix issue #16192.
Clean up indentation while we're at it.
2 years ago
|
|
|
static void show_print_file_io_error(void);
|
|
|
|
static gboolean write_preamble(capture_file *cf);
|
|
|
|
static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
|
|
|
|
static gboolean write_finale(void);
|
|
|
|
|
|
|
|
static void tshark_cmdarg_err(const char *msg_format, va_list ap);
|
|
|
|
static void tshark_cmdarg_err_cont(const char *msg_format, va_list ap);
|
|
|
|
|
|
|
|
static GHashTable *output_only_tables = NULL;
|
|
|
|
|
wiretap: more work on file type/subtypes.
Provide a wiretap routine to get an array of all savable file
type/subtypes, sorted with pcap and pcapng at the top, followed by the
other types, sorted either by the name or the description.
Use that routine to list options for the -F flag for various commands
Rename wtap_get_savable_file_types_subtypes() to
wtap_get_savable_file_types_subtypes_for_file(), to indicate that it
provides an array of all file type/subtypes in which a given file can be
saved. Have it sort all types, other than the default type/subtype and,
if there is one, the "other" type (both of which are put at the top), by
the name or the description.
Don't allow wtap_register_file_type_subtypes() to override any existing
registrations; have them always register a new type. In that routine,
if there are any emply slots in the table, due to an entry being
unregistered, use it rather than allocating a new slot.
Don't allow unregistration of built-in types.
Rename the "dump open table" to the "file type/subtype table", as it has
entries for all types/subtypes, even if we can't write them.
Initialize that table in a routine that pre-allocates the GArray before
filling it with built-in types/subtypes, so it doesn't keep getting
reallocated.
Get rid of wtap_num_file_types_subtypes - it's just a copy of the size
of the GArray.
Don't have wtap_file_type_subtype_description() crash if handed an
file type/subtype that isn't a valid array index - just return NULL, as
we do with wtap_file_type_subtype_name().
In wtap_name_to_file_type_subtype(), don't use WTAP_FILE_TYPE_SUBTYPE_
names for the backwards-compatibility names - map those names to the
current names, and then look them up. This reduces the number of
uses of hardwired WTAP_FILE_TYPE_SUBTYPE_ values.
Clean up the type of wtap_module_count - it has no need to be a gulong.
Have built-in wiretap file handlers register names to be used for their
file type/subtypes, rather than building the table in init.lua.
Add a new Lua C function get_wtap_filetypes() to construct the
wtap_filetypes table, based on the registered names, and use it in
init.lua.
Add a #define WSLUA_INTERNAL_FUNCTION to register functions intended
only for internal use in init.lua, so they can be made available from
Lua without being documented.
Get rid of WTAP_NUM_FILE_TYPES_SUBTYPES - most code has no need to use
it, as it can just request arrays of types, and the space of
type/subtype codes can be sparse due to registration in any case, so
code has to be careful using it.
wtap_get_num_file_types_subtypes() is no longer used, so remove it. It
returns the number of elements in the file type/subtype array, which is
not necessarily the name of known file type/subtypes, as there may have
been some deregistered types, and those types do *not* get removed from
the array, they just get cleared so that they're available for future
allocation (we don't want the indices of any registered types to changes
if another type is deregistered, as those indicates are the type/subtype
values, so we can't shrink the array).
Clean up white space and remove some comments that shouldn't have been
added.
2 years ago
|
|
|
static void
|
|
|
|
list_capture_types(void)
|
|
|
|
{
|
|
|
|
GArray *writable_type_subtypes;
|
|
|
|
|
|
|
|
fprintf(stderr, "tshark: The available capture file types for the \"-F\" flag are:\n");
|
|
|
|
writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME);
|
|
|
|
for (guint i = 0; i < writable_type_subtypes->len; i++) {
|
|
|
|
int ft = g_array_index(writable_type_subtypes, int, i);
|
|
|
|
fprintf(stderr, " %s - %s\n", wtap_file_type_subtype_name(ft),
|
|
|
|
wtap_file_type_subtype_description(ft));
|
|
|
|
}
|
|
|
|
g_array_free(writable_type_subtypes, TRUE);
|
wiretap: more work on file type/subtypes.
Provide a wiretap routine to get an array of all savable file
type/subtypes, sorted with pcap and pcapng at the top, followed by the
other types, sorted either by the name or the description.
Use that routine to list options for the -F flag for various commands
Rename wtap_get_savable_file_types_subtypes() to
wtap_get_savable_file_types_subtypes_for_file(), to indicate that it
provides an array of all file type/subtypes in which a given file can be
saved. Have it sort all types, other than the default type/subtype and,
if there is one, the "other" type (both of which are put at the top), by
the name or the description.
Don't allow wtap_register_file_type_subtypes() to override any existing
registrations; have them always register a new type. In that routine,
if there are any emply slots in the table, due to an entry being
unregistered, use it rather than allocating a new slot.
Don't allow unregistration of built-in types.
Rename the "dump open table" to the "file type/subtype table", as it has
entries for all types/subtypes, even if we can't write them.
Initialize that table in a routine that pre-allocates the GArray before
filling it with built-in types/subtypes, so it doesn't keep getting
reallocated.
Get rid of wtap_num_file_types_subtypes - it's just a copy of the size
of the GArray.
Don't have wtap_file_type_subtype_description() crash if handed an
file type/subtype that isn't a valid array index - just return NULL, as
we do with wtap_file_type_subtype_name().
In wtap_name_to_file_type_subtype(), don't use WTAP_FILE_TYPE_SUBTYPE_
names for the backwards-compatibility names - map those names to the
current names, and then look them up. This reduces the number of
uses of hardwired WTAP_FILE_TYPE_SUBTYPE_ values.
Clean up the type of wtap_module_count - it has no need to be a gulong.
Have built-in wiretap file handlers register names to be used for their
file type/subtypes, rather than building the table in init.lua.
Add a new Lua C function get_wtap_filetypes() to construct the
wtap_filetypes table, based on the registered names, and use it in
init.lua.
Add a #define WSLUA_INTERNAL_FUNCTION to register functions intended
only for internal use in init.lua, so they can be made available from
Lua without being documented.
Get rid of WTAP_NUM_FILE_TYPES_SUBTYPES - most code has no need to use
it, as it can just request arrays of types, and the space of
type/subtype codes can be sparse due to registration in any case, so
code has to be careful using it.
wtap_get_num_file_types_subtypes() is no longer used, so remove it. It
returns the number of elements in the file type/subtype array, which is
not necessarily the name of known file type/subtypes, as there may have
been some deregistered types, and those types do *not* get removed from
the array, they just get cleared so that they're available for future
allocation (we don't want the indices of any registered types to changes
if another type is deregistered, as those indicates are the type/subtype
values, so we can't shrink the array).
Clean up white space and remove some comments that shouldn't have been
added.
2 years ago
|
|
|
}
|
|
|
|
|
|
|
|
struct string_elem {
|
|
|
|
const char *sstr; /* The short string */
|
|
|
|
const char *lstr; /* The long string */
|
|
|
|
};
|
|
|
|
|
|
|
|
static gint
|
|
|
|
string_compare(gconstpointer a, gconstpointer b)
|
|
|
|
{
|
|
|
|
return strcmp(((const struct string_elem *)a)->sstr,
|
|
|
|
((const struct string_elem *)b)->sstr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
string_elem_print(gpointer data)
|
|
|
|
{
|
|
|
|
fprintf(stderr, " %s - %s\n",
|
|
|
|
((struct string_elem *)data)->sstr,
|
|
|
|
((struct string_elem *)data)->lstr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
list_read_capture_types(void)
|
|
|
|
{
|
|
|
|
guint i;
|
|
|
|
size_t num_file_types;
|
|
|
|
struct string_elem *captypes;
|
|
|
|
GSList *list = NULL;
|
|
|
|
const char *magic = "Magic-value-based";
|
|
|
|
const char *heuristic = "Heuristics-based";
|
|
|
|
|
|
|
|
/* How many readable file types are there? */
|
|
|
|
num_file_types = 0;
|
|
|
|
for (i = 0; open_routines[i].name != NULL; i++)
|
|
|
|
num_file_types++;
|
|
|
|
captypes = g_new(struct string_elem, num_file_types);
|
|
|
|
|
|
|
|
fprintf(stderr, "tshark: The available read file types for the \"-X read_format:\" option are:\n");
|
|
|
|
for (i = 0; i < num_file_types && open_routines[i].name != NULL; i++) {
|
|
|
|
captypes[i].sstr = open_routines[i].name;
|
|
|
|
captypes[i].lstr = (open_routines[i].type == OPEN_INFO_MAGIC) ? magic : heuristic;
|
|
|
|
list = g_slist_insert_sorted(list, &captypes[i], string_compare);
|
|
|
|
}
|
|
|
|
g_slist_free_full(list, string_elem_print);
|
|
|
|
g_free(captypes);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
list_export_pdu_taps(void)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "tshark: The available export tap names and the encapsulation types they produce for the \"-U tap_name\" option are:\n");
|
|
|
|
for (GSList *export_pdu_tap_name_list = get_export_pdu_tap_list();
|
|
|
|
export_pdu_tap_name_list != NULL;
|
|
|
|
export_pdu_tap_name_list = g_slist_next(export_pdu_tap_name_list)) {
|
|
|
|
fprintf(stderr, " %s - %s\n", (const char*)(export_pdu_tap_name_list->data), wtap_encap_description(export_pdu_tap_get_encap((const char*)export_pdu_tap_name_list->data)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_usage(FILE *output)
|
|
|
|
{
|
|
|
|
fprintf(output, "\n");
|
|
|
|
fprintf(output, "Usage: tshark [options] ...\n");
|
|
|
|
fprintf(output, "\n");
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBPCAP
|
|
|
|
fprintf(output, "Capture interface:\n");
|
|
|
|
fprintf(output, " -i <interface>, --interface <interface>\n");
|
|
|
|
fprintf(output, " name or idx of interface (def: first non-loopback)\n");
|
|
|
|
fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
|
|
|
|
fprintf(output, " -s <snaplen>, --snapshot-length <snaplen>\n");
|
Allow bigger snapshot lengths for D-Bus captures.
Use WTAP_MAX_PACKET_SIZE_STANDARD, set to 256KB, for everything except
for D-Bus captures. Use WTAP_MAX_PACKET_SIZE_DBUS, set to 128MB, for
them, because that's the largest possible D-Bus message size. See
https://bugs.freedesktop.org/show_bug.cgi?id=100220
for an example of the problems caused by limiting the snapshot length to
256KB for D-Bus.
Have a snapshot length of 0 in a capture_file structure mean "there is
no snapshot length for the file"; we don't need the has_snap field in
that case, a value of 0 mean "no, we don't have a snapshot length".
In dumpcap, start out with a pipe buffer size of 2KB, and grow it as
necessary. When checking for a too-big packet from a pipe, check
against the appropriate maximum - 128MB for DLT_DBUS, 256KB for
everything else.
Change-Id: Ib2ce7a0cf37b971fbc0318024fd011e18add8b20
Reviewed-on: https://code.wireshark.org/review/21952
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
6 years ago
|
|
|
#ifdef HAVE_PCAP_CREATE
|
|
|
|
fprintf(output, " packet snapshot length (def: appropriate maximum)\n");
|
Allow bigger snapshot lengths for D-Bus captures.
Use WTAP_MAX_PACKET_SIZE_STANDARD, set to 256KB, for everything except
for D-Bus captures. Use WTAP_MAX_PACKET_SIZE_DBUS, set to 128MB, for
them, because that's the largest possible D-Bus message size. See
https://bugs.freedesktop.org/show_bug.cgi?id=100220
for an example of the problems caused by limiting the snapshot length to
256KB for D-Bus.
Have a snapshot length of 0 in a capture_file structure mean "there is
no snapshot length for the file"; we don't need the has_snap field in
that case, a value of 0 mean "no, we don't have a snapshot length".
In dumpcap, start out with a pipe buffer size of 2KB, and grow it as
necessary. When checking for a too-big packet from a pipe, check
against the appropriate maximum - 128MB for DLT_DBUS, 256KB for
everything else.
Change-Id: Ib2ce7a0cf37b971fbc0318024fd011e18add8b20
Reviewed-on: https://code.wireshark.org/review/21952
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
6 years ago
|
|
|
#else
|
|
|
|
fprintf(output, " packet snapshot length (def: %u)\n", WTAP_MAX_PACKET_SIZE_STANDARD);
|
Allow bigger snapshot lengths for D-Bus captures.
Use WTAP_MAX_PACKET_SIZE_STANDARD, set to 256KB, for everything except
for D-Bus captures. Use WTAP_MAX_PACKET_SIZE_DBUS, set to 128MB, for
them, because that's the largest possible D-Bus message size. See
https://bugs.freedesktop.org/show_bug.cgi?id=100220
for an example of the problems caused by limiting the snapshot length to
256KB for D-Bus.
Have a snapshot length of 0 in a capture_file structure mean "there is
no snapshot length for the file"; we don't need the has_snap field in
that case, a value of 0 mean "no, we don't have a snapshot length".
In dumpcap, start out with a pipe buffer size of 2KB, and grow it as
necessary. When checking for a too-big packet from a pipe, check
against the appropriate maximum - 128MB for DLT_DBUS, 256KB for
everything else.
Change-Id: Ib2ce7a0cf37b971fbc0318024fd011e18add8b20
Reviewed-on: https://code.wireshark.org/review/21952
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
6 years ago
|
|
|
#endif
|
|
|
|
fprintf(output, " -p, --no-promiscuous-mode\n");
|
|
|
|
fprintf(output, " don't capture in promiscuous mode\n");
|
|
|
|
#ifdef HAVE_PCAP_CREATE
|
|
|
|
fprintf(output, " -I, --monitor-mode capture in monitor mode, if available\n");
|
|
|
|
#endif
|
|
|
|
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
|
|
|
|
fprintf(output, " -B <buffer size>, --buffer-size <buffer size>\n");
|
|
|
|
fprintf(output, " size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
|
|
|
|
#endif
|
|
|
|
fprintf(output, " -y <link type>, --linktype <link type>\n");
|
|
|
|
fprintf(output, " link layer type (def: first appropriate)\n");
|
|
|
|
fprintf(output, " --time-stamp-type <type> timestamp method for interface\n");
|
|
|
|
fprintf(output, " -D, --list-interfaces print list of interfaces and exit\n");
|
|
|
|
fprintf(output, " -L, --list-data-link-types\n");
|
|
|
|
fprintf(output, " print list of link-layer types of iface and exit\n");
|
|
|
|
fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n");
|
|
|
|
fprintf(output, "\n");
|
|
|
|
fprintf(output, "Capture stop conditions:\n");
|
|
|
|
fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
|
|
|
|
fprintf(output, " -a <autostop cond.> ..., --autostop <autostop cond.> ...\n");
|
|
|
|
fprintf(output, " duration:NUM - stop after NUM seconds\n");
|
|
|
|
fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
|
|
|
|
fprintf(output, " files:NUM - stop after NUM files\n");
|
|
|
|
fprintf(output, " packets:NUM - stop after NUM packets\n");
|
|
|
|
/*fprintf(output, "\n");*/
|
|
|
|
fprintf(output, "Capture output:\n");
|
|
|
|
fprintf(output, " -b <ringbuffer opt.> ..., --ring-buffer <ringbuffer opt.>\n");
|
|
|
|
fprintf(output, " duration:NUM - switch to next file after NUM secs\n");
|
|
|
|
fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
|
|
|
|
fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
|
|
|
|
fprintf(output, " packets:NUM - switch to next file after NUM packets\n");
|
|
|
|
fprintf(output, " interval:NUM - switch to next file when the time is\n");
|
|
|
|
fprintf(output, " an exact multiple of NUM secs\n");
|
|
|
|
#endif /* HAVE_LIBPCAP */
|
|
|
|
#ifdef HAVE_PCAP_REMOTE
|
|
|
|
fprintf(output, "RPCAP options:\n");
|
|
|
|
fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
|
|
|
|
#endif
|
|
|
|
/*fprintf(output, "\n");*/
|
|
|
|
fprintf(output, "Input file:\n");
|
|
|
|
fprintf(output, " -r <infile>, --read-file <infile>\n");
|
|
|
|
fprintf(output, " set the filename to read from (or '-' for stdin)\n");
|
|
|
|
|
|
|
|
fprintf(output, "\n");
|
|
|
|
fprintf(output, "Processing:\n");
|
|
|
|
fprintf(output, " -2 perform a two-pass analysis\n");
|
|
|
|
fprintf(output, " -M <packet count> perform session auto reset\n");
|
|
|
|
fprintf(output, " -R <read filter>, --read-filter <read filter>\n");
|
|
|
|
fprintf(output, " packet Read filter in Wireshark display filter syntax\n");
|
|
|
|
fprintf(output, " (requires -2)\n");
|
|
|
|
fprintf(output, " -Y <display filter>, --display-filter <display filter>\n");
|
|
|
|
fprintf(output, " packet displaY filter in Wireshark display filter\n");
|
|
|
|
fprintf(output, " syntax\n");
|
|
|
|
fprintf(output, " -n disable all name resolutions (def: \"mNd\" enabled, or\n");
|
|
|
|
fprintf(output, " as set in preferences)\n");
|
|
|
|
fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtdv\"\n");
|
|
|
|
fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
|
|
|
|
fprintf(output, " \"Decode As\", see the man page for details\n");
|
|
|
|
fprintf(output, " Example: tcp.port==8888,http\n");
|
|
|
|
fprintf(output, " -H <hosts file> read a list of entries from a hosts file, which will\n");
|
|
|
|
fprintf(output, " then be written to a capture file. (Implies -W n)\n");
|
|
|
|
fprintf(output, " --enable-protocol <proto_name>\n");
|
|
|
|
fprintf(output, " enable dissection of proto_name\n");
|
|
|
|
fprintf(output, " --disable-protocol <proto_name>\n");
|
|
|
|
fprintf(output, " disable dissection of proto_name\n");
|
|
|
|
fprintf(output, " --enable-heuristic <short_name>\n");
|
|
|
|
fprintf(output, " enable dissection of heuristic protocol\n");
|
|
|
|
fprintf(output, " --disable-heuristic <short_name>\n");
|
|
|
|
fprintf(output, " disable dissection of heuristic protocol\n");
|
|
|
|
|
|
|
|
/*fprintf(output, "\n");*/
|
|
|
|
fprintf(output, "Output:\n");
|
|
|
|
fprintf(output, " -w <outfile|-> write packets to a pcapng-format file named \"outfile\"\n");
|
|
|
|
fprintf(output, " (or '-' for stdout)\n");
|
|
|
|
fprintf(output, " --capture-comment <comment>\n");
|
|
|
|
fprintf(output, " add a capture file comment, if supported\n");
|
|
|
|
fprintf(output, " -C <config profile> start with specified configuration profile\n");
|
|
|
|
fprintf(output, " -F <output file type> set the output file type, default is pcapng\n");
|
|
|
|
fprintf(output, " an empty \"-F\" option will list the file types\n");
|
|
|
|
fprintf(output, " -V add output of packet tree (Packet Details)\n");
|
|
|
|
fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
|
|
|
|
fprintf(output, " separated\n");
|
|
|
|
fprintf(output, " -P, --print print packet summary even when writing to a file\n");
|
|
|
|
fprintf(output, " -S <separator> the line separator to print between packets\n");
|
|
|
|
fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
|
|
|
|
fprintf(output, " --hexdump <hexoption> add hexdump, set options for data source and ASCII dump\n");
|
|
|
|
fprintf(output, " all dump all data sources (-x default)\n");
|
|
|
|
fprintf(output, " frames dump only frame data source\n");
|
|
|
|
fprintf(output, " ascii include ASCII dump text (-x default)\n");
|
|
|
|
fprintf(output, " delimit delimit ASCII dump text with '|' characters\n");
|
|
|
|
fprintf(output, " noascii exclude ASCII dump text\n");
|
|
|
|
fprintf(output, " help display help for --hexdump and exit\n");
|
|
|
|
fprintf(output, " -T pdml|ps|psml|json|jsonraw|ek|tabs|text|fields|?\n");
|
|
|
|
fprintf(output, " format of text output (def: text)\n");
|
|
|
|
fprintf(output, " -j <protocolfilter> protocols layers filter if -T ek|pdml|json selected\n");
|
|
|
|
fprintf(output, " (e.g. \"ip ip.flags text\", filter does not expand child\n");
|
|
|
|
fprintf(output, " nodes, unless child is specified also in the filter)\n");
|
|
|
|
fprintf(output, " -J <protocolfilter> top level protocol filter if -T ek|pdml|json selected\n");
|
|
|
|
fprintf(output, " (e.g. \"http tcp\", filter which expands all child nodes)\n");
|
|
|
|
fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
|
|
|
|
fprintf(output, " _ws.col.Info)\n");
|
|
|
|
fprintf(output, " this option can be repeated to print multiple fields\n");
|
|
|
|
fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
|
|
|
|
fprintf(output, " bom=y|n print a UTF-8 BOM\n");
|
|
|
|
fprintf(output, " header=y|n switch headers on and off\n");
|
|
|
|
fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
|
|
|
|
fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
|
|
|
|
fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
|
|
|
|
fprintf(output, " aggregator\n");
|
|
|
|
fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
|
|
|
|
fprintf(output, " -t a|ad|adoy|d|dd|e|r|u|ud|udoy\n");
|
|
|
|
fprintf(output, " output format of time stamps (def: r: rel. to first)\n");
|
|
|
|
fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
|
|
|
|
fprintf(output, " -l flush standard output after each packet\n");
|
|
|
|
fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
|
|
|
|
fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
|
|
|
|
fprintf(output, " -g enable group read access on the output file(s)\n");
|
|
|
|
fprintf(output, " -W n Save extra information in the file, if supported.\n");
|
|
|
|
fprintf(output, " n = write network address resolution information\n");
|
|
|
|
fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
|
|
|
|
fprintf(output, " -U tap_name PDUs export mode, see the man page for details\n");
|
|
|
|
fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
|
|
|
|
fprintf(output, " --export-objects <protocol>,<destdir>\n");
|
|
|
|
fprintf(output, " save exported objects for a protocol to a directory\n");
|
|
|
|
fprintf(output, " named \"destdir\"\n");
|
|
|
|
fprintf(output, " --export-tls-session-keys <keyfile>\n");
|
|
|
|
fprintf(output, " export TLS Session Keys to a file named \"keyfile\"\n");
|
|
|
|
fprintf(output, " --color color output text similarly to the Wireshark GUI,\n");
|
|
|
|
fprintf(output, " requires a terminal with 24-bit color support\n");
|
|
|
|
fprintf(output, " Also supplies color attributes to pdml and psml formats\n");
|
|
|
|
fprintf(output, " (Note that attributes are nonstandard)\n");
|
|
|
|
fprintf(output, " --no-duplicate-keys If -T json is specified, merge duplicate keys in an object\n");
|
|
|
|
fprintf(output, " into a single key with as value a json array containing all\n");
|
|
|
|
fprintf(output, " values\n");
|
|
|
|
fprintf(output, " --elastic-mapping-filter <protocols> If -G elastic-mapping is specified, put only the\n");
|
|
|
|
fprintf(output, " specified protocols within the mapping file\n");
|
|
|
|
fprintf(output, " --temp-dir <directory> write temporary files to this directory\n");
|
|
|
|
fprintf(output, " (default: %s)\n", g_get_tmp_dir());
|
|
|
|
fprintf(output, "\n");
|
|
|
|
|
|
|
|
ws_log_print_usage(output);
|
|
|
|
fprintf(output, "\n");
|
|
|
|
|
|
|
|
fprintf(output, "Miscellaneous:\n");
|
|
|
|
fprintf(output, " -h, --help display this help and exit\n");
|
|
|
|
fprintf(output, " -v, --version 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");
|
|
|
|
fprintf(output, " -G [report] dump one of several available reports and exit\n");
|
|
|
|
fprintf(output, " default report=\"fields\"\n");
|
|
|
|
fprintf(output, " use \"-G help\" for more help\n");
|
|
|
|
#ifdef __linux__
|
|
|
|
fprintf(output, "\n");
|
|
|
|
fprintf(output, "Dumpcap can benefit from an enabled BPF JIT compiler if available.\n");
|
|
|
|
fprintf(output, "You might want to enable it by executing:\n");
|
|
|
|
fprintf(output, " \"echo 1 > /proc/sys/net/core/bpf_jit_enable\"\n");
|
|
|
|
fprintf(output, "Note that this can make your system less secure!\n");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
glossary_option_help(void)
|
|
|
|
{
|
|
|
|
FILE *output;
|
|
|
|
|
|
|
|
output = stdout;
|
|
|
|
|
|
|
|
fprintf(output, "%s\n", get_appname_and_version());
|
|
|
|
|
|
|
|
fprintf(output, "\n");
|
|
|
|
fprintf(output, "Usage: tshark -G [report]\n");
|
|
|
|
fprintf(output, "\n");
|
|
|
|
fprintf(output, "Glossary table reports:\n");
|
|
|
|
fprintf(output, " -G column-formats dump column format codes and exit\n");
|
|
|
|
fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
|
|
|
|
fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
|
|
|
|
fprintf(output, " -G elastic-mapping dump ElasticSearch mapping file\n");
|
|
|
|
fprintf(output, " -G fieldcount dump count of header fields and exit\n");
|
|
|
|
fprintf(output, " -G fields dump fields glossary and exit\n");
|
|
|
|
fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
|
|
|
|
fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
|
|
|
|
fprintf(output, " -G plugins dump installed plugins 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, "\n");
|
|
|
|
fprintf(output, "Preference reports:\n");
|
|
|
|
fprintf(output, " -G currentprefs dump current preferences and exit\n");
|
|
|
|
fprintf(output, " -G defaultprefs dump default preferences and exit\n");
|
|
|
|
fprintf(output, " -G folders dump about:folders\n");
|
|
|
|
fprintf(output, "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
hexdump_option_help(FILE *output)
|
|
|
|
{
|
|
|
|
fprintf(output, "%s\n", get_appname_and_version());
|
|
|
|
fprintf(output, "\n");
|
|
|
|
fprintf(output, "tshark: Valid --hexdump <hexoption> values include:\n");
|
|
|
|
fprintf(output, "\n");
|
|
|
|
fprintf(output, "Data source options:\n");
|
|
|
|
fprintf(output, " all add hexdump, dump all data sources (-x default)\n");
|
|
|
|
fprintf(output, " frames add hexdump, dump only frame data source\n");
|
|
|
|
fprintf(output, "\n");
|
|
|
|
fprintf(output, "ASCII options:\n");
|
|
|
|
fprintf(output, " ascii add hexdump, include ASCII dump text (-x default)\n");
|
|
|
|
fprintf(output, " delimit add hexdump, delimit ASCII dump text with '|' characters\n");
|
|
|
|
fprintf(output, " noascii add hexdump, exclude ASCII dump text\n");
|
|
|
|
fprintf(output, "\n");
|
|
|
|
fprintf(output, "Miscellaneous:\n");
|
|
|
|
fprintf(output, " help display this help and exit\n");
|
|
|
|
fprintf(output, "\n");
|
|
|
|
fprintf(output, "Example:\n");
|
|
|
|
fprintf(output, "\n");
|
|
|
|
fprintf(output, " $ tshark ... --hexdump frames --hexdump delimit ...\n");
|
|
|
|
fprintf(output, "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
protocolfilter_add_opt(const char* arg, pf_flags filter_flags)
|
|
|
|
{
|
|
|
|
void* value;
|
|
|
|
gchar **newfilter = NULL;
|
|
|
|
for (newfilter = wmem_strsplit(wmem_epan_scope(), arg, " ", -1); *newfilter; newfilter++) {
|
|
|
|
if (strcmp(*newfilter, "") == 0) {
|
|
|
|
/* Don't treat the empty string as an intended field abbreviation
|
|
|
|
* to output, consecutive spaces on the command line probably
|
|
|
|
* aren't intentional.
|
|
|
|
*/
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!protocolfilter) {
|
|
|
|
protocolfilter = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
|
|
|
|
}
|
|
|
|
if (wmem_map_lookup_extended(protocolfilter, *newfilter, NULL, &value)) {
|
|
|
|
if (GPOINTER_TO_UINT(value) != (guint)filter_flags) {
|
|
|
|
|
|
|
|
cmdarg_err("%s was already specified with different filter flags. Overwriting previous protocol filter.", *newfilter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
wmem_map_insert(protocolfilter, *newfilter, GINT_TO_POINTER(filter_flags));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
print_current_user(void)
|
|
|
|
{
|
|
|
|
gchar *cur_user, *cur_group;
|
|
|
|
|
|
|
|
if (started_with_special_privs()) {
|
|
|
|
cur_user = get_cur_username();
|
|
|
|
cur_group = get_cur_groupname();
|
|
|
|
fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
|
|
|
|
cur_user, cur_group);
|
|
|
|
g_free(cur_user);
|
|
|
|
g_free(cur_group);
|
|
|
|
if (running_with_special_privs()) {
|
|
|
|
fprintf(stderr, " This could be dangerous.");
|
|
|
|
}
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
}
|
|
|