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-or-later
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>
67 #include <wiretap/wtap-int.h>
68 #include <wiretap/file_wrappers.h>
71 #include <wsutil/unicode-utils.h>
75 #include <epan/funnel.h>
78 #include <wsutil/plugins.h>
81 #define INVALID_OPTION 1
82 #define NO_FILE_SPECIFIED 1
84 #define INVALID_FILTER 2
89 static guint32 cum_bytes;
90 static frame_data ref_frame;
91 static frame_data prev_dis_frame;
92 static frame_data prev_cap_frame;
94 static gboolean prefs_loaded = FALSE;
96 static gboolean perform_two_pass_analysis;
99 * The way the packet decode is to be written.
102 WRITE_TEXT, /* summary or detail text */
103 WRITE_XML, /* PDML or PSML */
104 WRITE_FIELDS /* User defined list of fields */
105 /* Add CSV and the like here */
108 static output_action_e output_action;
109 static gboolean do_dissection; /* TRUE if we have to dissect each packet */
110 static gboolean print_packet_info; /* TRUE if we're to print packet information */
111 static gint print_summary = -1; /* TRUE if we're to print packet summary information */
112 static gboolean print_details; /* TRUE if we're to print packet details information */
113 static gboolean print_hex; /* TRUE if we're to print hex/ascci information */
114 static gboolean line_buffered;
115 static gboolean really_quiet = FALSE;
117 static print_format_e print_format = PR_FMT_TEXT;
118 static print_stream_t *print_stream;
120 static output_fields_t* output_fields = NULL;
122 /* The line separator used between packets, changeable via the -S option */
123 static const char *separator = "";
125 static gboolean process_file(capture_file *, int, gint64);
126 static gboolean process_packet_single_pass(capture_file *cf,
127 epan_dissect_t *edt, gint64 offset, wtap_rec *rec,
128 const guchar *pd, guint tap_flags);
129 static void show_print_file_io_error(int err);
130 static gboolean write_preamble(capture_file *cf);
131 static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
132 static gboolean write_finale(void);
133 static const char *cf_open_error_message(int err, gchar *err_info,
134 gboolean for_writing, int file_type);
136 static void failure_warning_message(const char *msg_format, va_list ap);
137 static void open_failure_message(const char *filename, int err,
138 gboolean for_writing);
139 static void read_failure_message(const char *filename, int err);
140 static void write_failure_message(const char *filename, int err);
141 static void failure_message_cont(const char *msg_format, va_list ap);
143 static GHashTable *output_only_tables = NULL;
147 const char *sstr; /* The short string */
148 const char *lstr; /* The long string */
152 string_compare(gconstpointer a, gconstpointer b)
154 return strcmp(((const struct string_elem *)a)->sstr,
155 ((const struct string_elem *)b)->sstr);
159 string_elem_print(gpointer data, gpointer not_used _U_)
161 fprintf(stderr, " %s - %s\n",
162 ((struct string_elem *)data)->sstr,
163 ((struct string_elem *)data)->lstr);
168 print_usage(FILE *output)
170 fprintf(output, "\n");
171 fprintf(output, "Usage: tfshark [options] ...\n");
172 fprintf(output, "\n");
174 /*fprintf(output, "\n");*/
175 fprintf(output, "Input file:\n");
176 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin)\n");
178 fprintf(output, "\n");
179 fprintf(output, "Processing:\n");
180 fprintf(output, " -2 perform a two-pass analysis\n");
181 fprintf(output, " -R <read filter> packet Read filter in Wireshark display filter syntax\n");
182 fprintf(output, " (requires -2)\n");
183 fprintf(output, " -Y <display filter> packet displaY filter in Wireshark display filter\n");
184 fprintf(output, " syntax\n");
185 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
186 fprintf(output, " \"Decode As\", see the man page for details\n");
187 fprintf(output, " Example: tcp.port==8888,http\n");
189 /*fprintf(output, "\n");*/
190 fprintf(output, "Output:\n");
191 fprintf(output, " -C <config profile> start with specified configuration profile\n");
192 fprintf(output, " -V add output of packet tree (Packet Details)\n");
193 fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
194 fprintf(output, " separated\n");
195 fprintf(output, " -S <separator> the line separator to print between packets\n");
196 fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
197 fprintf(output, " -T pdml|ps|psml|text|fields\n");
198 fprintf(output, " format of text output (def: text)\n");
199 fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
200 fprintf(output, " _ws.col.Info)\n");
201 fprintf(output, " this option can be repeated to print multiple fields\n");
202 fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
203 fprintf(output, " header=y|n switch headers on and off\n");
204 fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
205 fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
206 fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
207 fprintf(output, " aggregator\n");
208 fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
209 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
210 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
211 fprintf(output, " -l flush standard output after each packet\n");
212 fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
213 fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
214 fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
215 fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
217 fprintf(output, "\n");
218 fprintf(output, "Miscellaneous:\n");
219 fprintf(output, " -h display this help and exit\n");
220 fprintf(output, " -v display version info and exit\n");
221 fprintf(output, " -o <name>:<value> ... override preference setting\n");
222 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
223 fprintf(output, " -G [report] dump one of several available reports and exit\n");
224 fprintf(output, " default report=\"fields\"\n");
225 fprintf(output, " use \"-G ?\" for more help\n");
229 glossary_option_help(void)
235 fprintf(output, "TFShark (Wireshark) %s\n", get_ws_vcs_version_info());
237 fprintf(output, "\n");
238 fprintf(output, "Usage: tfshark -G [report]\n");
239 fprintf(output, "\n");
240 fprintf(output, "Glossary table reports:\n");
241 fprintf(output, " -G column-formats dump column format codes and exit\n");
242 fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
243 fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
244 fprintf(output, " -G fields dump fields glossary and exit\n");
245 fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
246 fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
247 fprintf(output, " -G plugins dump installed plugins and exit\n");
248 fprintf(output, " -G protocols dump protocols in registration database and exit\n");
249 fprintf(output, " -G values dump value, range, true/false strings and exit\n");
250 fprintf(output, "\n");
251 fprintf(output, "Preference reports:\n");
252 fprintf(output, " -G currentprefs dump current preferences and exit\n");
253 fprintf(output, " -G defaultprefs dump default preferences and exit\n");
254 fprintf(output, "\n");
258 tfshark_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
259 const gchar *message, gpointer user_data)
261 /* ignore log message, if log_level isn't interesting based
262 upon the console log preferences.
263 If the preferences haven't been loaded yet, display the
266 The default console_log_level preference value is such that only
267 ERROR, CRITICAL and WARNING level messages are processed;
268 MESSAGE, INFO and DEBUG level messages are ignored.
270 XXX: Aug 07, 2009: Prior tshark g_log code was hardwired to process only
271 ERROR and CRITICAL level messages so the current code is a behavioral
272 change. The current behavior is the same as in Wireshark.
274 if (prefs_loaded && (log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0) {
278 g_log_default_handler(log_domain, log_level, message, user_data);
283 print_current_user(void) {
284 gchar *cur_user, *cur_group;
286 if (started_with_special_privs()) {
287 cur_user = get_cur_username();
288 cur_group = get_cur_groupname();
289 fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
290 cur_user, cur_group);
293 if (running_with_special_privs()) {
294 fprintf(stderr, " This could be dangerous.");
296 fprintf(stderr, "\n");
301 get_tfshark_runtime_version_info(GString *str)
303 /* stuff used by libwireshark */
304 epan_get_runtime_version_info(str);
308 main(int argc, char *argv[])
310 GString *comp_info_str;
311 GString *runtime_info_str;
312 char *init_progfile_dir_error;
314 static const struct option long_options[] = {
315 {"help", no_argument, NULL, 'h'},
316 {"version", no_argument, NULL, 'v'},
319 gboolean arg_error = FALSE;
322 volatile gboolean success;
323 volatile int exit_status = 0;
324 gboolean quiet = FALSE;
325 gchar *volatile cf_name = NULL;
326 gchar *rfilter = NULL;
327 gchar *dfilter = NULL;
328 dfilter_t *rfcode = NULL;
329 dfilter_t *dfcode = NULL;
333 gchar *output_only = NULL;
336 * The leading + ensures that getopt_long() does not permute the argv[]
339 * We have to make sure that the first getopt_long() preserves the content
340 * of argv[] for the subsequent getopt_long() call.
342 * We use getopt_long() in both cases to ensure that we're using a routine
343 * whose permutation behavior we can control in the same fashion on all
344 * platforms, and so that, if we ever need to process a long argument before
345 * doing further initialization, we can do so.
347 * Glibc and Solaris libc document that a leading + disables permutation
348 * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
349 * and macOS don't document it, but do so anyway.
351 * We do *not* use a leading - because the behavior of a leading - is
352 * platform-dependent.
354 #define OPTSTRING "+2C:d:e:E:hK:lo:O:qQr:R:S:t:T:u:vVxX:Y:z:"
356 static const char optstring[] = OPTSTRING;
358 /* Set the C-language locale to the native environment. */
359 setlocale(LC_ALL, "");
361 cmdarg_err_init(failure_warning_message, failure_message_cont);
364 arg_list_utf_16to8(argc, argv);
365 create_app_running_mutex();
366 #if !GLIB_CHECK_VERSION(2,31,0)
372 * Get credential information for later use, and drop privileges
373 * before doing anything else.
374 * Let the user know if anything happened.
376 init_process_policies();
377 relinquish_special_privs_perm();
378 print_current_user();
381 * Attempt to get the pathname of the directory containing the
384 init_progfile_dir_error = init_progfile_dir(argv[0], main);
385 if (init_progfile_dir_error != NULL) {
387 "tfshark: Can't get pathname of directory containing the tfshark program: %s.\n",
388 init_progfile_dir_error);
389 g_free(init_progfile_dir_error);
392 initialize_funnel_ops();
394 /* Get the compile-time version information string */
395 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
397 /* Get the run-time version information string */
398 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
400 /* Add it to the information to be reported on a crash. */
401 ws_add_crash_info("TFShark (Wireshark) %s\n"
406 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
407 g_string_free(comp_info_str, TRUE);
408 g_string_free(runtime_info_str, TRUE);
411 * In order to have the -X opts assigned before the wslua machine starts
412 * we need to call getopts before epan_init() gets called.
414 * In order to handle, for example, -o options, we also need to call it
415 * *after* epan_init() gets called, so that the dissectors have had a
416 * chance to register their preferences.
418 * XXX - can we do this all with one getopt_long() call, saving the
419 * arguments we can't handle until after initializing libwireshark,
420 * and then process them after initializing libwireshark?
424 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
426 case 'C': /* Configuration Profile */
427 if (profile_exists (optarg, FALSE)) {
428 set_profile_name (optarg);
430 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
434 case 'O': /* Only output these protocols */
435 output_only = g_strdup(optarg);
437 case 'V': /* Verbose */
438 print_details = TRUE;
439 print_packet_info = TRUE;
441 case 'x': /* Print packet data in hex (and ASCII) */
443 /* The user asked for hex output, so let's ensure they get it,
444 * even if they're writing to a file.
446 print_packet_info = TRUE;
457 * Print packet summary information is the default, unless either -V or -x
458 * were specified. Note that this is new behavior, which
459 * allows for the possibility of printing only hex/ascii output without
460 * necessarily requiring that either the summary or details be printed too.
462 if (print_summary == -1)
463 print_summary = (print_details || print_hex) ? FALSE : TRUE;
465 /** Send All g_log messages to our own handler **/
469 G_LOG_LEVEL_CRITICAL|
474 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
476 g_log_set_handler(NULL,
477 (GLogLevelFlags)log_flags,
478 tfshark_log_handler, NULL /* user_data */);
479 g_log_set_handler(LOG_DOMAIN_MAIN,
480 (GLogLevelFlags)log_flags,
481 tfshark_log_handler, NULL /* user_data */);
483 init_report_message(failure_warning_message, failure_warning_message,
484 open_failure_message, read_failure_message,
485 write_failure_message);
487 timestamp_set_type(TS_RELATIVE);
488 timestamp_set_precision(TS_PREC_AUTO);
489 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
493 /* Register all dissectors; we must do this before checking for the
494 "-G" flag, as the "-G" flag dumps information registered by the
495 dissectors, and we must do it before we read the preferences, in
496 case any dissectors register preferences. */
497 if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
499 exit_status = INIT_ERROR;
503 /* Register all tap listeners; we do this before we parse the arguments,
504 as the "-z" argument can specify a registered tap. */
506 /* we register the plugin taps before the other taps because
507 stats_tree taps plugins will be registered as tap listeners
508 by stats_tree_stat.c and need to registered before that */
510 /* XXX Disable tap registration for now until we can get tfshark set up with
511 * its own set of taps and the necessary registration function etc.
513 register_all_plugin_tap_listeners();
515 register_all_tap_listeners();
518 /* If invoked with the "-G" flag, we dump out information based on
519 the argument to the "-G" flag; if no argument is specified,
520 for backwards compatibility we dump out a glossary of display
523 XXX - we do this here, for now, to support "-G" with no arguments.
524 If none of our build or other processes uses "-G" with no arguments,
525 we can just process it with the other arguments. */
526 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
527 proto_initialize_all_prefixes();
530 proto_registrar_dump_fields();
532 if (strcmp(argv[2], "column-formats") == 0)
533 column_dump_column_formats();
534 else if (strcmp(argv[2], "currentprefs") == 0) {
535 epan_load_settings();
538 else if (strcmp(argv[2], "decodes") == 0)
539 dissector_dump_decodes();
540 else if (strcmp(argv[2], "defaultprefs") == 0)
542 else if (strcmp(argv[2], "dissector-tables") == 0)
543 dissector_dump_dissector_tables();
544 else if (strcmp(argv[2], "fields") == 0)
545 proto_registrar_dump_fields();
546 else if (strcmp(argv[2], "ftypes") == 0)
547 proto_registrar_dump_ftypes();
548 else if (strcmp(argv[2], "heuristic-decodes") == 0)
549 dissector_dump_heur_decodes();
550 else if (strcmp(argv[2], "plugins") == 0) {
555 wslua_plugins_dump_all();
558 else if (strcmp(argv[2], "protocols") == 0)
559 proto_registrar_dump_protocols();
560 else if (strcmp(argv[2], "values") == 0)
561 proto_registrar_dump_values();
562 else if (strcmp(argv[2], "?") == 0)
563 glossary_option_help();
564 else if (strcmp(argv[2], "-?") == 0)
565 glossary_option_help();
567 cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
568 exit_status = INVALID_OPTION;
575 /* Load libwireshark settings from the current profile. */
576 prefs_p = epan_load_settings();
579 cap_file_init(&cfile);
581 /* Print format defaults to this. */
582 print_format = PR_FMT_TEXT;
584 output_fields = output_fields_new();
587 * To reset the options parser, set optreset to 1 on platforms that
588 * have optreset (documented in *BSD and macOS, apparently present but
589 * not documented in Solaris - the Illumos repository seems to
590 * suggest that the first Solaris getopt_long(), at least as of 2004,
591 * was based on the NetBSD one, it had optreset) and set optind to 1,
592 * and set optind to 0 otherwise (documented as working in the GNU
593 * getopt_long(). Setting optind to 0 didn't originally work in the
594 * NetBSD one, but that was added later - we don't want to depend on
595 * it if we have optreset).
597 * Also reset opterr to 1, so that error messages are printed by
608 /* Now get our args */
609 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
611 case '2': /* Perform two pass analysis */
612 perform_two_pass_analysis = TRUE;
615 /* already processed; just ignore it now */
619 output_fields_add(output_fields, optarg);
623 if (!output_fields_set_option(output_fields, optarg)) {
624 cmdarg_err("\"%s\" is not a valid field output option=value pair.", optarg);
625 output_fields_list_options(stderr);
626 exit_status = INVALID_OPTION;
631 case 'h': /* Print help and exit */
632 printf("TFShark (Wireshark) %s\n"
633 "Dump and analyze network traffic.\n"
634 "See https://www.wireshark.org for more information.\n",
635 get_ws_vcs_version_info());
639 case 'l': /* "Line-buffer" standard output */
640 /* The ANSI C standard does not appear to *require* that a line-buffered
641 stream be flushed to the host environment whenever a newline is
642 written, it just says that, on such a stream, characters "are
643 intended to be transmitted to or from the host environment as a
644 block when a new-line character is encountered".
646 The Visual C++ 6.0 C implementation doesn't do what is intended;
647 even if you set a stream to be line-buffered, it still doesn't
648 flush the buffer at the end of every line.
650 The whole reason for the "-l" flag in either tcpdump or TShark
651 is to allow the output of a live capture to be piped to a program
652 or script and to have that script see the information for the
653 packet as soon as it's printed, rather than having to wait until
654 a standard I/O buffer fills up.
656 So, if the "-l" flag is specified, we flush the standard output
657 at the end of a packet. This will do the right thing if we're
658 printing packet summary lines, and, as we print the entire protocol
659 tree for a single packet without waiting for anything to happen,
660 it should be as good as line-buffered mode if we're printing
661 protocol trees - arguably even better, as it may do fewer
663 line_buffered = TRUE;
665 case 'o': /* Override preference from command line */
669 switch (prefs_set_pref(optarg, &errmsg)) {
674 case PREFS_SET_SYNTAX_ERR:
675 cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg,
676 errmsg ? ": " : "", errmsg ? errmsg : "");
681 case PREFS_SET_NO_SUCH_PREF:
682 case PREFS_SET_OBSOLETE:
683 cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
684 exit_status = INVALID_OPTION;
690 case 'q': /* Quiet */
693 case 'Q': /* Really quiet */
697 case 'r': /* Read capture file x */
698 cf_name = g_strdup(optarg);
700 case 'R': /* Read file filter */
703 case 'S': /* Set the line Separator to be printed between packets */
704 separator = g_strdup(optarg);
706 case 'T': /* printing Type */
707 if (strcmp(optarg, "text") == 0) {
708 output_action = WRITE_TEXT;
709 print_format = PR_FMT_TEXT;
710 } else if (strcmp(optarg, "ps") == 0) {
711 output_action = WRITE_TEXT;
712 print_format = PR_FMT_PS;
713 } else if (strcmp(optarg, "pdml") == 0) {
714 output_action = WRITE_XML;
715 print_details = TRUE; /* Need details */
716 print_summary = FALSE; /* Don't allow summary */
717 } else if (strcmp(optarg, "psml") == 0) {
718 output_action = WRITE_XML;
719 print_details = FALSE; /* Don't allow details */
720 print_summary = TRUE; /* Need summary */
721 } else if (strcmp(optarg, "fields") == 0) {
722 output_action = WRITE_FIELDS;
723 print_details = TRUE; /* Need full tree info */
724 print_summary = FALSE; /* Don't allow summary */
726 cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg); /* x */
727 cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
728 "\t specified by the -E option.\n"
729 "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
730 "\t details of a decoded packet. This information is equivalent to\n"
731 "\t the packet details printed with the -V flag.\n"
732 "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
733 "\t the packets, or a multi-line view of the details of each of\n"
734 "\t the packets, depending on whether the -V flag was specified.\n"
735 "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
736 "\t summary information of a decoded packet. This information is\n"
737 "\t equivalent to the information shown in the one-line summary\n"
738 "\t printed by default.\n"
739 "\t\"text\" Text of a human-readable one-line summary of each of the\n"
740 "\t packets, or a multi-line view of the details of each of the\n"
741 "\t packets, depending on whether the -V flag was specified.\n"
742 "\t This is the default.");
743 exit_status = INVALID_OPTION;
747 case 'v': /* Show version and exit */
748 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
749 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
750 show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
751 g_string_free(comp_info_str, TRUE);
752 g_string_free(runtime_info_str, TRUE);
754 case 'O': /* Only output these protocols */
755 /* already processed; just ignore it now */
757 case 'V': /* Verbose */
758 /* already processed; just ignore it now */
760 case 'x': /* Print packet data in hex (and ASCII) */
761 /* already processed; just ignore it now */
764 /* already processed; just ignore it now */
770 /* We won't call the init function for the stat this soon
771 as it would disallow MATE's fields (which are registered
772 by the preferences set callback) from being used as
773 part of a tap filter. Instead, we just add the argument
774 to a list of stat arguments. */
775 if (strcmp("help", optarg) == 0) {
776 fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
777 list_stat_cmd_args();
780 if (!process_stat_cmd_arg(optarg)) {
781 cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
782 list_stat_cmd_args();
783 exit_status = INVALID_OPTION;
787 case 'd': /* Decode as rule */
788 case 'K': /* Kerberos keytab file */
789 case 't': /* Time stamp type */
790 case 'u': /* Seconds type */
791 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
792 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
793 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
794 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
795 if (!dissect_opts_handle_opt(opt, optarg)) {
796 exit_status = INVALID_OPTION;
801 case '?': /* Bad flag - print usage message */
803 exit_status = INVALID_OPTION;
809 /* If we specified output fields, but not the output field type... */
810 if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
811 cmdarg_err("Output fields were specified with \"-e\", "
812 "but \"-Tfields\" was not specified.");
814 } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
815 cmdarg_err("\"-Tfields\" was specified, but no fields were "
816 "specified with \"-e\".");
818 exit_status = INVALID_OPTION;
822 /* We require a -r flag specifying a file to read. */
823 if (cf_name == NULL) {
824 cmdarg_err("A file to read must be specified with \"-r\".");
825 exit_status = NO_FILE_SPECIFIED;
829 /* If no display filter has been specified, and there are still command-
830 line arguments, treat them as the tokens of a display filter. */
832 if (dfilter != NULL) {
833 cmdarg_err("Display filters were specified both with \"-d\" "
834 "and with additional command-line arguments.");
835 exit_status = INVALID_OPTION;
838 dfilter = get_args_as_string(argc, argv, optind);
841 /* if "-q" wasn't specified, we should print packet information */
843 print_packet_info = TRUE;
847 exit_status = INVALID_OPTION;
852 if (output_action != WRITE_TEXT) {
853 cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
854 exit_status = INVALID_OPTION;
859 if (output_only != NULL) {
862 if (!print_details) {
863 cmdarg_err("-O requires -V");
864 exit_status = INVALID_OPTION;
868 output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
869 for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
870 g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
874 if (rfilter != NULL && !perform_two_pass_analysis) {
875 cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
876 exit_status = INVALID_OPTION;
880 /* Notify all registered modules that have had any of their preferences
881 changed either from one of the preferences file or from the command
882 line that their preferences have changed. */
886 * Enabled and disabled protocols and heuristic dissectors as per
887 * command-line options.
889 if (!setup_enabled_and_disabled_protocols()) {
890 exit_status = INVALID_OPTION;
894 /* Build the column format array */
895 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
897 if (rfilter != NULL) {
898 if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
899 cmdarg_err("%s", err_msg);
901 exit_status = INVALID_FILTER;
905 cfile.rfcode = rfcode;
907 if (dfilter != NULL) {
908 if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
909 cmdarg_err("%s", err_msg);
911 exit_status = INVALID_FILTER;
915 cfile.dfcode = dfcode;
917 if (print_packet_info) {
918 /* If we're printing as text or PostScript, we have
919 to create a print stream. */
920 if (output_action == WRITE_TEXT) {
921 switch (print_format) {
924 print_stream = print_stream_text_stdio_new(stdout);
928 print_stream = print_stream_ps_stdio_new(stdout);
932 g_assert_not_reached();
937 /* We have to dissect each packet if:
939 we're printing information about each packet;
941 we're using a read filter on the packets;
943 we're using a display filter on the packets;
945 we're using any taps that need dissection. */
946 do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
952 /* TODO: if tfshark is ever changed to give the user a choice of which
953 open_routine reader to use, then the following needs to change. */
954 if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
955 exit_status = OPEN_ERROR;
959 /* Start statistics taps; we do so after successfully opening the
960 capture file, so we know we have something to compute stats
961 on, and after registering all dissectors, so that MATE will
962 have registered its field array so we can have a tap filter
963 with one of MATE's late-registered fields as part of the
965 start_requested_stats();
967 /* Process the packets in the file */
969 /* XXX - for now there is only 1 packet */
970 success = process_file(&cfile, 1, 0);
972 CATCH(OutOfMemoryError) {
976 "Sorry, but TFShark has to terminate now.\n"
978 "Some infos / workarounds can be found at:\n"
979 "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
985 /* We still dump out the results of taps, etc., as we might have
986 read some packets; however, we exit with an error status. */
992 if (cfile.provider.frames != NULL) {
993 free_frame_data_sequence(cfile.provider.frames);
994 cfile.provider.frames = NULL;
997 draw_tap_listeners(TRUE);
998 funnel_dump_all_text_windows();
1001 destroy_print_stream(print_stream);
1002 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, wtap_rec *rec,
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, rec, 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, rec,
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, wtap_rec *rec,
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, rec,
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, wtap_rec *file_rec _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_rec->rec_header.packet_header.caplen = (guint32)packet_size;
1235 file_rec->rec_header.packet_header.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->rec.rec_header.packet_header.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->rec.rec_header.packet_header.caplen > wth->rec.rec_header.packet_header.len)
1267 wth->rec.rec_header.packet_header.caplen = wth->rec.rec_header.packet_header.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->rec.rec_header.packet_header.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;
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_rec_init(&file_rec);
1311 /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1312 file_rec.rec_header.packet_header.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_rec, &err, &err_info, &data_offset, &raw_data)) {
1340 if (process_packet_first_pass(cf, edt, data_offset, &file_rec/*wtap_get_rec(cf->provider.wth)*/,
1341 wtap_get_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->rec, &buf, tap_flags);
1408 if (!process_packet_second_pass(cf, edt, fdata, &cf->rec, &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_rec, &err, &err_info, &data_offset, &raw_data)) {
1463 if (!process_packet_single_pass(cf, edt, data_offset,
1464 &file_rec/*wtap_get_rec(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_rec_cleanup(&file_rec);
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 wtap_rec *rec, 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, rec, 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, rec,
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: