3 * Text-mode variant of Fileshark, based off of TShark,
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0+
26 #ifndef HAVE_GETOPT_LONG
27 #include "wsutil/wsgetopt.h"
32 #include <epan/exceptions.h>
33 #include <epan/epan.h>
35 #include <wsutil/clopts_common.h>
36 #include <wsutil/cmdarg_err.h>
37 #include <wsutil/crash_info.h>
38 #include <wsutil/filesystem.h>
39 #include <wsutil/file_util.h>
40 #include <wsutil/privileges.h>
41 #include <wsutil/report_message.h>
42 #include <version_info.h>
45 #include <epan/timestamp.h>
46 #include <epan/packet.h>
48 #include <epan/wslua/init_wslua.h>
51 #include "frame_tvbuff.h"
52 #include <epan/disabled_protos.h>
53 #include <epan/prefs.h>
54 #include <epan/column.h>
55 #include <epan/print.h>
56 #include <epan/addr_resolv.h>
58 #include "ui/decode_as_utils.h"
59 #include "ui/dissect_opts.h"
60 #include "epan/register.h"
61 #include <epan/epan_dissect.h>
63 #include <epan/stat_tap_ui.h>
64 #include <epan/ex-opt.h>
70 #include <wiretap/wtap-int.h>
71 #include <wiretap/file_wrappers.h>
74 #include <wsutil/unicode-utils.h>
78 #include <epan/funnel.h>
81 #include <wsutil/plugins.h>
84 #define INVALID_OPTION 1
86 #define INVALID_FILTER 2
91 static guint32 cum_bytes;
92 static frame_data ref_frame;
93 static frame_data prev_dis_frame;
94 static frame_data prev_cap_frame;
96 static gboolean prefs_loaded = FALSE;
98 static gboolean perform_two_pass_analysis;
101 * The way the packet decode is to be written.
104 WRITE_TEXT, /* summary or detail text */
105 WRITE_XML, /* PDML or PSML */
106 WRITE_FIELDS /* User defined list of fields */
107 /* Add CSV and the like here */
110 static output_action_e output_action;
111 static gboolean do_dissection; /* TRUE if we have to dissect each packet */
112 static gboolean print_packet_info; /* TRUE if we're to print packet information */
113 static gint print_summary = -1; /* TRUE if we're to print packet summary information */
114 static gboolean print_details; /* TRUE if we're to print packet details information */
115 static gboolean print_hex; /* TRUE if we're to print hex/ascci information */
116 static gboolean line_buffered;
117 static gboolean really_quiet = FALSE;
119 static print_format_e print_format = PR_FMT_TEXT;
120 static print_stream_t *print_stream;
122 static output_fields_t* output_fields = NULL;
124 /* The line separator used between packets, changeable via the -S option */
125 static const char *separator = "";
127 static gboolean process_file(capture_file *, int, gint64);
128 static gboolean process_packet_single_pass(capture_file *cf,
129 epan_dissect_t *edt, gint64 offset, struct wtap_pkthdr *whdr,
130 const guchar *pd, guint tap_flags);
131 static void show_print_file_io_error(int err);
132 static gboolean write_preamble(capture_file *cf);
133 static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
134 static gboolean write_finale(void);
135 static const char *cf_open_error_message(int err, gchar *err_info,
136 gboolean for_writing, int file_type);
138 static void failure_warning_message(const char *msg_format, va_list ap);
139 static void open_failure_message(const char *filename, int err,
140 gboolean for_writing);
141 static void read_failure_message(const char *filename, int err);
142 static void write_failure_message(const char *filename, int err);
143 static void failure_message_cont(const char *msg_format, va_list ap);
145 static GHashTable *output_only_tables = NULL;
149 const char *sstr; /* The short string */
150 const char *lstr; /* The long string */
154 string_compare(gconstpointer a, gconstpointer b)
156 return strcmp(((const struct string_elem *)a)->sstr,
157 ((const struct string_elem *)b)->sstr);
161 string_elem_print(gpointer data, gpointer not_used _U_)
163 fprintf(stderr, " %s - %s\n",
164 ((struct string_elem *)data)->sstr,
165 ((struct string_elem *)data)->lstr);
170 print_usage(FILE *output)
172 fprintf(output, "\n");
173 fprintf(output, "Usage: tfshark [options] ...\n");
174 fprintf(output, "\n");
176 /*fprintf(output, "\n");*/
177 fprintf(output, "Input file:\n");
178 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin)\n");
180 fprintf(output, "\n");
181 fprintf(output, "Processing:\n");
182 fprintf(output, " -2 perform a two-pass analysis\n");
183 fprintf(output, " -R <read filter> packet Read filter in Wireshark display filter syntax\n");
184 fprintf(output, " (requires -2)\n");
185 fprintf(output, " -Y <display filter> packet displaY filter in Wireshark display filter\n");
186 fprintf(output, " syntax\n");
187 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
188 fprintf(output, " \"Decode As\", see the man page for details\n");
189 fprintf(output, " Example: tcp.port==8888,http\n");
191 /*fprintf(output, "\n");*/
192 fprintf(output, "Output:\n");
193 fprintf(output, " -C <config profile> start with specified configuration profile\n");
194 fprintf(output, " -V add output of packet tree (Packet Details)\n");
195 fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
196 fprintf(output, " separated\n");
197 fprintf(output, " -S <separator> the line separator to print between packets\n");
198 fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
199 fprintf(output, " -T pdml|ps|psml|text|fields\n");
200 fprintf(output, " format of text output (def: text)\n");
201 fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
202 fprintf(output, " _ws.col.Info)\n");
203 fprintf(output, " this option can be repeated to print multiple fields\n");
204 fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
205 fprintf(output, " header=y|n switch headers on and off\n");
206 fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
207 fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
208 fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
209 fprintf(output, " aggregator\n");
210 fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
211 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
212 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
213 fprintf(output, " -l flush standard output after each packet\n");
214 fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
215 fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
216 fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
217 fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
219 fprintf(output, "\n");
220 fprintf(output, "Miscellaneous:\n");
221 fprintf(output, " -h display this help and exit\n");
222 fprintf(output, " -v display version info and exit\n");
223 fprintf(output, " -o <name>:<value> ... override preference setting\n");
224 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
225 fprintf(output, " -G [report] dump one of several available reports and exit\n");
226 fprintf(output, " default report=\"fields\"\n");
227 fprintf(output, " use \"-G ?\" for more help\n");
231 glossary_option_help(void)
237 fprintf(output, "TFShark (Wireshark) %s\n", get_ws_vcs_version_info());
239 fprintf(output, "\n");
240 fprintf(output, "Usage: tfshark -G [report]\n");
241 fprintf(output, "\n");
242 fprintf(output, "Glossary table reports:\n");
243 fprintf(output, " -G column-formats dump column format codes and exit\n");
244 fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
245 fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
246 fprintf(output, " -G fields dump fields glossary and exit\n");
247 fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
248 fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
249 fprintf(output, " -G plugins dump installed plugins and exit\n");
250 fprintf(output, " -G protocols dump protocols in registration database and exit\n");
251 fprintf(output, " -G values dump value, range, true/false strings and exit\n");
252 fprintf(output, "\n");
253 fprintf(output, "Preference reports:\n");
254 fprintf(output, " -G currentprefs dump current preferences and exit\n");
255 fprintf(output, " -G defaultprefs dump default preferences and exit\n");
256 fprintf(output, "\n");
260 tfshark_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
261 const gchar *message, gpointer user_data)
263 /* ignore log message, if log_level isn't interesting based
264 upon the console log preferences.
265 If the preferences haven't been loaded yet, display the
268 The default console_log_level preference value is such that only
269 ERROR, CRITICAL and WARNING level messages are processed;
270 MESSAGE, INFO and DEBUG level messages are ignored.
272 XXX: Aug 07, 2009: Prior tshark g_log code was hardwired to process only
273 ERROR and CRITICAL level messages so the current code is a behavioral
274 change. The current behavior is the same as in Wireshark.
276 if (prefs_loaded && (log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0) {
280 g_log_default_handler(log_domain, log_level, message, user_data);
285 print_current_user(void) {
286 gchar *cur_user, *cur_group;
288 if (started_with_special_privs()) {
289 cur_user = get_cur_username();
290 cur_group = get_cur_groupname();
291 fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
292 cur_user, cur_group);
295 if (running_with_special_privs()) {
296 fprintf(stderr, " This could be dangerous.");
298 fprintf(stderr, "\n");
303 get_tfshark_runtime_version_info(GString *str)
305 /* stuff used by libwireshark */
306 epan_get_runtime_version_info(str);
310 main(int argc, char *argv[])
312 GString *comp_info_str;
313 GString *runtime_info_str;
314 char *init_progfile_dir_error;
316 static const struct option long_options[] = {
317 {"help", no_argument, NULL, 'h'},
318 {"version", no_argument, NULL, 'v'},
321 gboolean arg_error = FALSE;
324 volatile gboolean success;
325 volatile int exit_status = 0;
326 gboolean quiet = FALSE;
327 gchar *volatile cf_name = NULL;
328 gchar *rfilter = NULL;
329 gchar *dfilter = NULL;
330 dfilter_t *rfcode = NULL;
331 dfilter_t *dfcode = NULL;
335 gchar *output_only = NULL;
338 * The leading + ensures that getopt_long() does not permute the argv[]
341 * We have to make sure that the first getopt_long() preserves the content
342 * of argv[] for the subsequent getopt_long() call.
344 * We use getopt_long() in both cases to ensure that we're using a routine
345 * whose permutation behavior we can control in the same fashion on all
346 * platforms, and so that, if we ever need to process a long argument before
347 * doing further initialization, we can do so.
349 * Glibc and Solaris libc document that a leading + disables permutation
350 * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
351 * and macOS don't document it, but do so anyway.
353 * We do *not* use a leading - because the behavior of a leading - is
354 * platform-dependent.
356 #define OPTSTRING "+2C:d:e:E:hK:lo:O:qQr:R:S:t:T:u:vVxX:Y:z:"
358 static const char optstring[] = OPTSTRING;
360 /* Set the C-language locale to the native environment. */
361 setlocale(LC_ALL, "");
363 cmdarg_err_init(failure_warning_message, failure_message_cont);
366 arg_list_utf_16to8(argc, argv);
367 create_app_running_mutex();
368 #if !GLIB_CHECK_VERSION(2,31,0)
374 * Get credential information for later use, and drop privileges
375 * before doing anything else.
376 * Let the user know if anything happened.
378 init_process_policies();
379 relinquish_special_privs_perm();
380 print_current_user();
383 * Attempt to get the pathname of the directory containing the
386 init_progfile_dir_error = init_progfile_dir(argv[0], main);
387 if (init_progfile_dir_error != NULL) {
389 "tfshark: Can't get pathname of directory containing the tfshark program: %s.\n",
390 init_progfile_dir_error);
391 g_free(init_progfile_dir_error);
394 initialize_funnel_ops();
396 /* Get the compile-time version information string */
397 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
399 /* Get the run-time version information string */
400 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
402 /* Add it to the information to be reported on a crash. */
403 ws_add_crash_info("TFShark (Wireshark) %s\n"
408 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
409 g_string_free(comp_info_str, TRUE);
410 g_string_free(runtime_info_str, TRUE);
413 * In order to have the -X opts assigned before the wslua machine starts
414 * we need to call getopts before epan_init() gets called.
416 * In order to handle, for example, -o options, we also need to call it
417 * *after* epan_init() gets called, so that the dissectors have had a
418 * chance to register their preferences.
420 * XXX - can we do this all with one getopt_long() call, saving the
421 * arguments we can't handle until after initializing libwireshark,
422 * and then process them after initializing libwireshark?
426 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
428 case 'C': /* Configuration Profile */
429 if (profile_exists (optarg, FALSE)) {
430 set_profile_name (optarg);
432 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
436 case 'O': /* Only output these protocols */
437 output_only = g_strdup(optarg);
439 case 'V': /* Verbose */
440 print_details = TRUE;
441 print_packet_info = TRUE;
443 case 'x': /* Print packet data in hex (and ASCII) */
445 /* The user asked for hex output, so let's ensure they get it,
446 * even if they're writing to a file.
448 print_packet_info = TRUE;
459 * Print packet summary information is the default, unless either -V or -x
460 * were specified. Note that this is new behavior, which
461 * allows for the possibility of printing only hex/ascii output without
462 * necessarily requiring that either the summary or details be printed too.
464 if (print_summary == -1)
465 print_summary = (print_details || print_hex) ? FALSE : TRUE;
467 /** Send All g_log messages to our own handler **/
471 G_LOG_LEVEL_CRITICAL|
476 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
478 g_log_set_handler(NULL,
479 (GLogLevelFlags)log_flags,
480 tfshark_log_handler, NULL /* user_data */);
481 g_log_set_handler(LOG_DOMAIN_MAIN,
482 (GLogLevelFlags)log_flags,
483 tfshark_log_handler, NULL /* user_data */);
485 init_report_message(failure_warning_message, failure_warning_message,
486 open_failure_message, read_failure_message,
487 write_failure_message);
489 timestamp_set_type(TS_RELATIVE);
490 timestamp_set_precision(TS_PREC_AUTO);
491 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
495 /* Register all dissectors; we must do this before checking for the
496 "-G" flag, as the "-G" flag dumps information registered by the
497 dissectors, and we must do it before we read the preferences, in
498 case any dissectors register preferences. */
499 if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
501 exit_status = INIT_ERROR;
505 /* Register all tap listeners; we do this before we parse the arguments,
506 as the "-z" argument can specify a registered tap. */
508 /* we register the plugin taps before the other taps because
509 stats_tree taps plugins will be registered as tap listeners
510 by stats_tree_stat.c and need to registered before that */
512 /* XXX Disable tap registration for now until we can get tfshark set up with
513 * its own set of taps and the necessary registration function etc.
515 register_all_plugin_tap_listeners();
517 register_all_tap_listeners();
520 /* If invoked with the "-G" flag, we dump out information based on
521 the argument to the "-G" flag; if no argument is specified,
522 for backwards compatibility we dump out a glossary of display
525 XXX - we do this here, for now, to support "-G" with no arguments.
526 If none of our build or other processes uses "-G" with no arguments,
527 we can just process it with the other arguments. */
528 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
529 proto_initialize_all_prefixes();
532 proto_registrar_dump_fields();
534 if (strcmp(argv[2], "column-formats") == 0)
535 column_dump_column_formats();
536 else if (strcmp(argv[2], "currentprefs") == 0) {
537 epan_load_settings();
540 else if (strcmp(argv[2], "decodes") == 0)
541 dissector_dump_decodes();
542 else if (strcmp(argv[2], "defaultprefs") == 0)
544 else if (strcmp(argv[2], "dissector-tables") == 0)
545 dissector_dump_dissector_tables();
546 else if (strcmp(argv[2], "fields") == 0)
547 proto_registrar_dump_fields();
548 else if (strcmp(argv[2], "ftypes") == 0)
549 proto_registrar_dump_ftypes();
550 else if (strcmp(argv[2], "heuristic-decodes") == 0)
551 dissector_dump_heur_decodes();
552 else if (strcmp(argv[2], "plugins") == 0) {
557 wslua_plugins_dump_all();
560 else if (strcmp(argv[2], "protocols") == 0)
561 proto_registrar_dump_protocols();
562 else if (strcmp(argv[2], "values") == 0)
563 proto_registrar_dump_values();
564 else if (strcmp(argv[2], "?") == 0)
565 glossary_option_help();
566 else if (strcmp(argv[2], "-?") == 0)
567 glossary_option_help();
569 cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
570 exit_status = INVALID_OPTION;
577 /* Load libwireshark settings from the current profile. */
578 prefs_p = epan_load_settings();
581 cap_file_init(&cfile);
583 /* Print format defaults to this. */
584 print_format = PR_FMT_TEXT;
586 output_fields = output_fields_new();
589 * To reset the options parser, set optreset to 1 on platforms that
590 * have optreset (documented in *BSD and macOS, apparently present but
591 * not documented in Solaris - the Illumos repository seems to
592 * suggest that the first Solaris getopt_long(), at least as of 2004,
593 * was based on the NetBSD one, it had optreset) and set optind to 1,
594 * and set optind to 0 otherwise (documented as working in the GNU
595 * getopt_long(). Setting optind to 0 didn't originally work in the
596 * NetBSD one, but that was added later - we don't want to depend on
597 * it if we have optreset).
599 * Also reset opterr to 1, so that error messages are printed by
610 /* Now get our args */
611 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
613 case '2': /* Perform two pass analysis */
614 perform_two_pass_analysis = TRUE;
617 /* already processed; just ignore it now */
621 output_fields_add(output_fields, optarg);
625 if (!output_fields_set_option(output_fields, optarg)) {
626 cmdarg_err("\"%s\" is not a valid field output option=value pair.", optarg);
627 output_fields_list_options(stderr);
628 exit_status = INVALID_OPTION;
633 case 'h': /* Print help and exit */
634 printf("TFShark (Wireshark) %s\n"
635 "Dump and analyze network traffic.\n"
636 "See https://www.wireshark.org for more information.\n",
637 get_ws_vcs_version_info());
641 case 'l': /* "Line-buffer" standard output */
642 /* The ANSI C standard does not appear to *require* that a line-buffered
643 stream be flushed to the host environment whenever a newline is
644 written, it just says that, on such a stream, characters "are
645 intended to be transmitted to or from the host environment as a
646 block when a new-line character is encountered".
648 The Visual C++ 6.0 C implementation doesn't do what is intended;
649 even if you set a stream to be line-buffered, it still doesn't
650 flush the buffer at the end of every line.
652 The whole reason for the "-l" flag in either tcpdump or TShark
653 is to allow the output of a live capture to be piped to a program
654 or script and to have that script see the information for the
655 packet as soon as it's printed, rather than having to wait until
656 a standard I/O buffer fills up.
658 So, if the "-l" flag is specified, we flush the standard output
659 at the end of a packet. This will do the right thing if we're
660 printing packet summary lines, and, as we print the entire protocol
661 tree for a single packet without waiting for anything to happen,
662 it should be as good as line-buffered mode if we're printing
663 protocol trees - arguably even better, as it may do fewer
665 line_buffered = TRUE;
667 case 'o': /* Override preference from command line */
671 switch (prefs_set_pref(optarg, &errmsg)) {
676 case PREFS_SET_SYNTAX_ERR:
677 cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg,
678 errmsg ? ": " : "", errmsg ? errmsg : "");
683 case PREFS_SET_NO_SUCH_PREF:
684 case PREFS_SET_OBSOLETE:
685 cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
686 exit_status = INVALID_OPTION;
692 case 'q': /* Quiet */
695 case 'Q': /* Really quiet */
699 case 'r': /* Read capture file x */
700 cf_name = g_strdup(optarg);
702 case 'R': /* Read file filter */
705 case 'S': /* Set the line Separator to be printed between packets */
706 separator = g_strdup(optarg);
708 case 'T': /* printing Type */
709 if (strcmp(optarg, "text") == 0) {
710 output_action = WRITE_TEXT;
711 print_format = PR_FMT_TEXT;
712 } else if (strcmp(optarg, "ps") == 0) {
713 output_action = WRITE_TEXT;
714 print_format = PR_FMT_PS;
715 } else if (strcmp(optarg, "pdml") == 0) {
716 output_action = WRITE_XML;
717 print_details = TRUE; /* Need details */
718 print_summary = FALSE; /* Don't allow summary */
719 } else if (strcmp(optarg, "psml") == 0) {
720 output_action = WRITE_XML;
721 print_details = FALSE; /* Don't allow details */
722 print_summary = TRUE; /* Need summary */
723 } else if (strcmp(optarg, "fields") == 0) {
724 output_action = WRITE_FIELDS;
725 print_details = TRUE; /* Need full tree info */
726 print_summary = FALSE; /* Don't allow summary */
728 cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg); /* x */
729 cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
730 "\t specified by the -E option.\n"
731 "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
732 "\t details of a decoded packet. This information is equivalent to\n"
733 "\t the packet details printed with the -V flag.\n"
734 "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
735 "\t the packets, or a multi-line view of the details of each of\n"
736 "\t the packets, depending on whether the -V flag was specified.\n"
737 "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
738 "\t summary information of a decoded packet. This information is\n"
739 "\t equivalent to the information shown in the one-line summary\n"
740 "\t printed by default.\n"
741 "\t\"text\" Text of a human-readable one-line summary of each of the\n"
742 "\t packets, or a multi-line view of the details of each of the\n"
743 "\t packets, depending on whether the -V flag was specified.\n"
744 "\t This is the default.");
745 exit_status = INVALID_OPTION;
749 case 'v': /* Show version and exit */
750 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
751 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
752 show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
753 g_string_free(comp_info_str, TRUE);
754 g_string_free(runtime_info_str, TRUE);
756 case 'O': /* Only output these protocols */
757 /* already processed; just ignore it now */
759 case 'V': /* Verbose */
760 /* already processed; just ignore it now */
762 case 'x': /* Print packet data in hex (and ASCII) */
763 /* already processed; just ignore it now */
766 /* already processed; just ignore it now */
772 /* We won't call the init function for the stat this soon
773 as it would disallow MATE's fields (which are registered
774 by the preferences set callback) from being used as
775 part of a tap filter. Instead, we just add the argument
776 to a list of stat arguments. */
777 if (strcmp("help", optarg) == 0) {
778 fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
779 list_stat_cmd_args();
782 if (!process_stat_cmd_arg(optarg)) {
783 cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
784 list_stat_cmd_args();
785 exit_status = INVALID_OPTION;
789 case 'd': /* Decode as rule */
790 case 'K': /* Kerberos keytab file */
791 case 't': /* Time stamp type */
792 case 'u': /* Seconds type */
793 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
794 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
795 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
796 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
797 if (!dissect_opts_handle_opt(opt, optarg)) {
798 exit_status = INVALID_OPTION;
803 case '?': /* Bad flag - print usage message */
805 exit_status = INVALID_OPTION;
811 /* If we specified output fields, but not the output field type... */
812 if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
813 cmdarg_err("Output fields were specified with \"-e\", "
814 "but \"-Tfields\" was not specified.");
816 } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
817 cmdarg_err("\"-Tfields\" was specified, but no fields were "
818 "specified with \"-e\".");
820 exit_status = INVALID_OPTION;
824 /* If no capture filter or display filter has been specified, and there are
825 still command-line arguments, treat them as the tokens of a capture
826 filter (if no "-r" flag was specified) or a display filter (if a "-r"
827 flag was specified. */
829 if (cf_name != NULL) {
830 if (dfilter != NULL) {
831 cmdarg_err("Display filters were specified both with \"-d\" "
832 "and with additional command-line arguments.");
833 exit_status = INVALID_OPTION;
836 dfilter = get_args_as_string(argc, argv, optind);
840 /* if "-q" wasn't specified, we should print packet information */
842 print_packet_info = TRUE;
846 exit_status = INVALID_OPTION;
851 if (output_action != WRITE_TEXT) {
852 cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
853 exit_status = INVALID_OPTION;
858 if (output_only != NULL) {
861 if (!print_details) {
862 cmdarg_err("-O requires -V");
863 exit_status = INVALID_OPTION;
867 output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
868 for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
869 g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
873 if (rfilter != NULL && !perform_two_pass_analysis) {
874 cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
875 exit_status = INVALID_OPTION;
879 /* Notify all registered modules that have had any of their preferences
880 changed either from one of the preferences file or from the command
881 line that their preferences have changed. */
884 /* At this point MATE will have registered its field array so we can
885 have a tap filter with one of MATE's late-registered fields as part
886 of the filter. We can now process all the "-z" arguments. */
887 start_requested_stats();
890 * Enabled and disabled protocols and heuristic dissectors as per
891 * command-line options.
893 if (!setup_enabled_and_disabled_protocols()) {
894 exit_status = INVALID_OPTION;
898 /* Build the column format array */
899 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
901 if (rfilter != NULL) {
902 if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
903 cmdarg_err("%s", err_msg);
905 exit_status = INVALID_FILTER;
909 cfile.rfcode = rfcode;
911 if (dfilter != NULL) {
912 if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
913 cmdarg_err("%s", err_msg);
915 exit_status = INVALID_FILTER;
919 cfile.dfcode = dfcode;
921 if (print_packet_info) {
922 /* If we're printing as text or PostScript, we have
923 to create a print stream. */
924 if (output_action == WRITE_TEXT) {
925 switch (print_format) {
928 print_stream = print_stream_text_stdio_new(stdout);
932 print_stream = print_stream_ps_stdio_new(stdout);
936 g_assert_not_reached();
941 /* We have to dissect each packet if:
943 we're printing information about each packet;
945 we're using a read filter on the packets;
947 we're using a display filter on the packets;
949 we're using any taps that need dissection. */
950 do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
954 * We're reading a capture file.
957 /* TODO: if tfshark is ever changed to give the user a choice of which
958 open_routine reader to use, then the following needs to change. */
959 if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
960 exit_status = OPEN_ERROR;
964 /* Process the packets in the file */
966 /* XXX - for now there is only 1 packet */
967 success = process_file(&cfile, 1, 0);
969 CATCH(OutOfMemoryError) {
973 "Sorry, but TFShark has to terminate now.\n"
975 "Some infos / workarounds can be found at:\n"
976 "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
982 /* We still dump out the results of taps, etc., as we might have
983 read some packets; however, we exit with an error status. */
990 if (cfile.provider.frames != NULL) {
991 free_frame_data_sequence(cfile.provider.frames);
992 cfile.provider.frames = NULL;
995 draw_tap_listeners(TRUE);
996 funnel_dump_all_text_windows();
999 destroy_print_stream(print_stream);
1000 epan_free(cfile.epan);
1006 output_fields_free(output_fields);
1007 output_fields = NULL;
1009 col_cleanup(&cfile.cinfo);
1014 static const nstime_t *
1015 tfshark_get_frame_ts(struct packet_provider_data *prov, guint32 frame_num)
1017 if (prov->ref && prov->ref->num == frame_num)
1018 return &prov->ref->abs_ts;
1020 if (prov->prev_dis && prov->prev_dis->num == frame_num)
1021 return &prov->prev_dis->abs_ts;
1023 if (prov->prev_cap && prov->prev_cap->num == frame_num)
1024 return &prov->prev_cap->abs_ts;
1027 frame_data *fd = frame_data_sequence_find(prov->frames, frame_num);
1029 return (fd) ? &fd->abs_ts : NULL;
1036 no_interface_name(struct packet_provider_data *prov _U_, guint32 interface_id _U_)
1042 tfshark_epan_new(capture_file *cf)
1044 static const struct packet_provider_funcs funcs = {
1045 tfshark_get_frame_ts,
1051 return epan_new(&cf->provider, &funcs);
1055 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
1056 gint64 offset, struct wtap_pkthdr *whdr,
1063 /* The frame number of this packet is one more than the count of
1064 frames in this packet. */
1065 framenum = cf->count + 1;
1067 /* If we're not running a display filter and we're not printing any
1068 packet information, we don't need to do a dissection. This means
1069 that all packets can be marked as 'passed'. */
1072 frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
1074 /* If we're going to print packet information, or we're going to
1075 run a read filter, or display filter, or we're going to process taps, set up to
1076 do a dissection and do so. */
1078 /* If we're running a read filter, prime the epan_dissect_t with that
1081 epan_dissect_prime_with_dfilter(edt, cf->rfcode);
1083 /* This is the first pass, so prime the epan_dissect_t with the
1084 hfids postdissectors want on the first pass. */
1085 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1087 frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
1088 &cf->provider.ref, cf->provider.prev_dis);
1089 if (cf->provider.ref == &fdlocal) {
1090 ref_frame = fdlocal;
1091 cf->provider.ref = &ref_frame;
1094 epan_dissect_file_run(edt, whdr,
1095 file_tvbuff_new(&cf->provider, &fdlocal, pd),
1098 /* Run the read filter if we have one. */
1100 passed = dfilter_apply_edt(cf->rfcode, edt);
1104 frame_data_set_after_dissect(&fdlocal, &cum_bytes);
1105 cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
1107 /* If we're not doing dissection then there won't be any dependent frames.
1108 * More importantly, edt.pi.dependent_frames won't be initialized because
1109 * epan hasn't been initialized.
1112 g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
1117 /* if we don't add it to the frame_data_sequence, clean it up right now
1119 frame_data_destroy(&fdlocal);
1123 epan_dissect_reset(edt);
1129 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
1130 frame_data *fdata, struct wtap_pkthdr *phdr,
1131 Buffer *buf, guint tap_flags)
1136 /* If we're not running a display filter and we're not printing any
1137 packet information, we don't need to do a dissection. This means
1138 that all packets can be marked as 'passed'. */
1141 /* If we're going to print packet information, or we're going to
1142 run a read filter, or we're going to process taps, set up to
1143 do a dissection and do so. */
1146 /* If we're running a display filter, prime the epan_dissect_t with that
1149 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1151 /* This is the first and only pass, so prime the epan_dissect_t
1152 with the hfids postdissectors want on the first pass. */
1153 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1155 col_custom_prime_edt(edt, &cf->cinfo);
1157 /* We only need the columns if either
1158 1) some tap needs the columns
1160 2) we're printing packet info but we're *not* verbose; in verbose
1161 mode, we print the protocol tree, not the protocol summary.
1163 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
1168 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1169 &cf->provider.ref, cf->provider.prev_dis);
1170 if (cf->provider.ref == fdata) {
1172 cf->provider.ref = &ref_frame;
1175 epan_dissect_file_run_with_taps(edt, phdr,
1176 file_tvbuff_new_buffer(&cf->provider, fdata, buf), fdata, cinfo);
1178 /* Run the read/display filter if we have one. */
1180 passed = dfilter_apply_edt(cf->dfcode, edt);
1184 frame_data_set_after_dissect(fdata, &cum_bytes);
1185 /* Process this packet. */
1186 if (print_packet_info) {
1187 /* We're printing packet information; print the information for
1189 print_packet(cf, edt);
1191 /* If we're doing "line-buffering", flush the standard output
1192 after every packet. See the comment above, for the "-l"
1193 option, for an explanation of why we do that. */
1197 if (ferror(stdout)) {
1198 show_print_file_io_error(errno);
1202 cf->provider.prev_dis = fdata;
1204 cf->provider.prev_cap = fdata;
1207 epan_dissect_reset(edt);
1209 return passed || fdata->flags.dependent_of_displayed;
1213 local_wtap_read(capture_file *cf, struct wtap_pkthdr* file_phdr _U_, int *err, gchar **err_info _U_, gint64 *data_offset _U_, guint8** data_buffer)
1215 /* int bytes_read; */
1216 gint64 packet_size = wtap_file_size(cf->provider.wth, err);
1218 *data_buffer = (guint8*)g_malloc((gsize)packet_size);
1219 /* bytes_read =*/ file_read(*data_buffer, (unsigned int)packet_size, cf->provider.wth->fh);
1221 #if 0 /* no more filetap */
1222 if (bytes_read < 0) {
1223 *err = file_error(cf->provider.wth->fh, err_info);
1225 *err = FTAP_ERR_SHORT_READ;
1227 } else if (bytes_read == 0) {
1228 /* Done with file, no error */
1233 /* XXX - SET FRAME SIZE EQUAL TO TOTAL FILE SIZE */
1234 file_phdr->caplen = (guint32)packet_size;
1235 file_phdr->len = (guint32)packet_size;
1238 * Set the packet encapsulation to the file's encapsulation
1239 * value; if that's not WTAP_ENCAP_PER_PACKET, it's the
1240 * right answer (and means that the read routine for this
1241 * capture file type doesn't have to set it), and if it
1242 * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it
1245 wth->phdr.pkt_encap = wth->file_encap;
1247 if (!wth->subtype_read(wth, err, err_info, data_offset)) {
1249 * If we didn't get an error indication, we read
1250 * the last packet. See if there's any deferred
1251 * error, as might, for example, occur if we're
1252 * reading a compressed file, and we got an error
1253 * reading compressed data from the file, but
1254 * got enough compressed data to decompress the
1255 * last packet of the file.
1258 *err = file_error(wth->fh, err_info);
1259 return FALSE; /* failure */
1263 * It makes no sense for the captured data length to be bigger
1264 * than the actual data length.
1266 if (wth->phdr.caplen > wth->phdr.len)
1267 wth->phdr.caplen = wth->phdr.len;
1270 * Make sure that it's not WTAP_ENCAP_PER_PACKET, as that
1271 * probably means the file has that encapsulation type
1272 * but the read routine didn't set this packet's
1273 * encapsulation type.
1275 g_assert(wth->phdr.pkt_encap != WTAP_ENCAP_PER_PACKET);
1278 return TRUE; /* success */
1282 process_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
1286 gchar *err_info = NULL;
1287 gint64 data_offset = 0;
1288 gboolean filtering_tap_listeners;
1291 epan_dissect_t *edt = NULL;
1292 struct wtap_pkthdr file_phdr;
1295 if (print_packet_info) {
1296 if (!write_preamble(cf)) {
1298 show_print_file_io_error(err);
1303 /* Do we have any tap listeners with filters? */
1304 filtering_tap_listeners = have_filtering_tap_listeners();
1306 /* Get the union of the flags for all tap listeners. */
1307 tap_flags = union_of_tap_listener_flags();
1309 wtap_phdr_init(&file_phdr);
1311 /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1312 file_phdr.pkt_encap = 1234;
1314 if (perform_two_pass_analysis) {
1317 /* Allocate a frame_data_sequence for all the frames. */
1318 cf->provider.frames = new_frame_data_sequence();
1320 if (do_dissection) {
1321 gboolean create_proto_tree;
1324 * Determine whether we need to create a protocol tree.
1327 * we're going to apply a read filter;
1329 * a postdissector wants field values or protocols
1330 * on the first pass.
1333 (cf->rfcode != NULL || postdissectors_want_hfids());
1335 /* We're not going to display the protocol tree on this pass,
1336 so it's not going to be "visible". */
1337 edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
1339 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1340 if (process_packet_first_pass(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->provider.wth)*/,
1341 wtap_buf_ptr(cf->provider.wth))) {
1343 /* Stop reading if we have the maximum number of packets;
1344 * When the -c option has not been used, max_packet_count
1345 * starts at 0, which practically means, never stop reading.
1346 * (unless we roll over max_packet_count ?)
1348 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1349 err = 0; /* This is not an error */
1356 epan_dissect_free(edt);
1361 /* Close the sequential I/O side, to free up memory it requires. */
1362 wtap_sequential_close(cf->provider.wth);
1365 /* Allow the protocol dissectors to free up memory that they
1366 * don't need after the sequential run-through of the packets. */
1367 postseq_cleanup_all_protocols();
1369 cf->provider.prev_dis = NULL;
1370 cf->provider.prev_cap = NULL;
1371 ws_buffer_init(&buf, 1500);
1373 if (do_dissection) {
1374 gboolean create_proto_tree;
1377 * Determine whether we need to create a protocol tree.
1380 * we're going to apply a display filter;
1382 * we're going to print the protocol tree;
1384 * one of the tap listeners requires a protocol tree;
1386 * we have custom columns (which require field values, which
1387 * currently requires that we build a protocol tree).
1390 (cf->dfcode || print_details || filtering_tap_listeners ||
1391 (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo));
1393 /* The protocol tree will be "visible", i.e., printed, only if we're
1394 printing packet details, which is true if we're printing stuff
1395 ("print_packet_info" is true) and we're in verbose mode
1396 ("packet_details" is true). */
1397 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1400 for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
1401 fdata = frame_data_sequence_find(cf->provider.frames, framenum);
1403 if (wtap_seek_read(cf->provider.wth, fdata->file_off,
1404 &buf, fdata->cap_len, &err, &err_info)) {
1405 process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1408 if (!process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf,
1415 epan_dissect_free(edt);
1419 ws_buffer_free(&buf);
1424 if (do_dissection) {
1425 gboolean create_proto_tree;
1428 * Determine whether we need to create a protocol tree.
1431 * we're going to apply a read filter;
1433 * we're going to apply a display filter;
1435 * we're going to print the protocol tree;
1437 * one of the tap listeners is going to apply a filter;
1439 * one of the tap listeners requires a protocol tree;
1441 * a postdissector wants field values or protocols
1442 * on the first pass;
1444 * we have custom columns (which require field values, which
1445 * currently requires that we build a protocol tree).
1448 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
1449 (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
1450 have_custom_cols(&cf->cinfo));
1452 /* The protocol tree will be "visible", i.e., printed, only if we're
1453 printing packet details, which is true if we're printing stuff
1454 ("print_packet_info" is true) and we're in verbose mode
1455 ("packet_details" is true). */
1456 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1459 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1463 if (!process_packet_single_pass(cf, edt, data_offset,
1464 &file_phdr/*wtap_phdr(cf->provider.wth)*/,
1465 raw_data, tap_flags))
1468 /* Stop reading if we have the maximum number of packets;
1469 * When the -c option has not been used, max_packet_count
1470 * starts at 0, which practically means, never stop reading.
1471 * (unless we roll over max_packet_count ?)
1473 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1474 err = 0; /* This is not an error */
1480 epan_dissect_free(edt);
1485 wtap_phdr_cleanup(&file_phdr);
1489 * Print a message noting that the read failed somewhere along the line.
1491 * If we're printing packet data, and the standard output and error are
1492 * going to the same place, flush the standard output, so everything
1493 * buffered up is written, and then print a newline to the standard error
1494 * before printing the error message, to separate it from the packet
1495 * data. (Alas, that only works on UN*X; st_dev is meaningless, and
1496 * the _fstat() documentation at Microsoft doesn't indicate whether
1497 * st_ino is even supported.)
1500 if (print_packet_info) {
1501 ws_statb64 stat_stdout, stat_stderr;
1503 if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
1504 if (stat_stdout.st_dev == stat_stderr.st_dev &&
1505 stat_stdout.st_ino == stat_stderr.st_ino) {
1507 fprintf(stderr, "\n");
1515 case FTAP_ERR_UNSUPPORTED:
1516 cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
1517 cf->filename, err_info);
1521 case FTAP_ERR_UNSUPPORTED_ENCAP:
1522 cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
1523 cf->filename, err_info);
1527 case FTAP_ERR_CANT_READ:
1528 cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
1532 case FTAP_ERR_SHORT_READ:
1533 cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
1537 case FTAP_ERR_BAD_FILE:
1538 cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
1539 cf->filename, err_info);
1543 case FTAP_ERR_DECOMPRESS:
1544 cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
1545 "(%s)", cf->filename, err_info);
1549 cmdarg_err("An error occurred while reading the file \"%s\": %s.",
1550 cf->filename, ftap_strerror(err));
1555 if (print_packet_info) {
1556 if (!write_finale()) {
1558 show_print_file_io_error(err);
1564 wtap_close(cf->provider.wth);
1565 cf->provider.wth = NULL;
1571 process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset,
1572 struct wtap_pkthdr *whdr, const guchar *pd,
1579 /* Count this packet. */
1582 /* If we're not running a display filter and we're not printing any
1583 packet information, we don't need to do a dissection. This means
1584 that all packets can be marked as 'passed'. */
1587 frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
1589 /* If we're going to print packet information, or we're going to
1590 run a read filter, or we're going to process taps, set up to
1591 do a dissection and do so. */
1593 /* If we're running a filter, prime the epan_dissect_t with that
1596 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1598 col_custom_prime_edt(edt, &cf->cinfo);
1600 /* We only need the columns if either
1601 1) some tap needs the columns
1603 2) we're printing packet info but we're *not* verbose; in verbose
1604 mode, we print the protocol tree, not the protocol summary.
1606 3) there is a column mapped as an individual field */
1607 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
1612 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
1613 &cf->provider.ref, cf->provider.prev_dis);
1614 if (cf->provider.ref == &fdata) {
1616 cf->provider.ref = &ref_frame;
1619 epan_dissect_file_run_with_taps(edt, whdr,
1620 frame_tvbuff_new(&cf->provider, &fdata, pd),
1623 /* Run the filter if we have it. */
1625 passed = dfilter_apply_edt(cf->dfcode, edt);
1629 frame_data_set_after_dissect(&fdata, &cum_bytes);
1631 /* Process this packet. */
1632 if (print_packet_info) {
1633 /* We're printing packet information; print the information for
1635 print_packet(cf, edt);
1637 /* If we're doing "line-buffering", flush the standard output
1638 after every packet. See the comment above, for the "-l"
1639 option, for an explanation of why we do that. */
1643 if (ferror(stdout)) {
1644 show_print_file_io_error(errno);
1649 /* this must be set after print_packet() [bug #8160] */
1650 prev_dis_frame = fdata;
1651 cf->provider.prev_dis = &prev_dis_frame;
1654 prev_cap_frame = fdata;
1655 cf->provider.prev_cap = &prev_cap_frame;
1658 epan_dissect_reset(edt);
1659 frame_data_destroy(&fdata);
1665 write_preamble(capture_file *cf)
1667 switch (output_action) {
1670 return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
1674 write_pdml_preamble(stdout, cf->filename);
1676 write_psml_preamble(&cf->cinfo, stdout);
1677 return !ferror(stdout);
1680 write_fields_preamble(output_fields, stdout);
1681 return !ferror(stdout);
1684 g_assert_not_reached();
1690 get_line_buf(size_t len)
1692 static char *line_bufp = NULL;
1693 static size_t line_buf_len = 256;
1694 size_t new_line_buf_len;
1696 for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
1697 new_line_buf_len *= 2)
1699 if (line_bufp == NULL) {
1700 line_buf_len = new_line_buf_len;
1701 line_bufp = (char *)g_malloc(line_buf_len + 1);
1703 if (new_line_buf_len > line_buf_len) {
1704 line_buf_len = new_line_buf_len;
1705 line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
1712 put_string(char *dest, const char *str, size_t str_len)
1714 memcpy(dest, str, str_len);
1715 dest[str_len] = '\0';
1719 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1723 for (i = str_len; i < str_with_spaces; i++)
1726 put_string(dest, str, str_len);
1730 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1734 memcpy(dest, str, str_len);
1735 for (i = str_len; i < str_with_spaces; i++)
1738 dest[str_with_spaces] = '\0';
1742 print_columns(capture_file *cf)
1749 col_item_t* col_item;
1751 line_bufp = get_line_buf(256);
1754 for (i = 0; i < cf->cinfo.num_cols; i++) {
1755 col_item = &cf->cinfo.columns[i];
1756 /* Skip columns not marked as visible. */
1757 if (!get_column_visible(i))
1759 switch (col_item->col_fmt) {
1761 column_len = col_len = strlen(col_item->col_data);
1764 line_bufp = get_line_buf(buf_offset + column_len);
1765 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1771 case COL_ABS_YMD_TIME: /* XXX - wider */
1772 case COL_ABS_YDOY_TIME: /* XXX - wider */
1774 case COL_UTC_YMD_TIME: /* XXX - wider */
1775 case COL_UTC_YDOY_TIME: /* XXX - wider */
1776 column_len = col_len = strlen(col_item->col_data);
1777 if (column_len < 10)
1779 line_bufp = get_line_buf(buf_offset + column_len);
1780 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1786 case COL_DEF_DL_SRC:
1787 case COL_RES_DL_SRC:
1788 case COL_UNRES_DL_SRC:
1789 case COL_DEF_NET_SRC:
1790 case COL_RES_NET_SRC:
1791 case COL_UNRES_NET_SRC:
1792 column_len = col_len = strlen(col_item->col_data);
1793 if (column_len < 12)
1795 line_bufp = get_line_buf(buf_offset + column_len);
1796 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1802 case COL_DEF_DL_DST:
1803 case COL_RES_DL_DST:
1804 case COL_UNRES_DL_DST:
1805 case COL_DEF_NET_DST:
1806 case COL_RES_NET_DST:
1807 case COL_UNRES_NET_DST:
1808 column_len = col_len = strlen(col_item->col_data);
1809 if (column_len < 12)
1811 line_bufp = get_line_buf(buf_offset + column_len);
1812 put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1816 column_len = strlen(col_item->col_data);
1817 line_bufp = get_line_buf(buf_offset + column_len);
1818 put_string(line_bufp + buf_offset, col_item->col_data, column_len);
1821 buf_offset += column_len;
1822 if (i != cf->cinfo.num_cols - 1) {
1824 * This isn't the last column, so we need to print a
1825 * separator between this column and the next.
1827 * If we printed a network source and are printing a
1828 * network destination of the same type next, separate
1829 * them with " -> "; if we printed a network destination
1830 * and are printing a network source of the same type
1831 * next, separate them with " <- "; otherwise separate them
1834 * We add enough space to the buffer for " <- " or " -> ",
1835 * even if we're only adding " ".
1837 line_bufp = get_line_buf(buf_offset + 4);
1838 switch (col_item->col_fmt) {
1843 switch (cf->cinfo.columns[i+1].col_fmt) {
1848 put_string(line_bufp + buf_offset, " -> ", 4);
1853 put_string(line_bufp + buf_offset, " ", 1);
1859 case COL_DEF_DL_SRC:
1860 case COL_RES_DL_SRC:
1861 case COL_UNRES_DL_SRC:
1862 switch (cf->cinfo.columns[i+1].col_fmt) {
1864 case COL_DEF_DL_DST:
1865 case COL_RES_DL_DST:
1866 case COL_UNRES_DL_DST:
1867 put_string(line_bufp + buf_offset, " -> ", 4);
1872 put_string(line_bufp + buf_offset, " ", 1);
1878 case COL_DEF_NET_SRC:
1879 case COL_RES_NET_SRC:
1880 case COL_UNRES_NET_SRC:
1881 switch (cf->cinfo.columns[i+1].col_fmt) {
1883 case COL_DEF_NET_DST:
1884 case COL_RES_NET_DST:
1885 case COL_UNRES_NET_DST:
1886 put_string(line_bufp + buf_offset, " -> ", 4);
1891 put_string(line_bufp + buf_offset, " ", 1);
1900 switch (cf->cinfo.columns[i+1].col_fmt) {
1905 put_string(line_bufp + buf_offset, " <- ", 4);
1910 put_string(line_bufp + buf_offset, " ", 1);
1916 case COL_DEF_DL_DST:
1917 case COL_RES_DL_DST:
1918 case COL_UNRES_DL_DST:
1919 switch (cf->cinfo.columns[i+1].col_fmt) {
1921 case COL_DEF_DL_SRC:
1922 case COL_RES_DL_SRC:
1923 case COL_UNRES_DL_SRC:
1924 put_string(line_bufp + buf_offset, " <- ", 4);
1929 put_string(line_bufp + buf_offset, " ", 1);
1935 case COL_DEF_NET_DST:
1936 case COL_RES_NET_DST:
1937 case COL_UNRES_NET_DST:
1938 switch (cf->cinfo.columns[i+1].col_fmt) {
1940 case COL_DEF_NET_SRC:
1941 case COL_RES_NET_SRC:
1942 case COL_UNRES_NET_SRC:
1943 put_string(line_bufp + buf_offset, " <- ", 4);
1948 put_string(line_bufp + buf_offset, " ", 1);
1955 put_string(line_bufp + buf_offset, " ", 1);
1961 return print_line(print_stream, 0, line_bufp);
1965 print_packet(capture_file *cf, epan_dissect_t *edt)
1967 if (print_summary || output_fields_has_cols(output_fields)) {
1968 /* Just fill in the columns. */
1969 epan_dissect_fill_in_columns(edt, FALSE, TRUE);
1971 if (print_summary) {
1972 /* Now print them. */
1973 switch (output_action) {
1976 if (!print_columns(cf))
1981 write_psml_columns(edt, stdout, FALSE);
1982 return !ferror(stdout);
1983 case WRITE_FIELDS: /*No non-verbose "fields" format */
1984 g_assert_not_reached();
1989 if (print_details) {
1990 /* Print the information in the protocol tree. */
1991 switch (output_action) {
1994 if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
1995 print_hex, edt, output_only_tables, print_stream))
1998 if (!print_line(print_stream, 0, separator))
2004 write_pdml_proto_tree(NULL, NULL, PF_NONE, edt, &cf->cinfo, stdout, FALSE);
2006 return !ferror(stdout);
2008 write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
2010 return !ferror(stdout);
2014 if (print_summary || print_details) {
2015 if (!print_line(print_stream, 0, ""))
2018 if (!print_hex_data(print_stream, edt))
2020 if (!print_line(print_stream, 0, separator))
2029 switch (output_action) {
2032 return print_finale(print_stream);
2036 write_pdml_finale(stdout);
2038 write_psml_finale(stdout);
2039 return !ferror(stdout);
2042 write_fields_finale(output_fields, stdout);
2043 return !ferror(stdout);
2046 g_assert_not_reached();
2052 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
2055 char err_msg[2048+1];
2057 /* The open isn't implemented yet. Fill in the information for this file. */
2059 /* Create new epan session for dissection. */
2060 epan_free(cf->epan);
2061 cf->epan = tfshark_epan_new(cf);
2063 cf->provider.wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2064 cf->f_datalen = 0; /* not used, but set it anyway */
2066 /* Set the file name because we need it to set the follow stream filter.
2067 XXX - is that still true? We need it for other reasons, though,
2069 cf->filename = g_strdup(fname);
2071 /* Indicate whether it's a permanent or temporary file. */
2072 cf->is_tempfile = is_tempfile;
2074 /* No user changes yet. */
2075 cf->unsaved_changes = FALSE;
2077 cf->cd_t = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2078 cf->open_type = type;
2080 cf->drops_known = FALSE;
2082 cf->snap = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2083 nstime_set_zero(&cf->elapsed_time);
2084 cf->provider.ref = NULL;
2085 cf->provider.prev_dis = NULL;
2086 cf->provider.prev_cap = NULL;
2088 cf->state = FILE_READ_IN_PROGRESS;
2093 g_snprintf(err_msg, sizeof err_msg,
2094 cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
2095 cmdarg_err("%s", err_msg);
2100 show_print_file_io_error(int err)
2105 cmdarg_err("Not all the packets could be printed because there is "
2106 "no space left on the file system.");
2111 cmdarg_err("Not all the packets could be printed because you are "
2112 "too close to, or over your disk quota.");
2117 cmdarg_err("An error occurred while printing packets: %s.",
2124 cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
2128 /* static char errmsg_errno[1024+1]; */
2132 /* Wiretap error. */
2135 case FTAP_ERR_NOT_REGULAR_FILE:
2136 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
2139 case FTAP_ERR_RANDOM_OPEN_PIPE:
2140 /* Seen only when opening a capture file for reading. */
2141 errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
2144 case FTAP_ERR_FILE_UNKNOWN_FORMAT:
2145 /* Seen only when opening a capture file for reading. */
2146 errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
2149 case FTAP_ERR_UNSUPPORTED:
2150 /* Seen only when opening a capture file for reading. */
2151 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2152 "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
2155 errmsg = errmsg_errno;
2158 case FTAP_ERR_CANT_WRITE_TO_PIPE:
2159 /* Seen only when opening a capture file for writing. */
2160 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2161 "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
2162 "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
2163 errmsg = errmsg_errno;
2166 case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
2167 /* Seen only when opening a capture file for writing. */
2168 errmsg = "TFShark doesn't support writing capture files in that format.";
2171 case FTAP_ERR_UNSUPPORTED_ENCAP:
2173 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2174 "TFShark can't save this capture as a \"%s\" file.",
2175 ftap_file_type_subtype_short_string(file_type));
2177 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2178 "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
2182 errmsg = errmsg_errno;
2185 case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
2187 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2188 "TFShark can't save this capture as a \"%s\" file.",
2189 ftap_file_type_subtype_short_string(file_type));
2190 errmsg = errmsg_errno;
2192 errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
2195 case FTAP_ERR_BAD_FILE:
2196 /* Seen only when opening a capture file for reading. */
2197 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2198 "The file \"%%s\" appears to be damaged or corrupt.\n"
2201 errmsg = errmsg_errno;
2204 case FTAP_ERR_CANT_OPEN:
2206 errmsg = "The file \"%s\" could not be created for some unknown reason.";
2208 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
2211 case FTAP_ERR_SHORT_READ:
2212 errmsg = "The file \"%s\" appears to have been cut short"
2213 " in the middle of a packet or other data.";
2216 case FTAP_ERR_SHORT_WRITE:
2217 errmsg = "A full header couldn't be written to the file \"%s\".";
2220 case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
2221 errmsg = "This file type cannot be written as a compressed file.";
2224 case FTAP_ERR_DECOMPRESS:
2225 /* Seen only when opening a capture file for reading. */
2226 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2227 "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
2230 errmsg = errmsg_errno;
2234 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2235 "The file \"%%s\" could not be %s: %s.",
2236 for_writing ? "created" : "opened",
2237 ftap_strerror(err));
2238 errmsg = errmsg_errno;
2243 errmsg = file_open_error_message(err, for_writing);
2248 * General errors and warnings are reported with an console message
2252 failure_warning_message(const char *msg_format, va_list ap)
2254 fprintf(stderr, "tfshark: ");
2255 vfprintf(stderr, msg_format, ap);
2256 fprintf(stderr, "\n");
2260 * Open/create errors are reported with an console message in TFShark.
2263 open_failure_message(const char *filename, int err, gboolean for_writing)
2265 fprintf(stderr, "tfshark: ");
2266 fprintf(stderr, file_open_error_message(err, for_writing), filename);
2267 fprintf(stderr, "\n");
2271 * Read errors are reported with an console message in TFShark.
2274 read_failure_message(const char *filename, int err)
2276 cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
2277 filename, g_strerror(err));
2281 * Write errors are reported with an console message in TFShark.
2284 write_failure_message(const char *filename, int err)
2286 cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
2287 filename, g_strerror(err));
2291 * Report additional information for an error in command-line arguments.
2294 failure_message_cont(const char *msg_format, va_list ap)
2296 vfprintf(stderr, msg_format, ap);
2297 fprintf(stderr, "\n");
2301 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2306 * indent-tabs-mode: nil
2309 * vi: set shiftwidth=2 tabstop=8 expandtab:
2310 * :indentSize=2:tabSize=8:noTabs=true: