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
83 #define INVALID_FILTER 2
88 static guint32 cum_bytes;
89 static frame_data ref_frame;
90 static frame_data prev_dis_frame;
91 static frame_data prev_cap_frame;
93 static gboolean prefs_loaded = FALSE;
95 static gboolean perform_two_pass_analysis;
98 * The way the packet decode is to be written.
101 WRITE_TEXT, /* summary or detail text */
102 WRITE_XML, /* PDML or PSML */
103 WRITE_FIELDS /* User defined list of fields */
104 /* Add CSV and the like here */
107 static output_action_e output_action;
108 static gboolean do_dissection; /* TRUE if we have to dissect each packet */
109 static gboolean print_packet_info; /* TRUE if we're to print packet information */
110 static gint print_summary = -1; /* TRUE if we're to print packet summary information */
111 static gboolean print_details; /* TRUE if we're to print packet details information */
112 static gboolean print_hex; /* TRUE if we're to print hex/ascci information */
113 static gboolean line_buffered;
114 static gboolean really_quiet = FALSE;
116 static print_format_e print_format = PR_FMT_TEXT;
117 static print_stream_t *print_stream;
119 static output_fields_t* output_fields = NULL;
121 /* The line separator used between packets, changeable via the -S option */
122 static const char *separator = "";
124 static gboolean process_file(capture_file *, int, gint64);
125 static gboolean process_packet_single_pass(capture_file *cf,
126 epan_dissect_t *edt, gint64 offset, wtap_rec *rec,
127 const guchar *pd, guint tap_flags);
128 static void show_print_file_io_error(int err);
129 static gboolean write_preamble(capture_file *cf);
130 static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
131 static gboolean write_finale(void);
132 static const char *cf_open_error_message(int err, gchar *err_info,
133 gboolean for_writing, int file_type);
135 static void failure_warning_message(const char *msg_format, va_list ap);
136 static void open_failure_message(const char *filename, int err,
137 gboolean for_writing);
138 static void read_failure_message(const char *filename, int err);
139 static void write_failure_message(const char *filename, int err);
140 static void failure_message_cont(const char *msg_format, va_list ap);
142 static GHashTable *output_only_tables = NULL;
146 const char *sstr; /* The short string */
147 const char *lstr; /* The long string */
151 string_compare(gconstpointer a, gconstpointer b)
153 return strcmp(((const struct string_elem *)a)->sstr,
154 ((const struct string_elem *)b)->sstr);
158 string_elem_print(gpointer data, gpointer not_used _U_)
160 fprintf(stderr, " %s - %s\n",
161 ((struct string_elem *)data)->sstr,
162 ((struct string_elem *)data)->lstr);
167 print_usage(FILE *output)
169 fprintf(output, "\n");
170 fprintf(output, "Usage: tfshark [options] ...\n");
171 fprintf(output, "\n");
173 /*fprintf(output, "\n");*/
174 fprintf(output, "Input file:\n");
175 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin)\n");
177 fprintf(output, "\n");
178 fprintf(output, "Processing:\n");
179 fprintf(output, " -2 perform a two-pass analysis\n");
180 fprintf(output, " -R <read filter> packet Read filter in Wireshark display filter syntax\n");
181 fprintf(output, " (requires -2)\n");
182 fprintf(output, " -Y <display filter> packet displaY filter in Wireshark display filter\n");
183 fprintf(output, " syntax\n");
184 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
185 fprintf(output, " \"Decode As\", see the man page for details\n");
186 fprintf(output, " Example: tcp.port==8888,http\n");
188 /*fprintf(output, "\n");*/
189 fprintf(output, "Output:\n");
190 fprintf(output, " -C <config profile> start with specified configuration profile\n");
191 fprintf(output, " -V add output of packet tree (Packet Details)\n");
192 fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
193 fprintf(output, " separated\n");
194 fprintf(output, " -S <separator> the line separator to print between packets\n");
195 fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
196 fprintf(output, " -T pdml|ps|psml|text|fields\n");
197 fprintf(output, " format of text output (def: text)\n");
198 fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
199 fprintf(output, " _ws.col.Info)\n");
200 fprintf(output, " this option can be repeated to print multiple fields\n");
201 fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
202 fprintf(output, " header=y|n switch headers on and off\n");
203 fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
204 fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
205 fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
206 fprintf(output, " aggregator\n");
207 fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
208 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
209 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
210 fprintf(output, " -l flush standard output after each packet\n");
211 fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
212 fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
213 fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
214 fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
216 fprintf(output, "\n");
217 fprintf(output, "Miscellaneous:\n");
218 fprintf(output, " -h display this help and exit\n");
219 fprintf(output, " -v display version info and exit\n");
220 fprintf(output, " -o <name>:<value> ... override preference setting\n");
221 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
222 fprintf(output, " -G [report] dump one of several available reports and exit\n");
223 fprintf(output, " default report=\"fields\"\n");
224 fprintf(output, " use \"-G ?\" for more help\n");
228 glossary_option_help(void)
234 fprintf(output, "TFShark (Wireshark) %s\n", get_ws_vcs_version_info());
236 fprintf(output, "\n");
237 fprintf(output, "Usage: tfshark -G [report]\n");
238 fprintf(output, "\n");
239 fprintf(output, "Glossary table reports:\n");
240 fprintf(output, " -G column-formats dump column format codes and exit\n");
241 fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
242 fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
243 fprintf(output, " -G fields dump fields glossary and exit\n");
244 fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
245 fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
246 fprintf(output, " -G plugins dump installed plugins and exit\n");
247 fprintf(output, " -G protocols dump protocols in registration database and exit\n");
248 fprintf(output, " -G values dump value, range, true/false strings and exit\n");
249 fprintf(output, "\n");
250 fprintf(output, "Preference reports:\n");
251 fprintf(output, " -G currentprefs dump current preferences and exit\n");
252 fprintf(output, " -G defaultprefs dump default preferences and exit\n");
253 fprintf(output, "\n");
257 tfshark_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
258 const gchar *message, gpointer user_data)
260 /* ignore log message, if log_level isn't interesting based
261 upon the console log preferences.
262 If the preferences haven't been loaded yet, display the
265 The default console_log_level preference value is such that only
266 ERROR, CRITICAL and WARNING level messages are processed;
267 MESSAGE, INFO and DEBUG level messages are ignored.
269 XXX: Aug 07, 2009: Prior tshark g_log code was hardwired to process only
270 ERROR and CRITICAL level messages so the current code is a behavioral
271 change. The current behavior is the same as in Wireshark.
273 if (prefs_loaded && (log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0) {
277 g_log_default_handler(log_domain, log_level, message, user_data);
282 print_current_user(void) {
283 gchar *cur_user, *cur_group;
285 if (started_with_special_privs()) {
286 cur_user = get_cur_username();
287 cur_group = get_cur_groupname();
288 fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
289 cur_user, cur_group);
292 if (running_with_special_privs()) {
293 fprintf(stderr, " This could be dangerous.");
295 fprintf(stderr, "\n");
300 get_tfshark_runtime_version_info(GString *str)
302 /* stuff used by libwireshark */
303 epan_get_runtime_version_info(str);
307 main(int argc, char *argv[])
309 GString *comp_info_str;
310 GString *runtime_info_str;
311 char *init_progfile_dir_error;
313 static const struct option long_options[] = {
314 {"help", no_argument, NULL, 'h'},
315 {"version", no_argument, NULL, 'v'},
318 gboolean arg_error = FALSE;
321 volatile gboolean success;
322 volatile int exit_status = 0;
323 gboolean quiet = FALSE;
324 gchar *volatile cf_name = NULL;
325 gchar *rfilter = NULL;
326 gchar *dfilter = NULL;
327 dfilter_t *rfcode = NULL;
328 dfilter_t *dfcode = NULL;
332 gchar *output_only = NULL;
335 * The leading + ensures that getopt_long() does not permute the argv[]
338 * We have to make sure that the first getopt_long() preserves the content
339 * of argv[] for the subsequent getopt_long() call.
341 * We use getopt_long() in both cases to ensure that we're using a routine
342 * whose permutation behavior we can control in the same fashion on all
343 * platforms, and so that, if we ever need to process a long argument before
344 * doing further initialization, we can do so.
346 * Glibc and Solaris libc document that a leading + disables permutation
347 * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
348 * and macOS don't document it, but do so anyway.
350 * We do *not* use a leading - because the behavior of a leading - is
351 * platform-dependent.
353 #define OPTSTRING "+2C:d:e:E:hK:lo:O:qQr:R:S:t:T:u:vVxX:Y:z:"
355 static const char optstring[] = OPTSTRING;
357 /* Set the C-language locale to the native environment. */
358 setlocale(LC_ALL, "");
360 cmdarg_err_init(failure_warning_message, failure_message_cont);
363 arg_list_utf_16to8(argc, argv);
364 create_app_running_mutex();
365 #if !GLIB_CHECK_VERSION(2,31,0)
371 * Get credential information for later use, and drop privileges
372 * before doing anything else.
373 * Let the user know if anything happened.
375 init_process_policies();
376 relinquish_special_privs_perm();
377 print_current_user();
380 * Attempt to get the pathname of the directory containing the
383 init_progfile_dir_error = init_progfile_dir(argv[0], main);
384 if (init_progfile_dir_error != NULL) {
386 "tfshark: Can't get pathname of directory containing the tfshark program: %s.\n",
387 init_progfile_dir_error);
388 g_free(init_progfile_dir_error);
391 initialize_funnel_ops();
393 /* Get the compile-time version information string */
394 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
396 /* Get the run-time version information string */
397 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
399 /* Add it to the information to be reported on a crash. */
400 ws_add_crash_info("TFShark (Wireshark) %s\n"
405 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
406 g_string_free(comp_info_str, TRUE);
407 g_string_free(runtime_info_str, TRUE);
410 * In order to have the -X opts assigned before the wslua machine starts
411 * we need to call getopts before epan_init() gets called.
413 * In order to handle, for example, -o options, we also need to call it
414 * *after* epan_init() gets called, so that the dissectors have had a
415 * chance to register their preferences.
417 * XXX - can we do this all with one getopt_long() call, saving the
418 * arguments we can't handle until after initializing libwireshark,
419 * and then process them after initializing libwireshark?
423 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
425 case 'C': /* Configuration Profile */
426 if (profile_exists (optarg, FALSE)) {
427 set_profile_name (optarg);
429 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
433 case 'O': /* Only output these protocols */
434 output_only = g_strdup(optarg);
436 case 'V': /* Verbose */
437 print_details = TRUE;
438 print_packet_info = TRUE;
440 case 'x': /* Print packet data in hex (and ASCII) */
442 /* The user asked for hex output, so let's ensure they get it,
443 * even if they're writing to a file.
445 print_packet_info = TRUE;
456 * Print packet summary information is the default, unless either -V or -x
457 * were specified. Note that this is new behavior, which
458 * allows for the possibility of printing only hex/ascii output without
459 * necessarily requiring that either the summary or details be printed too.
461 if (print_summary == -1)
462 print_summary = (print_details || print_hex) ? FALSE : TRUE;
464 /** Send All g_log messages to our own handler **/
468 G_LOG_LEVEL_CRITICAL|
473 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
475 g_log_set_handler(NULL,
476 (GLogLevelFlags)log_flags,
477 tfshark_log_handler, NULL /* user_data */);
478 g_log_set_handler(LOG_DOMAIN_MAIN,
479 (GLogLevelFlags)log_flags,
480 tfshark_log_handler, NULL /* user_data */);
482 init_report_message(failure_warning_message, failure_warning_message,
483 open_failure_message, read_failure_message,
484 write_failure_message);
486 timestamp_set_type(TS_RELATIVE);
487 timestamp_set_precision(TS_PREC_AUTO);
488 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
492 /* Register all dissectors; we must do this before checking for the
493 "-G" flag, as the "-G" flag dumps information registered by the
494 dissectors, and we must do it before we read the preferences, in
495 case any dissectors register preferences. */
496 if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
498 exit_status = INIT_ERROR;
502 /* Register all tap listeners; we do this before we parse the arguments,
503 as the "-z" argument can specify a registered tap. */
505 /* we register the plugin taps before the other taps because
506 stats_tree taps plugins will be registered as tap listeners
507 by stats_tree_stat.c and need to registered before that */
509 /* XXX Disable tap registration for now until we can get tfshark set up with
510 * its own set of taps and the necessary registration function etc.
512 register_all_plugin_tap_listeners();
514 register_all_tap_listeners();
517 /* If invoked with the "-G" flag, we dump out information based on
518 the argument to the "-G" flag; if no argument is specified,
519 for backwards compatibility we dump out a glossary of display
522 XXX - we do this here, for now, to support "-G" with no arguments.
523 If none of our build or other processes uses "-G" with no arguments,
524 we can just process it with the other arguments. */
525 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
526 proto_initialize_all_prefixes();
529 proto_registrar_dump_fields();
531 if (strcmp(argv[2], "column-formats") == 0)
532 column_dump_column_formats();
533 else if (strcmp(argv[2], "currentprefs") == 0) {
534 epan_load_settings();
537 else if (strcmp(argv[2], "decodes") == 0)
538 dissector_dump_decodes();
539 else if (strcmp(argv[2], "defaultprefs") == 0)
541 else if (strcmp(argv[2], "dissector-tables") == 0)
542 dissector_dump_dissector_tables();
543 else if (strcmp(argv[2], "fields") == 0)
544 proto_registrar_dump_fields();
545 else if (strcmp(argv[2], "ftypes") == 0)
546 proto_registrar_dump_ftypes();
547 else if (strcmp(argv[2], "heuristic-decodes") == 0)
548 dissector_dump_heur_decodes();
549 else if (strcmp(argv[2], "plugins") == 0) {
554 wslua_plugins_dump_all();
557 else if (strcmp(argv[2], "protocols") == 0)
558 proto_registrar_dump_protocols();
559 else if (strcmp(argv[2], "values") == 0)
560 proto_registrar_dump_values();
561 else if (strcmp(argv[2], "?") == 0)
562 glossary_option_help();
563 else if (strcmp(argv[2], "-?") == 0)
564 glossary_option_help();
566 cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
567 exit_status = INVALID_OPTION;
574 /* Load libwireshark settings from the current profile. */
575 prefs_p = epan_load_settings();
578 cap_file_init(&cfile);
580 /* Print format defaults to this. */
581 print_format = PR_FMT_TEXT;
583 output_fields = output_fields_new();
586 * To reset the options parser, set optreset to 1 on platforms that
587 * have optreset (documented in *BSD and macOS, apparently present but
588 * not documented in Solaris - the Illumos repository seems to
589 * suggest that the first Solaris getopt_long(), at least as of 2004,
590 * was based on the NetBSD one, it had optreset) and set optind to 1,
591 * and set optind to 0 otherwise (documented as working in the GNU
592 * getopt_long(). Setting optind to 0 didn't originally work in the
593 * NetBSD one, but that was added later - we don't want to depend on
594 * it if we have optreset).
596 * Also reset opterr to 1, so that error messages are printed by
607 /* Now get our args */
608 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
610 case '2': /* Perform two pass analysis */
611 perform_two_pass_analysis = TRUE;
614 /* already processed; just ignore it now */
618 output_fields_add(output_fields, optarg);
622 if (!output_fields_set_option(output_fields, optarg)) {
623 cmdarg_err("\"%s\" is not a valid field output option=value pair.", optarg);
624 output_fields_list_options(stderr);
625 exit_status = INVALID_OPTION;
630 case 'h': /* Print help and exit */
631 printf("TFShark (Wireshark) %s\n"
632 "Dump and analyze network traffic.\n"
633 "See https://www.wireshark.org for more information.\n",
634 get_ws_vcs_version_info());
638 case 'l': /* "Line-buffer" standard output */
639 /* The ANSI C standard does not appear to *require* that a line-buffered
640 stream be flushed to the host environment whenever a newline is
641 written, it just says that, on such a stream, characters "are
642 intended to be transmitted to or from the host environment as a
643 block when a new-line character is encountered".
645 The Visual C++ 6.0 C implementation doesn't do what is intended;
646 even if you set a stream to be line-buffered, it still doesn't
647 flush the buffer at the end of every line.
649 The whole reason for the "-l" flag in either tcpdump or TShark
650 is to allow the output of a live capture to be piped to a program
651 or script and to have that script see the information for the
652 packet as soon as it's printed, rather than having to wait until
653 a standard I/O buffer fills up.
655 So, if the "-l" flag is specified, we flush the standard output
656 at the end of a packet. This will do the right thing if we're
657 printing packet summary lines, and, as we print the entire protocol
658 tree for a single packet without waiting for anything to happen,
659 it should be as good as line-buffered mode if we're printing
660 protocol trees - arguably even better, as it may do fewer
662 line_buffered = TRUE;
664 case 'o': /* Override preference from command line */
668 switch (prefs_set_pref(optarg, &errmsg)) {
673 case PREFS_SET_SYNTAX_ERR:
674 cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg,
675 errmsg ? ": " : "", errmsg ? errmsg : "");
680 case PREFS_SET_NO_SUCH_PREF:
681 case PREFS_SET_OBSOLETE:
682 cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
683 exit_status = INVALID_OPTION;
689 case 'q': /* Quiet */
692 case 'Q': /* Really quiet */
696 case 'r': /* Read capture file x */
697 cf_name = g_strdup(optarg);
699 case 'R': /* Read file filter */
702 case 'S': /* Set the line Separator to be printed between packets */
703 separator = g_strdup(optarg);
705 case 'T': /* printing Type */
706 if (strcmp(optarg, "text") == 0) {
707 output_action = WRITE_TEXT;
708 print_format = PR_FMT_TEXT;
709 } else if (strcmp(optarg, "ps") == 0) {
710 output_action = WRITE_TEXT;
711 print_format = PR_FMT_PS;
712 } else if (strcmp(optarg, "pdml") == 0) {
713 output_action = WRITE_XML;
714 print_details = TRUE; /* Need details */
715 print_summary = FALSE; /* Don't allow summary */
716 } else if (strcmp(optarg, "psml") == 0) {
717 output_action = WRITE_XML;
718 print_details = FALSE; /* Don't allow details */
719 print_summary = TRUE; /* Need summary */
720 } else if (strcmp(optarg, "fields") == 0) {
721 output_action = WRITE_FIELDS;
722 print_details = TRUE; /* Need full tree info */
723 print_summary = FALSE; /* Don't allow summary */
725 cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg); /* x */
726 cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
727 "\t specified by the -E option.\n"
728 "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
729 "\t details of a decoded packet. This information is equivalent to\n"
730 "\t the packet details printed with the -V flag.\n"
731 "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
732 "\t the packets, or a multi-line view of the details of each of\n"
733 "\t the packets, depending on whether the -V flag was specified.\n"
734 "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
735 "\t summary information of a decoded packet. This information is\n"
736 "\t equivalent to the information shown in the one-line summary\n"
737 "\t printed by default.\n"
738 "\t\"text\" Text of a human-readable one-line summary of each of the\n"
739 "\t packets, or a multi-line view of the details of each of the\n"
740 "\t packets, depending on whether the -V flag was specified.\n"
741 "\t This is the default.");
742 exit_status = INVALID_OPTION;
746 case 'v': /* Show version and exit */
747 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
748 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
749 show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
750 g_string_free(comp_info_str, TRUE);
751 g_string_free(runtime_info_str, TRUE);
753 case 'O': /* Only output these protocols */
754 /* already processed; just ignore it now */
756 case 'V': /* Verbose */
757 /* already processed; just ignore it now */
759 case 'x': /* Print packet data in hex (and ASCII) */
760 /* already processed; just ignore it now */
763 /* already processed; just ignore it now */
769 /* We won't call the init function for the stat this soon
770 as it would disallow MATE's fields (which are registered
771 by the preferences set callback) from being used as
772 part of a tap filter. Instead, we just add the argument
773 to a list of stat arguments. */
774 if (strcmp("help", optarg) == 0) {
775 fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
776 list_stat_cmd_args();
779 if (!process_stat_cmd_arg(optarg)) {
780 cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
781 list_stat_cmd_args();
782 exit_status = INVALID_OPTION;
786 case 'd': /* Decode as rule */
787 case 'K': /* Kerberos keytab file */
788 case 't': /* Time stamp type */
789 case 'u': /* Seconds type */
790 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
791 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
792 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
793 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
794 if (!dissect_opts_handle_opt(opt, optarg)) {
795 exit_status = INVALID_OPTION;
800 case '?': /* Bad flag - print usage message */
802 exit_status = INVALID_OPTION;
808 /* If we specified output fields, but not the output field type... */
809 if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
810 cmdarg_err("Output fields were specified with \"-e\", "
811 "but \"-Tfields\" was not specified.");
813 } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
814 cmdarg_err("\"-Tfields\" was specified, but no fields were "
815 "specified with \"-e\".");
817 exit_status = INVALID_OPTION;
821 /* If no capture filter or display filter has been specified, and there are
822 still command-line arguments, treat them as the tokens of a capture
823 filter (if no "-r" flag was specified) or a display filter (if a "-r"
824 flag was specified. */
826 if (cf_name != NULL) {
827 if (dfilter != NULL) {
828 cmdarg_err("Display filters were specified both with \"-d\" "
829 "and with additional command-line arguments.");
830 exit_status = INVALID_OPTION;
833 dfilter = get_args_as_string(argc, argv, optind);
837 /* if "-q" wasn't specified, we should print packet information */
839 print_packet_info = TRUE;
843 exit_status = INVALID_OPTION;
848 if (output_action != WRITE_TEXT) {
849 cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
850 exit_status = INVALID_OPTION;
855 if (output_only != NULL) {
858 if (!print_details) {
859 cmdarg_err("-O requires -V");
860 exit_status = INVALID_OPTION;
864 output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
865 for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
866 g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
870 if (rfilter != NULL && !perform_two_pass_analysis) {
871 cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
872 exit_status = INVALID_OPTION;
876 /* Notify all registered modules that have had any of their preferences
877 changed either from one of the preferences file or from the command
878 line that their preferences have changed. */
881 /* At this point MATE will have registered its field array so we can
882 have a tap filter with one of MATE's late-registered fields as part
883 of the filter. We can now process all the "-z" arguments. */
884 start_requested_stats();
887 * Enabled and disabled protocols and heuristic dissectors as per
888 * command-line options.
890 if (!setup_enabled_and_disabled_protocols()) {
891 exit_status = INVALID_OPTION;
895 /* Build the column format array */
896 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
898 if (rfilter != NULL) {
899 if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
900 cmdarg_err("%s", err_msg);
902 exit_status = INVALID_FILTER;
906 cfile.rfcode = rfcode;
908 if (dfilter != NULL) {
909 if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
910 cmdarg_err("%s", err_msg);
912 exit_status = INVALID_FILTER;
916 cfile.dfcode = dfcode;
918 if (print_packet_info) {
919 /* If we're printing as text or PostScript, we have
920 to create a print stream. */
921 if (output_action == WRITE_TEXT) {
922 switch (print_format) {
925 print_stream = print_stream_text_stdio_new(stdout);
929 print_stream = print_stream_ps_stdio_new(stdout);
933 g_assert_not_reached();
938 /* We have to dissect each packet if:
940 we're printing information about each packet;
942 we're using a read filter on the packets;
944 we're using a display filter on the packets;
946 we're using any taps that need dissection. */
947 do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
951 * We're reading a capture file.
954 /* TODO: if tfshark is ever changed to give the user a choice of which
955 open_routine reader to use, then the following needs to change. */
956 if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
957 exit_status = OPEN_ERROR;
961 /* Process the packets in the file */
963 /* XXX - for now there is only 1 packet */
964 success = process_file(&cfile, 1, 0);
966 CATCH(OutOfMemoryError) {
970 "Sorry, but TFShark has to terminate now.\n"
972 "Some infos / workarounds can be found at:\n"
973 "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
979 /* We still dump out the results of taps, etc., as we might have
980 read some packets; however, we exit with an error status. */
987 if (cfile.provider.frames != NULL) {
988 free_frame_data_sequence(cfile.provider.frames);
989 cfile.provider.frames = NULL;
992 draw_tap_listeners(TRUE);
993 funnel_dump_all_text_windows();
996 destroy_print_stream(print_stream);
997 epan_free(cfile.epan);
1001 output_fields_free(output_fields);
1002 output_fields = NULL;
1004 col_cleanup(&cfile.cinfo);
1009 static const nstime_t *
1010 tfshark_get_frame_ts(struct packet_provider_data *prov, guint32 frame_num)
1012 if (prov->ref && prov->ref->num == frame_num)
1013 return &prov->ref->abs_ts;
1015 if (prov->prev_dis && prov->prev_dis->num == frame_num)
1016 return &prov->prev_dis->abs_ts;
1018 if (prov->prev_cap && prov->prev_cap->num == frame_num)
1019 return &prov->prev_cap->abs_ts;
1022 frame_data *fd = frame_data_sequence_find(prov->frames, frame_num);
1024 return (fd) ? &fd->abs_ts : NULL;
1031 no_interface_name(struct packet_provider_data *prov _U_, guint32 interface_id _U_)
1037 tfshark_epan_new(capture_file *cf)
1039 static const struct packet_provider_funcs funcs = {
1040 tfshark_get_frame_ts,
1046 return epan_new(&cf->provider, &funcs);
1050 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
1051 gint64 offset, wtap_rec *rec,
1058 /* The frame number of this packet is one more than the count of
1059 frames in this packet. */
1060 framenum = cf->count + 1;
1062 /* If we're not running a display filter and we're not printing any
1063 packet information, we don't need to do a dissection. This means
1064 that all packets can be marked as 'passed'. */
1067 frame_data_init(&fdlocal, framenum, rec, offset, cum_bytes);
1069 /* If we're going to print packet information, or we're going to
1070 run a read filter, or display filter, or we're going to process taps, set up to
1071 do a dissection and do so. */
1073 /* If we're running a read filter, prime the epan_dissect_t with that
1076 epan_dissect_prime_with_dfilter(edt, cf->rfcode);
1078 /* This is the first pass, so prime the epan_dissect_t with the
1079 hfids postdissectors want on the first pass. */
1080 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1082 frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
1083 &cf->provider.ref, cf->provider.prev_dis);
1084 if (cf->provider.ref == &fdlocal) {
1085 ref_frame = fdlocal;
1086 cf->provider.ref = &ref_frame;
1089 epan_dissect_file_run(edt, rec,
1090 file_tvbuff_new(&cf->provider, &fdlocal, pd),
1093 /* Run the read filter if we have one. */
1095 passed = dfilter_apply_edt(cf->rfcode, edt);
1099 frame_data_set_after_dissect(&fdlocal, &cum_bytes);
1100 cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
1102 /* If we're not doing dissection then there won't be any dependent frames.
1103 * More importantly, edt.pi.dependent_frames won't be initialized because
1104 * epan hasn't been initialized.
1107 g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
1112 /* if we don't add it to the frame_data_sequence, clean it up right now
1114 frame_data_destroy(&fdlocal);
1118 epan_dissect_reset(edt);
1124 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
1125 frame_data *fdata, wtap_rec *rec,
1126 Buffer *buf, guint tap_flags)
1131 /* If we're not running a display filter and we're not printing any
1132 packet information, we don't need to do a dissection. This means
1133 that all packets can be marked as 'passed'. */
1136 /* If we're going to print packet information, or we're going to
1137 run a read filter, or we're going to process taps, set up to
1138 do a dissection and do so. */
1141 /* If we're running a display filter, prime the epan_dissect_t with that
1144 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1146 /* This is the first and only pass, so prime the epan_dissect_t
1147 with the hfids postdissectors want on the first pass. */
1148 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1150 col_custom_prime_edt(edt, &cf->cinfo);
1152 /* We only need the columns if either
1153 1) some tap needs the columns
1155 2) we're printing packet info but we're *not* verbose; in verbose
1156 mode, we print the protocol tree, not the protocol summary.
1158 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
1163 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1164 &cf->provider.ref, cf->provider.prev_dis);
1165 if (cf->provider.ref == fdata) {
1167 cf->provider.ref = &ref_frame;
1170 epan_dissect_file_run_with_taps(edt, rec,
1171 file_tvbuff_new_buffer(&cf->provider, fdata, buf), fdata, cinfo);
1173 /* Run the read/display filter if we have one. */
1175 passed = dfilter_apply_edt(cf->dfcode, edt);
1179 frame_data_set_after_dissect(fdata, &cum_bytes);
1180 /* Process this packet. */
1181 if (print_packet_info) {
1182 /* We're printing packet information; print the information for
1184 print_packet(cf, edt);
1186 /* If we're doing "line-buffering", flush the standard output
1187 after every packet. See the comment above, for the "-l"
1188 option, for an explanation of why we do that. */
1192 if (ferror(stdout)) {
1193 show_print_file_io_error(errno);
1197 cf->provider.prev_dis = fdata;
1199 cf->provider.prev_cap = fdata;
1202 epan_dissect_reset(edt);
1204 return passed || fdata->flags.dependent_of_displayed;
1208 local_wtap_read(capture_file *cf, wtap_rec *file_rec _U_, int *err, gchar **err_info _U_, gint64 *data_offset _U_, guint8** data_buffer)
1210 /* int bytes_read; */
1211 gint64 packet_size = wtap_file_size(cf->provider.wth, err);
1213 *data_buffer = (guint8*)g_malloc((gsize)packet_size);
1214 /* bytes_read =*/ file_read(*data_buffer, (unsigned int)packet_size, cf->provider.wth->fh);
1216 #if 0 /* no more filetap */
1217 if (bytes_read < 0) {
1218 *err = file_error(cf->provider.wth->fh, err_info);
1220 *err = FTAP_ERR_SHORT_READ;
1222 } else if (bytes_read == 0) {
1223 /* Done with file, no error */
1228 /* XXX - SET FRAME SIZE EQUAL TO TOTAL FILE SIZE */
1229 file_rec->rec_header.packet_header.caplen = (guint32)packet_size;
1230 file_rec->rec_header.packet_header.len = (guint32)packet_size;
1233 * Set the packet encapsulation to the file's encapsulation
1234 * value; if that's not WTAP_ENCAP_PER_PACKET, it's the
1235 * right answer (and means that the read routine for this
1236 * capture file type doesn't have to set it), and if it
1237 * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it
1240 wth->rec.rec_header.packet_header.pkt_encap = wth->file_encap;
1242 if (!wth->subtype_read(wth, err, err_info, data_offset)) {
1244 * If we didn't get an error indication, we read
1245 * the last packet. See if there's any deferred
1246 * error, as might, for example, occur if we're
1247 * reading a compressed file, and we got an error
1248 * reading compressed data from the file, but
1249 * got enough compressed data to decompress the
1250 * last packet of the file.
1253 *err = file_error(wth->fh, err_info);
1254 return FALSE; /* failure */
1258 * It makes no sense for the captured data length to be bigger
1259 * than the actual data length.
1261 if (wth->rec.rec_header.packet_header.caplen > wth->rec.rec_header.packet_header.len)
1262 wth->rec.rec_header.packet_header.caplen = wth->rec.rec_header.packet_header.len;
1265 * Make sure that it's not WTAP_ENCAP_PER_PACKET, as that
1266 * probably means the file has that encapsulation type
1267 * but the read routine didn't set this packet's
1268 * encapsulation type.
1270 g_assert(wth->rec.rec_header.packet_header.pkt_encap != WTAP_ENCAP_PER_PACKET);
1273 return TRUE; /* success */
1277 process_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
1281 gchar *err_info = NULL;
1282 gint64 data_offset = 0;
1283 gboolean filtering_tap_listeners;
1286 epan_dissect_t *edt = NULL;
1290 if (print_packet_info) {
1291 if (!write_preamble(cf)) {
1293 show_print_file_io_error(err);
1298 /* Do we have any tap listeners with filters? */
1299 filtering_tap_listeners = have_filtering_tap_listeners();
1301 /* Get the union of the flags for all tap listeners. */
1302 tap_flags = union_of_tap_listener_flags();
1304 wtap_rec_init(&file_rec);
1306 /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1307 file_rec.rec_header.packet_header.pkt_encap = 1234;
1309 if (perform_two_pass_analysis) {
1312 /* Allocate a frame_data_sequence for all the frames. */
1313 cf->provider.frames = new_frame_data_sequence();
1315 if (do_dissection) {
1316 gboolean create_proto_tree;
1319 * Determine whether we need to create a protocol tree.
1322 * we're going to apply a read filter;
1324 * a postdissector wants field values or protocols
1325 * on the first pass.
1328 (cf->rfcode != NULL || postdissectors_want_hfids());
1330 /* We're not going to display the protocol tree on this pass,
1331 so it's not going to be "visible". */
1332 edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
1334 while (local_wtap_read(cf, &file_rec, &err, &err_info, &data_offset, &raw_data)) {
1335 if (process_packet_first_pass(cf, edt, data_offset, &file_rec/*wtap_get_rec(cf->provider.wth)*/,
1336 wtap_get_buf_ptr(cf->provider.wth))) {
1338 /* Stop reading if we have the maximum number of packets;
1339 * When the -c option has not been used, max_packet_count
1340 * starts at 0, which practically means, never stop reading.
1341 * (unless we roll over max_packet_count ?)
1343 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1344 err = 0; /* This is not an error */
1351 epan_dissect_free(edt);
1356 /* Close the sequential I/O side, to free up memory it requires. */
1357 wtap_sequential_close(cf->provider.wth);
1360 /* Allow the protocol dissectors to free up memory that they
1361 * don't need after the sequential run-through of the packets. */
1362 postseq_cleanup_all_protocols();
1364 cf->provider.prev_dis = NULL;
1365 cf->provider.prev_cap = NULL;
1366 ws_buffer_init(&buf, 1500);
1368 if (do_dissection) {
1369 gboolean create_proto_tree;
1372 * Determine whether we need to create a protocol tree.
1375 * we're going to apply a display filter;
1377 * we're going to print the protocol tree;
1379 * one of the tap listeners requires a protocol tree;
1381 * we have custom columns (which require field values, which
1382 * currently requires that we build a protocol tree).
1385 (cf->dfcode || print_details || filtering_tap_listeners ||
1386 (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo));
1388 /* The protocol tree will be "visible", i.e., printed, only if we're
1389 printing packet details, which is true if we're printing stuff
1390 ("print_packet_info" is true) and we're in verbose mode
1391 ("packet_details" is true). */
1392 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1395 for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
1396 fdata = frame_data_sequence_find(cf->provider.frames, framenum);
1398 if (wtap_seek_read(cf->provider.wth, fdata->file_off,
1399 &buf, fdata->cap_len, &err, &err_info)) {
1400 process_packet_second_pass(cf, edt, fdata, &cf->rec, &buf, tap_flags);
1403 if (!process_packet_second_pass(cf, edt, fdata, &cf->rec, &buf,
1410 epan_dissect_free(edt);
1414 ws_buffer_free(&buf);
1419 if (do_dissection) {
1420 gboolean create_proto_tree;
1423 * Determine whether we need to create a protocol tree.
1426 * we're going to apply a read filter;
1428 * we're going to apply a display filter;
1430 * we're going to print the protocol tree;
1432 * one of the tap listeners is going to apply a filter;
1434 * one of the tap listeners requires a protocol tree;
1436 * a postdissector wants field values or protocols
1437 * on the first pass;
1439 * we have custom columns (which require field values, which
1440 * currently requires that we build a protocol tree).
1443 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
1444 (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
1445 have_custom_cols(&cf->cinfo));
1447 /* The protocol tree will be "visible", i.e., printed, only if we're
1448 printing packet details, which is true if we're printing stuff
1449 ("print_packet_info" is true) and we're in verbose mode
1450 ("packet_details" is true). */
1451 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1454 while (local_wtap_read(cf, &file_rec, &err, &err_info, &data_offset, &raw_data)) {
1458 if (!process_packet_single_pass(cf, edt, data_offset,
1459 &file_rec/*wtap_get_rec(cf->provider.wth)*/,
1460 raw_data, tap_flags))
1463 /* Stop reading if we have the maximum number of packets;
1464 * When the -c option has not been used, max_packet_count
1465 * starts at 0, which practically means, never stop reading.
1466 * (unless we roll over max_packet_count ?)
1468 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1469 err = 0; /* This is not an error */
1475 epan_dissect_free(edt);
1480 wtap_rec_cleanup(&file_rec);
1484 * Print a message noting that the read failed somewhere along the line.
1486 * If we're printing packet data, and the standard output and error are
1487 * going to the same place, flush the standard output, so everything
1488 * buffered up is written, and then print a newline to the standard error
1489 * before printing the error message, to separate it from the packet
1490 * data. (Alas, that only works on UN*X; st_dev is meaningless, and
1491 * the _fstat() documentation at Microsoft doesn't indicate whether
1492 * st_ino is even supported.)
1495 if (print_packet_info) {
1496 ws_statb64 stat_stdout, stat_stderr;
1498 if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
1499 if (stat_stdout.st_dev == stat_stderr.st_dev &&
1500 stat_stdout.st_ino == stat_stderr.st_ino) {
1502 fprintf(stderr, "\n");
1510 case FTAP_ERR_UNSUPPORTED:
1511 cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
1512 cf->filename, err_info);
1516 case FTAP_ERR_UNSUPPORTED_ENCAP:
1517 cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
1518 cf->filename, err_info);
1522 case FTAP_ERR_CANT_READ:
1523 cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
1527 case FTAP_ERR_SHORT_READ:
1528 cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
1532 case FTAP_ERR_BAD_FILE:
1533 cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
1534 cf->filename, err_info);
1538 case FTAP_ERR_DECOMPRESS:
1539 cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
1540 "(%s)", cf->filename, err_info);
1544 cmdarg_err("An error occurred while reading the file \"%s\": %s.",
1545 cf->filename, ftap_strerror(err));
1550 if (print_packet_info) {
1551 if (!write_finale()) {
1553 show_print_file_io_error(err);
1559 wtap_close(cf->provider.wth);
1560 cf->provider.wth = NULL;
1566 process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset,
1567 wtap_rec *rec, const guchar *pd,
1574 /* Count this packet. */
1577 /* If we're not running a display filter and we're not printing any
1578 packet information, we don't need to do a dissection. This means
1579 that all packets can be marked as 'passed'. */
1582 frame_data_init(&fdata, cf->count, rec, offset, cum_bytes);
1584 /* If we're going to print packet information, or we're going to
1585 run a read filter, or we're going to process taps, set up to
1586 do a dissection and do so. */
1588 /* If we're running a filter, prime the epan_dissect_t with that
1591 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1593 col_custom_prime_edt(edt, &cf->cinfo);
1595 /* We only need the columns if either
1596 1) some tap needs the columns
1598 2) we're printing packet info but we're *not* verbose; in verbose
1599 mode, we print the protocol tree, not the protocol summary.
1601 3) there is a column mapped as an individual field */
1602 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
1607 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
1608 &cf->provider.ref, cf->provider.prev_dis);
1609 if (cf->provider.ref == &fdata) {
1611 cf->provider.ref = &ref_frame;
1614 epan_dissect_file_run_with_taps(edt, rec,
1615 frame_tvbuff_new(&cf->provider, &fdata, pd),
1618 /* Run the filter if we have it. */
1620 passed = dfilter_apply_edt(cf->dfcode, edt);
1624 frame_data_set_after_dissect(&fdata, &cum_bytes);
1626 /* Process this packet. */
1627 if (print_packet_info) {
1628 /* We're printing packet information; print the information for
1630 print_packet(cf, edt);
1632 /* If we're doing "line-buffering", flush the standard output
1633 after every packet. See the comment above, for the "-l"
1634 option, for an explanation of why we do that. */
1638 if (ferror(stdout)) {
1639 show_print_file_io_error(errno);
1644 /* this must be set after print_packet() [bug #8160] */
1645 prev_dis_frame = fdata;
1646 cf->provider.prev_dis = &prev_dis_frame;
1649 prev_cap_frame = fdata;
1650 cf->provider.prev_cap = &prev_cap_frame;
1653 epan_dissect_reset(edt);
1654 frame_data_destroy(&fdata);
1660 write_preamble(capture_file *cf)
1662 switch (output_action) {
1665 return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
1669 write_pdml_preamble(stdout, cf->filename);
1671 write_psml_preamble(&cf->cinfo, stdout);
1672 return !ferror(stdout);
1675 write_fields_preamble(output_fields, stdout);
1676 return !ferror(stdout);
1679 g_assert_not_reached();
1685 get_line_buf(size_t len)
1687 static char *line_bufp = NULL;
1688 static size_t line_buf_len = 256;
1689 size_t new_line_buf_len;
1691 for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
1692 new_line_buf_len *= 2)
1694 if (line_bufp == NULL) {
1695 line_buf_len = new_line_buf_len;
1696 line_bufp = (char *)g_malloc(line_buf_len + 1);
1698 if (new_line_buf_len > line_buf_len) {
1699 line_buf_len = new_line_buf_len;
1700 line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
1707 put_string(char *dest, const char *str, size_t str_len)
1709 memcpy(dest, str, str_len);
1710 dest[str_len] = '\0';
1714 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1718 for (i = str_len; i < str_with_spaces; i++)
1721 put_string(dest, str, str_len);
1725 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1729 memcpy(dest, str, str_len);
1730 for (i = str_len; i < str_with_spaces; i++)
1733 dest[str_with_spaces] = '\0';
1737 print_columns(capture_file *cf)
1744 col_item_t* col_item;
1746 line_bufp = get_line_buf(256);
1749 for (i = 0; i < cf->cinfo.num_cols; i++) {
1750 col_item = &cf->cinfo.columns[i];
1751 /* Skip columns not marked as visible. */
1752 if (!get_column_visible(i))
1754 switch (col_item->col_fmt) {
1756 column_len = col_len = strlen(col_item->col_data);
1759 line_bufp = get_line_buf(buf_offset + column_len);
1760 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1766 case COL_ABS_YMD_TIME: /* XXX - wider */
1767 case COL_ABS_YDOY_TIME: /* XXX - wider */
1769 case COL_UTC_YMD_TIME: /* XXX - wider */
1770 case COL_UTC_YDOY_TIME: /* XXX - wider */
1771 column_len = col_len = strlen(col_item->col_data);
1772 if (column_len < 10)
1774 line_bufp = get_line_buf(buf_offset + column_len);
1775 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1781 case COL_DEF_DL_SRC:
1782 case COL_RES_DL_SRC:
1783 case COL_UNRES_DL_SRC:
1784 case COL_DEF_NET_SRC:
1785 case COL_RES_NET_SRC:
1786 case COL_UNRES_NET_SRC:
1787 column_len = col_len = strlen(col_item->col_data);
1788 if (column_len < 12)
1790 line_bufp = get_line_buf(buf_offset + column_len);
1791 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1797 case COL_DEF_DL_DST:
1798 case COL_RES_DL_DST:
1799 case COL_UNRES_DL_DST:
1800 case COL_DEF_NET_DST:
1801 case COL_RES_NET_DST:
1802 case COL_UNRES_NET_DST:
1803 column_len = col_len = strlen(col_item->col_data);
1804 if (column_len < 12)
1806 line_bufp = get_line_buf(buf_offset + column_len);
1807 put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1811 column_len = strlen(col_item->col_data);
1812 line_bufp = get_line_buf(buf_offset + column_len);
1813 put_string(line_bufp + buf_offset, col_item->col_data, column_len);
1816 buf_offset += column_len;
1817 if (i != cf->cinfo.num_cols - 1) {
1819 * This isn't the last column, so we need to print a
1820 * separator between this column and the next.
1822 * If we printed a network source and are printing a
1823 * network destination of the same type next, separate
1824 * them with " -> "; if we printed a network destination
1825 * and are printing a network source of the same type
1826 * next, separate them with " <- "; otherwise separate them
1829 * We add enough space to the buffer for " <- " or " -> ",
1830 * even if we're only adding " ".
1832 line_bufp = get_line_buf(buf_offset + 4);
1833 switch (col_item->col_fmt) {
1838 switch (cf->cinfo.columns[i+1].col_fmt) {
1843 put_string(line_bufp + buf_offset, " -> ", 4);
1848 put_string(line_bufp + buf_offset, " ", 1);
1854 case COL_DEF_DL_SRC:
1855 case COL_RES_DL_SRC:
1856 case COL_UNRES_DL_SRC:
1857 switch (cf->cinfo.columns[i+1].col_fmt) {
1859 case COL_DEF_DL_DST:
1860 case COL_RES_DL_DST:
1861 case COL_UNRES_DL_DST:
1862 put_string(line_bufp + buf_offset, " -> ", 4);
1867 put_string(line_bufp + buf_offset, " ", 1);
1873 case COL_DEF_NET_SRC:
1874 case COL_RES_NET_SRC:
1875 case COL_UNRES_NET_SRC:
1876 switch (cf->cinfo.columns[i+1].col_fmt) {
1878 case COL_DEF_NET_DST:
1879 case COL_RES_NET_DST:
1880 case COL_UNRES_NET_DST:
1881 put_string(line_bufp + buf_offset, " -> ", 4);
1886 put_string(line_bufp + buf_offset, " ", 1);
1895 switch (cf->cinfo.columns[i+1].col_fmt) {
1900 put_string(line_bufp + buf_offset, " <- ", 4);
1905 put_string(line_bufp + buf_offset, " ", 1);
1911 case COL_DEF_DL_DST:
1912 case COL_RES_DL_DST:
1913 case COL_UNRES_DL_DST:
1914 switch (cf->cinfo.columns[i+1].col_fmt) {
1916 case COL_DEF_DL_SRC:
1917 case COL_RES_DL_SRC:
1918 case COL_UNRES_DL_SRC:
1919 put_string(line_bufp + buf_offset, " <- ", 4);
1924 put_string(line_bufp + buf_offset, " ", 1);
1930 case COL_DEF_NET_DST:
1931 case COL_RES_NET_DST:
1932 case COL_UNRES_NET_DST:
1933 switch (cf->cinfo.columns[i+1].col_fmt) {
1935 case COL_DEF_NET_SRC:
1936 case COL_RES_NET_SRC:
1937 case COL_UNRES_NET_SRC:
1938 put_string(line_bufp + buf_offset, " <- ", 4);
1943 put_string(line_bufp + buf_offset, " ", 1);
1950 put_string(line_bufp + buf_offset, " ", 1);
1956 return print_line(print_stream, 0, line_bufp);
1960 print_packet(capture_file *cf, epan_dissect_t *edt)
1962 if (print_summary || output_fields_has_cols(output_fields)) {
1963 /* Just fill in the columns. */
1964 epan_dissect_fill_in_columns(edt, FALSE, TRUE);
1966 if (print_summary) {
1967 /* Now print them. */
1968 switch (output_action) {
1971 if (!print_columns(cf))
1976 write_psml_columns(edt, stdout, FALSE);
1977 return !ferror(stdout);
1978 case WRITE_FIELDS: /*No non-verbose "fields" format */
1979 g_assert_not_reached();
1984 if (print_details) {
1985 /* Print the information in the protocol tree. */
1986 switch (output_action) {
1989 if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
1990 print_hex, edt, output_only_tables, print_stream))
1993 if (!print_line(print_stream, 0, separator))
1999 write_pdml_proto_tree(NULL, NULL, PF_NONE, edt, &cf->cinfo, stdout, FALSE);
2001 return !ferror(stdout);
2003 write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
2005 return !ferror(stdout);
2009 if (print_summary || print_details) {
2010 if (!print_line(print_stream, 0, ""))
2013 if (!print_hex_data(print_stream, edt))
2015 if (!print_line(print_stream, 0, separator))
2024 switch (output_action) {
2027 return print_finale(print_stream);
2031 write_pdml_finale(stdout);
2033 write_psml_finale(stdout);
2034 return !ferror(stdout);
2037 write_fields_finale(output_fields, stdout);
2038 return !ferror(stdout);
2041 g_assert_not_reached();
2047 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
2050 char err_msg[2048+1];
2052 /* The open isn't implemented yet. Fill in the information for this file. */
2054 /* Create new epan session for dissection. */
2055 epan_free(cf->epan);
2056 cf->epan = tfshark_epan_new(cf);
2058 cf->provider.wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2059 cf->f_datalen = 0; /* not used, but set it anyway */
2061 /* Set the file name because we need it to set the follow stream filter.
2062 XXX - is that still true? We need it for other reasons, though,
2064 cf->filename = g_strdup(fname);
2066 /* Indicate whether it's a permanent or temporary file. */
2067 cf->is_tempfile = is_tempfile;
2069 /* No user changes yet. */
2070 cf->unsaved_changes = FALSE;
2072 cf->cd_t = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2073 cf->open_type = type;
2075 cf->drops_known = FALSE;
2077 cf->snap = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2078 nstime_set_zero(&cf->elapsed_time);
2079 cf->provider.ref = NULL;
2080 cf->provider.prev_dis = NULL;
2081 cf->provider.prev_cap = NULL;
2083 cf->state = FILE_READ_IN_PROGRESS;
2088 g_snprintf(err_msg, sizeof err_msg,
2089 cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
2090 cmdarg_err("%s", err_msg);
2095 show_print_file_io_error(int err)
2100 cmdarg_err("Not all the packets could be printed because there is "
2101 "no space left on the file system.");
2106 cmdarg_err("Not all the packets could be printed because you are "
2107 "too close to, or over your disk quota.");
2112 cmdarg_err("An error occurred while printing packets: %s.",
2119 cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
2123 /* static char errmsg_errno[1024+1]; */
2127 /* Wiretap error. */
2130 case FTAP_ERR_NOT_REGULAR_FILE:
2131 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
2134 case FTAP_ERR_RANDOM_OPEN_PIPE:
2135 /* Seen only when opening a capture file for reading. */
2136 errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
2139 case FTAP_ERR_FILE_UNKNOWN_FORMAT:
2140 /* Seen only when opening a capture file for reading. */
2141 errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
2144 case FTAP_ERR_UNSUPPORTED:
2145 /* Seen only when opening a capture file for reading. */
2146 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2147 "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
2150 errmsg = errmsg_errno;
2153 case FTAP_ERR_CANT_WRITE_TO_PIPE:
2154 /* Seen only when opening a capture file for writing. */
2155 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2156 "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
2157 "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
2158 errmsg = errmsg_errno;
2161 case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
2162 /* Seen only when opening a capture file for writing. */
2163 errmsg = "TFShark doesn't support writing capture files in that format.";
2166 case FTAP_ERR_UNSUPPORTED_ENCAP:
2168 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2169 "TFShark can't save this capture as a \"%s\" file.",
2170 ftap_file_type_subtype_short_string(file_type));
2172 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2173 "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
2177 errmsg = errmsg_errno;
2180 case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
2182 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2183 "TFShark can't save this capture as a \"%s\" file.",
2184 ftap_file_type_subtype_short_string(file_type));
2185 errmsg = errmsg_errno;
2187 errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
2190 case FTAP_ERR_BAD_FILE:
2191 /* Seen only when opening a capture file for reading. */
2192 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2193 "The file \"%%s\" appears to be damaged or corrupt.\n"
2196 errmsg = errmsg_errno;
2199 case FTAP_ERR_CANT_OPEN:
2201 errmsg = "The file \"%s\" could not be created for some unknown reason.";
2203 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
2206 case FTAP_ERR_SHORT_READ:
2207 errmsg = "The file \"%s\" appears to have been cut short"
2208 " in the middle of a packet or other data.";
2211 case FTAP_ERR_SHORT_WRITE:
2212 errmsg = "A full header couldn't be written to the file \"%s\".";
2215 case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
2216 errmsg = "This file type cannot be written as a compressed file.";
2219 case FTAP_ERR_DECOMPRESS:
2220 /* Seen only when opening a capture file for reading. */
2221 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2222 "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
2225 errmsg = errmsg_errno;
2229 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2230 "The file \"%%s\" could not be %s: %s.",
2231 for_writing ? "created" : "opened",
2232 ftap_strerror(err));
2233 errmsg = errmsg_errno;
2238 errmsg = file_open_error_message(err, for_writing);
2243 * General errors and warnings are reported with an console message
2247 failure_warning_message(const char *msg_format, va_list ap)
2249 fprintf(stderr, "tfshark: ");
2250 vfprintf(stderr, msg_format, ap);
2251 fprintf(stderr, "\n");
2255 * Open/create errors are reported with an console message in TFShark.
2258 open_failure_message(const char *filename, int err, gboolean for_writing)
2260 fprintf(stderr, "tfshark: ");
2261 fprintf(stderr, file_open_error_message(err, for_writing), filename);
2262 fprintf(stderr, "\n");
2266 * Read errors are reported with an console message in TFShark.
2269 read_failure_message(const char *filename, int err)
2271 cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
2272 filename, g_strerror(err));
2276 * Write errors are reported with an console message in TFShark.
2279 write_failure_message(const char *filename, int err)
2281 cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
2282 filename, g_strerror(err));
2286 * Report additional information for an error in command-line arguments.
2289 failure_message_cont(const char *msg_format, va_list ap)
2291 vfprintf(stderr, msg_format, ap);
2292 fprintf(stderr, "\n");
2296 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2301 * indent-tabs-mode: nil
2304 * vi: set shiftwidth=2 tabstop=8 expandtab:
2305 * :indentSize=2:tabSize=8:noTabs=true: