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 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
38 #ifndef HAVE_GETOPT_LONG
39 #include "wsutil/wsgetopt.h"
44 #include <epan/exceptions.h>
45 #include <epan/epan-int.h>
46 #include <epan/epan.h>
48 #include <wsutil/clopts_common.h>
49 #include <wsutil/cmdarg_err.h>
50 #include <wsutil/crash_info.h>
51 #include <wsutil/filesystem.h>
52 #include <wsutil/file_util.h>
53 #include <wsutil/privileges.h>
54 #include <wsutil/report_message.h>
55 #include <ws_version_info.h>
58 #include <epan/timestamp.h>
59 #include <epan/packet.h>
61 #include <epan/wslua/init_wslua.h>
64 #include "frame_tvbuff.h"
65 #include <epan/disabled_protos.h>
66 #include <epan/prefs.h>
67 #include <epan/column.h>
68 #include <epan/print.h>
69 #include <epan/addr_resolv.h>
71 #include "ui/decode_as_utils.h"
72 #include "ui/dissect_opts.h"
74 #include <epan/epan_dissect.h>
76 #include <epan/stat_tap_ui.h>
77 #include <epan/ex-opt.h>
83 #include <wiretap/wtap-int.h>
84 #include <wiretap/file_wrappers.h>
87 #include <wsutil/unicode-utils.h>
91 #include <epan/funnel.h>
94 #include <wsutil/plugins.h>
97 #define INVALID_OPTION 1
99 #define INVALID_FILTER 2
102 static guint32 cum_bytes;
103 static const frame_data *ref;
104 static frame_data ref_frame;
105 static frame_data *prev_dis;
106 static frame_data prev_dis_frame;
107 static frame_data *prev_cap;
108 static frame_data prev_cap_frame;
110 static gboolean perform_two_pass_analysis;
113 * The way the packet decode is to be written.
116 WRITE_TEXT, /* summary or detail text */
117 WRITE_XML, /* PDML or PSML */
118 WRITE_FIELDS /* User defined list of fields */
119 /* Add CSV and the like here */
122 static output_action_e output_action;
123 static gboolean do_dissection; /* TRUE if we have to dissect each packet */
124 static gboolean print_packet_info; /* TRUE if we're to print packet information */
125 static gint print_summary = -1; /* TRUE if we're to print packet summary information */
126 static gboolean print_details; /* TRUE if we're to print packet details information */
127 static gboolean print_hex; /* TRUE if we're to print hex/ascci information */
128 static gboolean line_buffered;
129 static gboolean really_quiet = FALSE;
131 static print_format_e print_format = PR_FMT_TEXT;
132 static print_stream_t *print_stream;
134 static output_fields_t* output_fields = NULL;
136 /* The line separator used between packets, changeable via the -S option */
137 static const char *separator = "";
139 static gboolean process_file(capture_file *, int, gint64);
140 static gboolean process_packet_single_pass(capture_file *cf,
141 epan_dissect_t *edt, gint64 offset, struct wtap_pkthdr *whdr,
142 const guchar *pd, guint tap_flags);
143 static void show_print_file_io_error(int err);
144 static gboolean write_preamble(capture_file *cf);
145 static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
146 static gboolean write_finale(void);
147 static const char *cf_open_error_message(int err, gchar *err_info,
148 gboolean for_writing, int file_type);
150 static void failure_warning_message(const char *msg_format, va_list ap);
151 static void open_failure_message(const char *filename, int err,
152 gboolean for_writing);
153 static void read_failure_message(const char *filename, int err);
154 static void write_failure_message(const char *filename, int err);
155 static void failure_message_cont(const char *msg_format, va_list ap);
159 static GHashTable *output_only_tables = NULL;
163 const char *sstr; /* The short string */
164 const char *lstr; /* The long string */
168 string_compare(gconstpointer a, gconstpointer b)
170 return strcmp(((const struct string_elem *)a)->sstr,
171 ((const struct string_elem *)b)->sstr);
175 string_elem_print(gpointer data, gpointer not_used _U_)
177 fprintf(stderr, " %s - %s\n",
178 ((struct string_elem *)data)->sstr,
179 ((struct string_elem *)data)->lstr);
184 print_usage(FILE *output)
186 fprintf(output, "\n");
187 fprintf(output, "Usage: tfshark [options] ...\n");
188 fprintf(output, "\n");
190 /*fprintf(output, "\n");*/
191 fprintf(output, "Input file:\n");
192 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin)\n");
194 fprintf(output, "\n");
195 fprintf(output, "Processing:\n");
196 fprintf(output, " -2 perform a two-pass analysis\n");
197 fprintf(output, " -R <read filter> packet Read filter in Wireshark display filter syntax\n");
198 fprintf(output, " (requires -2)\n");
199 fprintf(output, " -Y <display filter> packet displaY filter in Wireshark display filter\n");
200 fprintf(output, " syntax\n");
201 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
202 fprintf(output, " \"Decode As\", see the man page for details\n");
203 fprintf(output, " Example: tcp.port==8888,http\n");
205 /*fprintf(output, "\n");*/
206 fprintf(output, "Output:\n");
207 fprintf(output, " -C <config profile> start with specified configuration profile\n");
208 fprintf(output, " -V add output of packet tree (Packet Details)\n");
209 fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
210 fprintf(output, " separated\n");
211 fprintf(output, " -S <separator> the line separator to print between packets\n");
212 fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
213 fprintf(output, " -T pdml|ps|psml|text|fields\n");
214 fprintf(output, " format of text output (def: text)\n");
215 fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
216 fprintf(output, " _ws.col.Info)\n");
217 fprintf(output, " this option can be repeated to print multiple fields\n");
218 fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
219 fprintf(output, " header=y|n switch headers on and off\n");
220 fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
221 fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
222 fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
223 fprintf(output, " aggregator\n");
224 fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
225 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
226 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
227 fprintf(output, " -l flush standard output after each packet\n");
228 fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
229 fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
230 fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
231 fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
233 fprintf(output, "\n");
234 fprintf(output, "Miscellaneous:\n");
235 fprintf(output, " -h display this help and exit\n");
236 fprintf(output, " -v display version info and exit\n");
237 fprintf(output, " -o <name>:<value> ... override preference setting\n");
238 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
239 fprintf(output, " -G [report] dump one of several available reports and exit\n");
240 fprintf(output, " default report=\"fields\"\n");
241 fprintf(output, " use \"-G ?\" for more help\n");
245 glossary_option_help(void)
251 fprintf(output, "TFShark (Wireshark) %s\n", get_ws_vcs_version_info());
253 fprintf(output, "\n");
254 fprintf(output, "Usage: tfshark -G [report]\n");
255 fprintf(output, "\n");
256 fprintf(output, "Glossary table reports:\n");
257 fprintf(output, " -G column-formats dump column format codes and exit\n");
258 fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
259 fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
260 fprintf(output, " -G fields dump fields glossary and exit\n");
261 fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
262 fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
263 fprintf(output, " -G plugins dump installed plugins and exit\n");
264 fprintf(output, " -G protocols dump protocols in registration database and exit\n");
265 fprintf(output, " -G values dump value, range, true/false strings and exit\n");
266 fprintf(output, "\n");
267 fprintf(output, "Preference reports:\n");
268 fprintf(output, " -G currentprefs dump current preferences and exit\n");
269 fprintf(output, " -G defaultprefs dump default preferences and exit\n");
270 fprintf(output, "\n");
274 tfshark_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
275 const gchar *message, gpointer user_data)
277 /* ignore log message, if log_level isn't interesting based
278 upon the console log preferences.
279 If the preferences haven't been loaded loaded yet, display the
282 The default console_log_level preference value is such that only
283 ERROR, CRITICAL and WARNING level messages are processed;
284 MESSAGE, INFO and DEBUG level messages are ignored.
286 XXX: Aug 07, 2009: Prior tshark g_log code was hardwired to process only
287 ERROR and CRITICAL level messages so the current code is a behavioral
288 change. The current behavior is the same as in Wireshark.
290 if ((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
291 prefs.console_log_level != 0) {
295 g_log_default_handler(log_domain, log_level, message, user_data);
300 print_current_user(void) {
301 gchar *cur_user, *cur_group;
303 if (started_with_special_privs()) {
304 cur_user = get_cur_username();
305 cur_group = get_cur_groupname();
306 fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
307 cur_user, cur_group);
310 if (running_with_special_privs()) {
311 fprintf(stderr, " This could be dangerous.");
313 fprintf(stderr, "\n");
318 get_tfshark_runtime_version_info(GString *str)
320 /* stuff used by libwireshark */
321 epan_get_runtime_version_info(str);
325 main(int argc, char *argv[])
327 GString *comp_info_str;
328 GString *runtime_info_str;
329 char *init_progfile_dir_error;
331 static const struct option long_options[] = {
332 {"help", no_argument, NULL, 'h'},
333 {"version", no_argument, NULL, 'v'},
336 gboolean arg_error = FALSE;
339 volatile gboolean success;
340 volatile int exit_status = 0;
341 gboolean quiet = FALSE;
342 gchar *volatile cf_name = NULL;
343 gchar *rfilter = NULL;
344 gchar *dfilter = NULL;
345 dfilter_t *rfcode = NULL;
346 dfilter_t *dfcode = NULL;
350 gchar *output_only = NULL;
353 * The leading + ensures that getopt_long() does not permute the argv[]
356 * We have to make sure that the first getopt_long() preserves the content
357 * of argv[] for the subsequent getopt_long() call.
359 * We use getopt_long() in both cases to ensure that we're using a routine
360 * whose permutation behavior we can control in the same fashion on all
361 * platforms, and so that, if we ever need to process a long argument before
362 * doing further initialization, we can do so.
364 * Glibc and Solaris libc document that a leading + disables permutation
365 * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
366 * and macOS don't document it, but do so anyway.
368 * We do *not* use a leading - because the behavior of a leading - is
369 * platform-dependent.
371 #define OPTSTRING "+2C:d:e:E:hK:lo:O:qQr:R:S:t:T:u:vVxX:Y:z:"
373 static const char optstring[] = OPTSTRING;
375 /* Set the C-language locale to the native environment. */
376 setlocale(LC_ALL, "");
378 cmdarg_err_init(failure_warning_message, failure_message_cont);
381 arg_list_utf_16to8(argc, argv);
382 create_app_running_mutex();
383 #if !GLIB_CHECK_VERSION(2,31,0)
389 * Get credential information for later use, and drop privileges
390 * before doing anything else.
391 * Let the user know if anything happened.
393 init_process_policies();
394 relinquish_special_privs_perm();
395 print_current_user();
398 * Attempt to get the pathname of the directory containing the
401 init_progfile_dir_error = init_progfile_dir(argv[0], main);
402 if (init_progfile_dir_error != NULL) {
404 "tfshark: Can't get pathname of directory containing the tfshark program: %s.\n",
405 init_progfile_dir_error);
406 g_free(init_progfile_dir_error);
409 initialize_funnel_ops();
411 /* Get the compile-time version information string */
412 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
414 /* Get the run-time version information string */
415 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
417 /* Add it to the information to be reported on a crash. */
418 ws_add_crash_info("TFShark (Wireshark) %s\n"
423 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
424 g_string_free(comp_info_str, TRUE);
425 g_string_free(runtime_info_str, TRUE);
428 * In order to have the -X opts assigned before the wslua machine starts
429 * we need to call getopts before epan_init() gets called.
431 * In order to handle, for example, -o options, we also need to call it
432 * *after* epan_init() gets called, so that the dissectors have had a
433 * chance to register their preferences.
435 * XXX - can we do this all with one getopt_long() call, saving the
436 * arguments we can't handle until after initializing libwireshark,
437 * and then process them after initializing libwireshark?
441 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
443 case 'C': /* Configuration Profile */
444 if (profile_exists (optarg, FALSE)) {
445 set_profile_name (optarg);
447 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
451 case 'O': /* Only output these protocols */
452 output_only = g_strdup(optarg);
454 case 'V': /* Verbose */
455 print_details = TRUE;
456 print_packet_info = TRUE;
458 case 'x': /* Print packet data in hex (and ASCII) */
460 /* The user asked for hex output, so let's ensure they get it,
461 * even if they're writing to a file.
463 print_packet_info = TRUE;
474 * Print packet summary information is the default, unless either -V or -x
475 * were specified. Note that this is new behavior, which
476 * allows for the possibility of printing only hex/ascii output without
477 * necessarily requiring that either the summary or details be printed too.
479 if (print_summary == -1)
480 print_summary = (print_details || print_hex) ? FALSE : TRUE;
482 /** Send All g_log messages to our own handler **/
486 G_LOG_LEVEL_CRITICAL|
491 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
493 g_log_set_handler(NULL,
494 (GLogLevelFlags)log_flags,
495 tfshark_log_handler, NULL /* user_data */);
496 g_log_set_handler(LOG_DOMAIN_MAIN,
497 (GLogLevelFlags)log_flags,
498 tfshark_log_handler, NULL /* user_data */);
500 init_report_message(failure_warning_message, failure_warning_message,
501 open_failure_message, read_failure_message,
502 write_failure_message);
504 timestamp_set_type(TS_RELATIVE);
505 timestamp_set_precision(TS_PREC_AUTO);
506 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
511 /* Register all the plugin types we have. */
512 epan_register_plugin_types(); /* Types known to libwireshark */
514 /* Scan for plugins. This does *not* call their registration routines;
515 that's done later. */
516 scan_plugins(REPORT_LOAD_FAILURE);
520 /* Register all dissectors; we must do this before checking for the
521 "-G" flag, as the "-G" flag dumps information registered by the
522 dissectors, and we must do it before we read the preferences, in
523 case any dissectors register preferences. */
524 if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
526 exit_status = INIT_ERROR;
530 /* Register all tap listeners; we do this before we parse the arguments,
531 as the "-z" argument can specify a registered tap. */
533 /* we register the plugin taps before the other taps because
534 stats_tree taps plugins will be registered as tap listeners
535 by stats_tree_stat.c and need to registered before that */
537 /* XXX Disable tap registration for now until we can get tfshark set up with
538 * its own set of taps and the necessary registration function etc.
540 register_all_plugin_tap_listeners();
542 register_all_tap_listeners();
545 /* If invoked with the "-G" flag, we dump out information based on
546 the argument to the "-G" flag; if no argument is specified,
547 for backwards compatibility we dump out a glossary of display
550 XXX - we do this here, for now, to support "-G" with no arguments.
551 If none of our build or other processes uses "-G" with no arguments,
552 we can just process it with the other arguments. */
553 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
554 proto_initialize_all_prefixes();
557 proto_registrar_dump_fields();
559 if (strcmp(argv[2], "column-formats") == 0)
560 column_dump_column_formats();
561 else if (strcmp(argv[2], "currentprefs") == 0) {
562 epan_load_settings();
565 else if (strcmp(argv[2], "decodes") == 0)
566 dissector_dump_decodes();
567 else if (strcmp(argv[2], "defaultprefs") == 0)
569 else if (strcmp(argv[2], "dissector-tables") == 0)
570 dissector_dump_dissector_tables();
571 else if (strcmp(argv[2], "fields") == 0)
572 proto_registrar_dump_fields();
573 else if (strcmp(argv[2], "ftypes") == 0)
574 proto_registrar_dump_ftypes();
575 else if (strcmp(argv[2], "heuristic-decodes") == 0)
576 dissector_dump_heur_decodes();
577 else if (strcmp(argv[2], "plugins") == 0) {
582 wslua_plugins_dump_all();
585 else if (strcmp(argv[2], "protocols") == 0)
586 proto_registrar_dump_protocols();
587 else if (strcmp(argv[2], "values") == 0)
588 proto_registrar_dump_values();
589 else if (strcmp(argv[2], "?") == 0)
590 glossary_option_help();
591 else if (strcmp(argv[2], "-?") == 0)
592 glossary_option_help();
594 cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
595 exit_status = INVALID_OPTION;
602 /* Load libwireshark settings from the current profile. */
603 prefs_p = epan_load_settings();
605 cap_file_init(&cfile);
607 /* Print format defaults to this. */
608 print_format = PR_FMT_TEXT;
610 output_fields = output_fields_new();
613 * To reset the options parser, set optreset to 1 on platforms that
614 * have optreset (documented in *BSD and macOS, apparently present but
615 * not documented in Solaris - the Illumos repository seems to
616 * suggest that the first Solaris getopt_long(), at least as of 2004,
617 * was based on the NetBSD one, it had optreset) and set optind to 1,
618 * and set optind to 0 otherwise (documented as working in the GNU
619 * getopt_long(). Setting optind to 0 didn't originally work in the
620 * NetBSD one, but that was added later - we don't want to depend on
621 * it if we have optreset).
623 * Also reset opterr to 1, so that error messages are printed by
634 /* Now get our args */
635 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
637 case '2': /* Perform two pass analysis */
638 perform_two_pass_analysis = TRUE;
641 /* already processed; just ignore it now */
645 output_fields_add(output_fields, optarg);
649 if (!output_fields_set_option(output_fields, optarg)) {
650 cmdarg_err("\"%s\" is not a valid field output option=value pair.", optarg);
651 output_fields_list_options(stderr);
652 exit_status = INVALID_OPTION;
657 case 'h': /* Print help and exit */
658 printf("TFShark (Wireshark) %s\n"
659 "Dump and analyze network traffic.\n"
660 "See https://www.wireshark.org for more information.\n",
661 get_ws_vcs_version_info());
665 case 'l': /* "Line-buffer" standard output */
666 /* The ANSI C standard does not appear to *require* that a line-buffered
667 stream be flushed to the host environment whenever a newline is
668 written, it just says that, on such a stream, characters "are
669 intended to be transmitted to or from the host environment as a
670 block when a new-line character is encountered".
672 The Visual C++ 6.0 C implementation doesn't do what is intended;
673 even if you set a stream to be line-buffered, it still doesn't
674 flush the buffer at the end of every line.
676 The whole reason for the "-l" flag in either tcpdump or TShark
677 is to allow the output of a live capture to be piped to a program
678 or script and to have that script see the information for the
679 packet as soon as it's printed, rather than having to wait until
680 a standard I/O buffer fills up.
682 So, if the "-l" flag is specified, we flush the standard output
683 at the end of a packet. This will do the right thing if we're
684 printing packet summary lines, and, as we print the entire protocol
685 tree for a single packet without waiting for anything to happen,
686 it should be as good as line-buffered mode if we're printing
687 protocol trees - arguably even better, as it may do fewer
689 line_buffered = TRUE;
691 case 'o': /* Override preference from command line */
695 switch (prefs_set_pref(optarg, &errmsg)) {
700 case PREFS_SET_SYNTAX_ERR:
701 cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg,
702 errmsg ? ": " : "", errmsg ? errmsg : "");
707 case PREFS_SET_NO_SUCH_PREF:
708 case PREFS_SET_OBSOLETE:
709 cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
710 exit_status = INVALID_OPTION;
716 case 'q': /* Quiet */
719 case 'Q': /* Really quiet */
723 case 'r': /* Read capture file x */
724 cf_name = g_strdup(optarg);
726 case 'R': /* Read file filter */
729 case 'S': /* Set the line Separator to be printed between packets */
730 separator = g_strdup(optarg);
732 case 'T': /* printing Type */
733 if (strcmp(optarg, "text") == 0) {
734 output_action = WRITE_TEXT;
735 print_format = PR_FMT_TEXT;
736 } else if (strcmp(optarg, "ps") == 0) {
737 output_action = WRITE_TEXT;
738 print_format = PR_FMT_PS;
739 } else if (strcmp(optarg, "pdml") == 0) {
740 output_action = WRITE_XML;
741 print_details = TRUE; /* Need details */
742 print_summary = FALSE; /* Don't allow summary */
743 } else if (strcmp(optarg, "psml") == 0) {
744 output_action = WRITE_XML;
745 print_details = FALSE; /* Don't allow details */
746 print_summary = TRUE; /* Need summary */
747 } else if (strcmp(optarg, "fields") == 0) {
748 output_action = WRITE_FIELDS;
749 print_details = TRUE; /* Need full tree info */
750 print_summary = FALSE; /* Don't allow summary */
752 cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg); /* x */
753 cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
754 "\t specified by the -E option.\n"
755 "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
756 "\t details of a decoded packet. This information is equivalent to\n"
757 "\t the packet details printed with the -V flag.\n"
758 "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
759 "\t the packets, or a multi-line view of the details of each of\n"
760 "\t the packets, depending on whether the -V flag was specified.\n"
761 "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
762 "\t summary information of a decoded packet. This information is\n"
763 "\t equivalent to the information shown in the one-line summary\n"
764 "\t printed by default.\n"
765 "\t\"text\" Text of a human-readable one-line summary of each of the\n"
766 "\t packets, or a multi-line view of the details of each of the\n"
767 "\t packets, depending on whether the -V flag was specified.\n"
768 "\t This is the default.");
769 exit_status = INVALID_OPTION;
773 case 'v': /* Show version and exit */
774 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
775 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
776 show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
777 g_string_free(comp_info_str, TRUE);
778 g_string_free(runtime_info_str, TRUE);
780 case 'O': /* Only output these protocols */
781 /* already processed; just ignore it now */
783 case 'V': /* Verbose */
784 /* already processed; just ignore it now */
786 case 'x': /* Print packet data in hex (and ASCII) */
787 /* already processed; just ignore it now */
790 /* already processed; just ignore it now */
796 /* We won't call the init function for the stat this soon
797 as it would disallow MATE's fields (which are registered
798 by the preferences set callback) from being used as
799 part of a tap filter. Instead, we just add the argument
800 to a list of stat arguments. */
801 if (strcmp("help", optarg) == 0) {
802 fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
803 list_stat_cmd_args();
806 if (!process_stat_cmd_arg(optarg)) {
807 cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
808 list_stat_cmd_args();
809 exit_status = INVALID_OPTION;
813 case 'd': /* Decode as rule */
814 case 'K': /* Kerberos keytab file */
815 case 't': /* Time stamp type */
816 case 'u': /* Seconds type */
817 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
818 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
819 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
820 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
821 if (!dissect_opts_handle_opt(opt, optarg)) {
822 exit_status = INVALID_OPTION;
827 case '?': /* Bad flag - print usage message */
829 exit_status = INVALID_OPTION;
835 /* If we specified output fields, but not the output field type... */
836 if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
837 cmdarg_err("Output fields were specified with \"-e\", "
838 "but \"-Tfields\" was not specified.");
840 } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
841 cmdarg_err("\"-Tfields\" was specified, but no fields were "
842 "specified with \"-e\".");
844 exit_status = INVALID_OPTION;
848 /* If no capture filter or display filter has been specified, and there are
849 still command-line arguments, treat them as the tokens of a capture
850 filter (if no "-r" flag was specified) or a display filter (if a "-r"
851 flag was specified. */
853 if (cf_name != NULL) {
854 if (dfilter != NULL) {
855 cmdarg_err("Display filters were specified both with \"-d\" "
856 "and with additional command-line arguments.");
857 exit_status = INVALID_OPTION;
860 dfilter = get_args_as_string(argc, argv, optind);
864 /* if "-q" wasn't specified, we should print packet information */
866 print_packet_info = TRUE;
870 exit_status = INVALID_OPTION;
875 if (output_action != WRITE_TEXT) {
876 cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
877 exit_status = INVALID_OPTION;
882 if (output_only != NULL) {
885 if (!print_details) {
886 cmdarg_err("-O requires -V");
887 exit_status = INVALID_OPTION;
891 output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
892 for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
893 g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
897 if (rfilter != NULL && !perform_two_pass_analysis) {
898 cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
899 exit_status = INVALID_OPTION;
903 /* Notify all registered modules that have had any of their preferences
904 changed either from one of the preferences file or from the command
905 line that their preferences have changed. */
908 /* At this point MATE will have registered its field array so we can
909 have a tap filter with one of MATE's late-registered fields as part
910 of the filter. We can now process all the "-z" arguments. */
911 start_requested_stats();
914 * Enabled and disabled protocols and heuristic dissectors as per
915 * command-line options.
917 if (!setup_enabled_and_disabled_protocols()) {
918 exit_status = INVALID_OPTION;
922 /* Build the column format array */
923 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
925 if (rfilter != NULL) {
926 if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
927 cmdarg_err("%s", err_msg);
929 exit_status = INVALID_FILTER;
933 cfile.rfcode = rfcode;
935 if (dfilter != NULL) {
936 if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
937 cmdarg_err("%s", err_msg);
939 exit_status = INVALID_FILTER;
943 cfile.dfcode = dfcode;
945 if (print_packet_info) {
946 /* If we're printing as text or PostScript, we have
947 to create a print stream. */
948 if (output_action == WRITE_TEXT) {
949 switch (print_format) {
952 print_stream = print_stream_text_stdio_new(stdout);
956 print_stream = print_stream_ps_stdio_new(stdout);
960 g_assert_not_reached();
965 /* We have to dissect each packet if:
967 we're printing information about each packet;
969 we're using a read filter on the packets;
971 we're using a display filter on the packets;
973 we're using any taps that need dissection. */
974 do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
978 * We're reading a capture file.
981 /* TODO: if tfshark is ever changed to give the user a choice of which
982 open_routine reader to use, then the following needs to change. */
983 if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
984 exit_status = OPEN_ERROR;
988 /* Process the packets in the file */
990 /* XXX - for now there is only 1 packet */
991 success = process_file(&cfile, 1, 0);
993 CATCH(OutOfMemoryError) {
997 "Sorry, but TFShark has to terminate now.\n"
999 "Some infos / workarounds can be found at:\n"
1000 "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
1006 /* We still dump out the results of taps, etc., as we might have
1007 read some packets; however, we exit with an error status. */
1014 if (cfile.frames != NULL) {
1015 free_frame_data_sequence(cfile.frames);
1016 cfile.frames = NULL;
1019 draw_tap_listeners(TRUE);
1020 funnel_dump_all_text_windows();
1023 destroy_print_stream(print_stream);
1024 epan_free(cfile.epan);
1030 output_fields_free(output_fields);
1031 output_fields = NULL;
1033 col_cleanup(&cfile.cinfo);
1038 static const nstime_t *
1039 tfshark_get_frame_ts(void *data, guint32 frame_num)
1041 capture_file *cf = (capture_file *) data;
1043 if (ref && ref->num == frame_num)
1044 return &ref->abs_ts;
1046 if (prev_dis && prev_dis->num == frame_num)
1047 return &prev_dis->abs_ts;
1049 if (prev_cap && prev_cap->num == frame_num)
1050 return &prev_cap->abs_ts;
1053 frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
1055 return (fd) ? &fd->abs_ts : NULL;
1062 no_interface_name(void *data _U_, guint32 interface_id _U_)
1068 tfshark_epan_new(capture_file *cf)
1070 epan_t *epan = epan_new();
1073 epan->get_frame_ts = tfshark_get_frame_ts;
1074 epan->get_interface_name = no_interface_name;
1075 epan->get_user_comment = NULL;
1081 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
1082 gint64 offset, struct wtap_pkthdr *whdr,
1089 /* The frame number of this packet is one more than the count of
1090 frames in this packet. */
1091 framenum = cf->count + 1;
1093 /* If we're not running a display filter and we're not printing any
1094 packet information, we don't need to do a dissection. This means
1095 that all packets can be marked as 'passed'. */
1098 frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
1100 /* If we're going to print packet information, or we're going to
1101 run a read filter, or display filter, or we're going to process taps, set up to
1102 do a dissection and do so. */
1104 /* If we're running a read filter, prime the epan_dissect_t with that
1107 epan_dissect_prime_with_dfilter(edt, cf->rfcode);
1109 /* This is the first pass, so prime the epan_dissect_t with the
1110 hfids postdissectors want on the first pass. */
1111 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1113 frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
1115 if (ref == &fdlocal) {
1116 ref_frame = fdlocal;
1120 epan_dissect_file_run(edt, whdr, file_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
1122 /* Run the read filter if we have one. */
1124 passed = dfilter_apply_edt(cf->rfcode, edt);
1128 frame_data_set_after_dissect(&fdlocal, &cum_bytes);
1129 prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
1131 /* If we're not doing dissection then there won't be any dependent frames.
1132 * More importantly, edt.pi.dependent_frames won't be initialized because
1133 * epan hasn't been initialized.
1136 g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
1141 /* if we don't add it to the frame_data_sequence, clean it up right now
1143 frame_data_destroy(&fdlocal);
1147 epan_dissect_reset(edt);
1153 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
1154 frame_data *fdata, struct wtap_pkthdr *phdr,
1155 Buffer *buf, guint tap_flags)
1160 /* If we're not running a display filter and we're not printing any
1161 packet information, we don't need to do a dissection. This means
1162 that all packets can be marked as 'passed'. */
1165 /* If we're going to print packet information, or we're going to
1166 run a read filter, or we're going to process taps, set up to
1167 do a dissection and do so. */
1170 /* If we're running a display filter, prime the epan_dissect_t with that
1173 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1175 /* This is the first and only pass, so prime the epan_dissect_t
1176 with the hfids postdissectors want on the first pass. */
1177 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1179 col_custom_prime_edt(edt, &cf->cinfo);
1181 /* We only need the columns if either
1182 1) some tap needs the columns
1184 2) we're printing packet info but we're *not* verbose; in verbose
1185 mode, we print the protocol tree, not the protocol summary.
1187 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
1192 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1199 epan_dissect_file_run_with_taps(edt, phdr, file_tvbuff_new_buffer(fdata, buf), fdata, cinfo);
1201 /* Run the read/display filter if we have one. */
1203 passed = dfilter_apply_edt(cf->dfcode, edt);
1207 frame_data_set_after_dissect(fdata, &cum_bytes);
1208 /* Process this packet. */
1209 if (print_packet_info) {
1210 /* We're printing packet information; print the information for
1212 print_packet(cf, edt);
1214 /* If we're doing "line-buffering", flush the standard output
1215 after every packet. See the comment above, for the "-l"
1216 option, for an explanation of why we do that. */
1220 if (ferror(stdout)) {
1221 show_print_file_io_error(errno);
1230 epan_dissect_reset(edt);
1232 return passed || fdata->flags.dependent_of_displayed;
1236 local_wtap_read(capture_file *cf, struct wtap_pkthdr* file_phdr _U_, int *err, gchar **err_info _U_, gint64 *data_offset _U_, guint8** data_buffer)
1238 /* int bytes_read; */
1239 gint64 packet_size = wtap_file_size(cf->wth, err);
1241 *data_buffer = (guint8*)g_malloc((gsize)packet_size);
1242 /* bytes_read =*/ file_read(*data_buffer, (unsigned int)packet_size, cf->wth->fh);
1244 #if 0 /* no more filetap */
1245 if (bytes_read < 0) {
1246 *err = file_error(cf->wth->fh, err_info);
1248 *err = FTAP_ERR_SHORT_READ;
1250 } else if (bytes_read == 0) {
1251 /* Done with file, no error */
1256 /* XXX - SET FRAME SIZE EQUAL TO TOTAL FILE SIZE */
1257 file_phdr->caplen = (guint32)packet_size;
1258 file_phdr->len = (guint32)packet_size;
1261 * Set the packet encapsulation to the file's encapsulation
1262 * value; if that's not WTAP_ENCAP_PER_PACKET, it's the
1263 * right answer (and means that the read routine for this
1264 * capture file type doesn't have to set it), and if it
1265 * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it
1268 wth->phdr.pkt_encap = wth->file_encap;
1270 if (!wth->subtype_read(wth, err, err_info, data_offset)) {
1272 * If we didn't get an error indication, we read
1273 * the last packet. See if there's any deferred
1274 * error, as might, for example, occur if we're
1275 * reading a compressed file, and we got an error
1276 * reading compressed data from the file, but
1277 * got enough compressed data to decompress the
1278 * last packet of the file.
1281 *err = file_error(wth->fh, err_info);
1282 return FALSE; /* failure */
1286 * It makes no sense for the captured data length to be bigger
1287 * than the actual data length.
1289 if (wth->phdr.caplen > wth->phdr.len)
1290 wth->phdr.caplen = wth->phdr.len;
1293 * Make sure that it's not WTAP_ENCAP_PER_PACKET, as that
1294 * probably means the file has that encapsulation type
1295 * but the read routine didn't set this packet's
1296 * encapsulation type.
1298 g_assert(wth->phdr.pkt_encap != WTAP_ENCAP_PER_PACKET);
1301 return TRUE; /* success */
1305 process_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
1309 gchar *err_info = NULL;
1310 gint64 data_offset = 0;
1311 gboolean filtering_tap_listeners;
1314 epan_dissect_t *edt = NULL;
1315 struct wtap_pkthdr file_phdr;
1318 if (print_packet_info) {
1319 if (!write_preamble(cf)) {
1321 show_print_file_io_error(err);
1326 /* Do we have any tap listeners with filters? */
1327 filtering_tap_listeners = have_filtering_tap_listeners();
1329 /* Get the union of the flags for all tap listeners. */
1330 tap_flags = union_of_tap_listener_flags();
1332 wtap_phdr_init(&file_phdr);
1334 /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1335 file_phdr.pkt_encap = 1234;
1337 if (perform_two_pass_analysis) {
1340 /* Allocate a frame_data_sequence for all the frames. */
1341 cf->frames = new_frame_data_sequence();
1343 if (do_dissection) {
1344 gboolean create_proto_tree;
1347 * Determine whether we need to create a protocol tree.
1350 * we're going to apply a read filter;
1352 * a postdissector wants field values or protocols
1353 * on the first pass.
1356 (cf->rfcode != NULL || postdissectors_want_hfids());
1358 /* We're not going to display the protocol tree on this pass,
1359 so it's not going to be "visible". */
1360 edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
1362 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1363 if (process_packet_first_pass(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1364 wtap_buf_ptr(cf->wth))) {
1366 /* Stop reading if we have the maximum number of packets;
1367 * When the -c option has not been used, max_packet_count
1368 * starts at 0, which practically means, never stop reading.
1369 * (unless we roll over max_packet_count ?)
1371 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1372 err = 0; /* This is not an error */
1379 epan_dissect_free(edt);
1384 /* Close the sequential I/O side, to free up memory it requires. */
1385 wtap_sequential_close(cf->wth);
1388 /* Allow the protocol dissectors to free up memory that they
1389 * don't need after the sequential run-through of the packets. */
1390 postseq_cleanup_all_protocols();
1394 ws_buffer_init(&buf, 1500);
1396 if (do_dissection) {
1397 gboolean create_proto_tree;
1400 * Determine whether we need to create a protocol tree.
1403 * we're going to apply a display filter;
1405 * we're going to print the protocol tree;
1407 * one of the tap listeners requires a protocol tree;
1409 * we have custom columns (which require field values, which
1410 * currently requires that we build a protocol tree).
1413 (cf->dfcode || print_details || filtering_tap_listeners ||
1414 (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo));
1416 /* The protocol tree will be "visible", i.e., printed, only if we're
1417 printing packet details, which is true if we're printing stuff
1418 ("print_packet_info" is true) and we're in verbose mode
1419 ("packet_details" is true). */
1420 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1423 for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
1424 fdata = frame_data_sequence_find(cf->frames, framenum);
1426 if (wtap_seek_read(cf->wth, fdata->file_off,
1427 &buf, fdata->cap_len, &err, &err_info)) {
1428 process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1431 if (!process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf,
1438 epan_dissect_free(edt);
1442 ws_buffer_free(&buf);
1447 if (do_dissection) {
1448 gboolean create_proto_tree;
1451 * Determine whether we need to create a protocol tree.
1454 * we're going to apply a read filter;
1456 * we're going to apply a display filter;
1458 * we're going to print the protocol tree;
1460 * one of the tap listeners is going to apply a filter;
1462 * one of the tap listeners requires a protocol tree;
1464 * a postdissector wants field values or protocols
1465 * on the first pass;
1467 * we have custom columns (which require field values, which
1468 * currently requires that we build a protocol tree).
1471 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
1472 (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
1473 have_custom_cols(&cf->cinfo));
1475 /* The protocol tree will be "visible", i.e., printed, only if we're
1476 printing packet details, which is true if we're printing stuff
1477 ("print_packet_info" is true) and we're in verbose mode
1478 ("packet_details" is true). */
1479 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1482 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1486 if (!process_packet_single_pass(cf, edt, data_offset,
1487 &file_phdr/*wtap_phdr(cf->wth)*/,
1488 raw_data, tap_flags))
1491 /* Stop reading if we have the maximum number of packets;
1492 * When the -c option has not been used, max_packet_count
1493 * starts at 0, which practically means, never stop reading.
1494 * (unless we roll over max_packet_count ?)
1496 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1497 err = 0; /* This is not an error */
1503 epan_dissect_free(edt);
1508 wtap_phdr_cleanup(&file_phdr);
1512 * Print a message noting that the read failed somewhere along the line.
1514 * If we're printing packet data, and the standard output and error are
1515 * going to the same place, flush the standard output, so everything
1516 * buffered up is written, and then print a newline to the standard error
1517 * before printing the error message, to separate it from the packet
1518 * data. (Alas, that only works on UN*X; st_dev is meaningless, and
1519 * the _fstat() documentation at Microsoft doesn't indicate whether
1520 * st_ino is even supported.)
1523 if (print_packet_info) {
1524 ws_statb64 stat_stdout, stat_stderr;
1526 if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
1527 if (stat_stdout.st_dev == stat_stderr.st_dev &&
1528 stat_stdout.st_ino == stat_stderr.st_ino) {
1530 fprintf(stderr, "\n");
1538 case FTAP_ERR_UNSUPPORTED:
1539 cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
1540 cf->filename, err_info);
1544 case FTAP_ERR_UNSUPPORTED_ENCAP:
1545 cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
1546 cf->filename, err_info);
1550 case FTAP_ERR_CANT_READ:
1551 cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
1555 case FTAP_ERR_SHORT_READ:
1556 cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
1560 case FTAP_ERR_BAD_FILE:
1561 cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
1562 cf->filename, err_info);
1566 case FTAP_ERR_DECOMPRESS:
1567 cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
1568 "(%s)", cf->filename, err_info);
1572 cmdarg_err("An error occurred while reading the file \"%s\": %s.",
1573 cf->filename, ftap_strerror(err));
1578 if (print_packet_info) {
1579 if (!write_finale()) {
1581 show_print_file_io_error(err);
1587 wtap_close(cf->wth);
1594 process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset,
1595 struct wtap_pkthdr *whdr, const guchar *pd,
1602 /* Count this packet. */
1605 /* If we're not running a display filter and we're not printing any
1606 packet information, we don't need to do a dissection. This means
1607 that all packets can be marked as 'passed'. */
1610 frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
1612 /* If we're going to print packet information, or we're going to
1613 run a read filter, or we're going to process taps, set up to
1614 do a dissection and do so. */
1616 /* If we're running a filter, prime the epan_dissect_t with that
1619 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1621 col_custom_prime_edt(edt, &cf->cinfo);
1623 /* We only need the columns if either
1624 1) some tap needs the columns
1626 2) we're printing packet info but we're *not* verbose; in verbose
1627 mode, we print the protocol tree, not the protocol summary.
1629 3) there is a column mapped as an individual field */
1630 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
1635 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
1637 if (ref == &fdata) {
1642 epan_dissect_file_run_with_taps(edt, whdr, frame_tvbuff_new(&fdata, pd), &fdata, cinfo);
1644 /* Run the filter if we have it. */
1646 passed = dfilter_apply_edt(cf->dfcode, edt);
1650 frame_data_set_after_dissect(&fdata, &cum_bytes);
1652 /* Process this packet. */
1653 if (print_packet_info) {
1654 /* We're printing packet information; print the information for
1656 print_packet(cf, edt);
1658 /* If we're doing "line-buffering", flush the standard output
1659 after every packet. See the comment above, for the "-l"
1660 option, for an explanation of why we do that. */
1664 if (ferror(stdout)) {
1665 show_print_file_io_error(errno);
1670 /* this must be set after print_packet() [bug #8160] */
1671 prev_dis_frame = fdata;
1672 prev_dis = &prev_dis_frame;
1675 prev_cap_frame = fdata;
1676 prev_cap = &prev_cap_frame;
1679 epan_dissect_reset(edt);
1680 frame_data_destroy(&fdata);
1686 write_preamble(capture_file *cf)
1688 switch (output_action) {
1691 return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
1695 write_pdml_preamble(stdout, cf->filename);
1697 write_psml_preamble(&cf->cinfo, stdout);
1698 return !ferror(stdout);
1701 write_fields_preamble(output_fields, stdout);
1702 return !ferror(stdout);
1705 g_assert_not_reached();
1711 get_line_buf(size_t len)
1713 static char *line_bufp = NULL;
1714 static size_t line_buf_len = 256;
1715 size_t new_line_buf_len;
1717 for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
1718 new_line_buf_len *= 2)
1720 if (line_bufp == NULL) {
1721 line_buf_len = new_line_buf_len;
1722 line_bufp = (char *)g_malloc(line_buf_len + 1);
1724 if (new_line_buf_len > line_buf_len) {
1725 line_buf_len = new_line_buf_len;
1726 line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
1733 put_string(char *dest, const char *str, size_t str_len)
1735 memcpy(dest, str, str_len);
1736 dest[str_len] = '\0';
1740 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1744 for (i = str_len; i < str_with_spaces; i++)
1747 put_string(dest, str, str_len);
1751 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1755 memcpy(dest, str, str_len);
1756 for (i = str_len; i < str_with_spaces; i++)
1759 dest[str_with_spaces] = '\0';
1763 print_columns(capture_file *cf)
1770 col_item_t* col_item;
1772 line_bufp = get_line_buf(256);
1775 for (i = 0; i < cf->cinfo.num_cols; i++) {
1776 col_item = &cf->cinfo.columns[i];
1777 /* Skip columns not marked as visible. */
1778 if (!get_column_visible(i))
1780 switch (col_item->col_fmt) {
1782 column_len = col_len = strlen(col_item->col_data);
1785 line_bufp = get_line_buf(buf_offset + column_len);
1786 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1792 case COL_ABS_YMD_TIME: /* XXX - wider */
1793 case COL_ABS_YDOY_TIME: /* XXX - wider */
1795 case COL_UTC_YMD_TIME: /* XXX - wider */
1796 case COL_UTC_YDOY_TIME: /* XXX - wider */
1797 column_len = col_len = strlen(col_item->col_data);
1798 if (column_len < 10)
1800 line_bufp = get_line_buf(buf_offset + column_len);
1801 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1807 case COL_DEF_DL_SRC:
1808 case COL_RES_DL_SRC:
1809 case COL_UNRES_DL_SRC:
1810 case COL_DEF_NET_SRC:
1811 case COL_RES_NET_SRC:
1812 case COL_UNRES_NET_SRC:
1813 column_len = col_len = strlen(col_item->col_data);
1814 if (column_len < 12)
1816 line_bufp = get_line_buf(buf_offset + column_len);
1817 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1823 case COL_DEF_DL_DST:
1824 case COL_RES_DL_DST:
1825 case COL_UNRES_DL_DST:
1826 case COL_DEF_NET_DST:
1827 case COL_RES_NET_DST:
1828 case COL_UNRES_NET_DST:
1829 column_len = col_len = strlen(col_item->col_data);
1830 if (column_len < 12)
1832 line_bufp = get_line_buf(buf_offset + column_len);
1833 put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1837 column_len = strlen(col_item->col_data);
1838 line_bufp = get_line_buf(buf_offset + column_len);
1839 put_string(line_bufp + buf_offset, col_item->col_data, column_len);
1842 buf_offset += column_len;
1843 if (i != cf->cinfo.num_cols - 1) {
1845 * This isn't the last column, so we need to print a
1846 * separator between this column and the next.
1848 * If we printed a network source and are printing a
1849 * network destination of the same type next, separate
1850 * them with " -> "; if we printed a network destination
1851 * and are printing a network source of the same type
1852 * next, separate them with " <- "; otherwise separate them
1855 * We add enough space to the buffer for " <- " or " -> ",
1856 * even if we're only adding " ".
1858 line_bufp = get_line_buf(buf_offset + 4);
1859 switch (col_item->col_fmt) {
1864 switch (cf->cinfo.columns[i+1].col_fmt) {
1869 put_string(line_bufp + buf_offset, " -> ", 4);
1874 put_string(line_bufp + buf_offset, " ", 1);
1880 case COL_DEF_DL_SRC:
1881 case COL_RES_DL_SRC:
1882 case COL_UNRES_DL_SRC:
1883 switch (cf->cinfo.columns[i+1].col_fmt) {
1885 case COL_DEF_DL_DST:
1886 case COL_RES_DL_DST:
1887 case COL_UNRES_DL_DST:
1888 put_string(line_bufp + buf_offset, " -> ", 4);
1893 put_string(line_bufp + buf_offset, " ", 1);
1899 case COL_DEF_NET_SRC:
1900 case COL_RES_NET_SRC:
1901 case COL_UNRES_NET_SRC:
1902 switch (cf->cinfo.columns[i+1].col_fmt) {
1904 case COL_DEF_NET_DST:
1905 case COL_RES_NET_DST:
1906 case COL_UNRES_NET_DST:
1907 put_string(line_bufp + buf_offset, " -> ", 4);
1912 put_string(line_bufp + buf_offset, " ", 1);
1921 switch (cf->cinfo.columns[i+1].col_fmt) {
1926 put_string(line_bufp + buf_offset, " <- ", 4);
1931 put_string(line_bufp + buf_offset, " ", 1);
1937 case COL_DEF_DL_DST:
1938 case COL_RES_DL_DST:
1939 case COL_UNRES_DL_DST:
1940 switch (cf->cinfo.columns[i+1].col_fmt) {
1942 case COL_DEF_DL_SRC:
1943 case COL_RES_DL_SRC:
1944 case COL_UNRES_DL_SRC:
1945 put_string(line_bufp + buf_offset, " <- ", 4);
1950 put_string(line_bufp + buf_offset, " ", 1);
1956 case COL_DEF_NET_DST:
1957 case COL_RES_NET_DST:
1958 case COL_UNRES_NET_DST:
1959 switch (cf->cinfo.columns[i+1].col_fmt) {
1961 case COL_DEF_NET_SRC:
1962 case COL_RES_NET_SRC:
1963 case COL_UNRES_NET_SRC:
1964 put_string(line_bufp + buf_offset, " <- ", 4);
1969 put_string(line_bufp + buf_offset, " ", 1);
1976 put_string(line_bufp + buf_offset, " ", 1);
1982 return print_line(print_stream, 0, line_bufp);
1986 print_packet(capture_file *cf, epan_dissect_t *edt)
1988 if (print_summary || output_fields_has_cols(output_fields)) {
1989 /* Just fill in the columns. */
1990 epan_dissect_fill_in_columns(edt, FALSE, TRUE);
1992 if (print_summary) {
1993 /* Now print them. */
1994 switch (output_action) {
1997 if (!print_columns(cf))
2002 write_psml_columns(edt, stdout, FALSE);
2003 return !ferror(stdout);
2004 case WRITE_FIELDS: /*No non-verbose "fields" format */
2005 g_assert_not_reached();
2010 if (print_details) {
2011 /* Print the information in the protocol tree. */
2012 switch (output_action) {
2015 if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
2016 print_hex, edt, output_only_tables, print_stream))
2019 if (!print_line(print_stream, 0, separator))
2025 write_pdml_proto_tree(NULL, NULL, PF_NONE, edt, stdout, FALSE);
2027 return !ferror(stdout);
2029 write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
2031 return !ferror(stdout);
2035 if (print_summary || print_details) {
2036 if (!print_line(print_stream, 0, ""))
2039 if (!print_hex_data(print_stream, edt))
2041 if (!print_line(print_stream, 0, separator))
2050 switch (output_action) {
2053 return print_finale(print_stream);
2057 write_pdml_finale(stdout);
2059 write_psml_finale(stdout);
2060 return !ferror(stdout);
2063 write_fields_finale(output_fields, stdout);
2064 return !ferror(stdout);
2067 g_assert_not_reached();
2073 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
2076 char err_msg[2048+1];
2078 /* The open isn't implemented yet. Fill in the information for this file. */
2080 /* Create new epan session for dissection. */
2081 epan_free(cf->epan);
2082 cf->epan = tfshark_epan_new(cf);
2084 cf->wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2085 cf->f_datalen = 0; /* not used, but set it anyway */
2087 /* Set the file name because we need it to set the follow stream filter.
2088 XXX - is that still true? We need it for other reasons, though,
2090 cf->filename = g_strdup(fname);
2092 /* Indicate whether it's a permanent or temporary file. */
2093 cf->is_tempfile = is_tempfile;
2095 /* No user changes yet. */
2096 cf->unsaved_changes = FALSE;
2098 cf->cd_t = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2099 cf->open_type = type;
2101 cf->drops_known = FALSE;
2103 cf->snap = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2104 nstime_set_zero(&cf->elapsed_time);
2109 cf->state = FILE_READ_IN_PROGRESS;
2114 g_snprintf(err_msg, sizeof err_msg,
2115 cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
2116 cmdarg_err("%s", err_msg);
2121 show_print_file_io_error(int err)
2126 cmdarg_err("Not all the packets could be printed because there is "
2127 "no space left on the file system.");
2132 cmdarg_err("Not all the packets could be printed because you are "
2133 "too close to, or over your disk quota.");
2138 cmdarg_err("An error occurred while printing packets: %s.",
2145 cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
2149 /* static char errmsg_errno[1024+1]; */
2153 /* Wiretap error. */
2156 case FTAP_ERR_NOT_REGULAR_FILE:
2157 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
2160 case FTAP_ERR_RANDOM_OPEN_PIPE:
2161 /* Seen only when opening a capture file for reading. */
2162 errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
2165 case FTAP_ERR_FILE_UNKNOWN_FORMAT:
2166 /* Seen only when opening a capture file for reading. */
2167 errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
2170 case FTAP_ERR_UNSUPPORTED:
2171 /* Seen only when opening a capture file for reading. */
2172 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2173 "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
2176 errmsg = errmsg_errno;
2179 case FTAP_ERR_CANT_WRITE_TO_PIPE:
2180 /* Seen only when opening a capture file for writing. */
2181 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2182 "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
2183 "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
2184 errmsg = errmsg_errno;
2187 case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
2188 /* Seen only when opening a capture file for writing. */
2189 errmsg = "TFShark doesn't support writing capture files in that format.";
2192 case FTAP_ERR_UNSUPPORTED_ENCAP:
2194 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2195 "TFShark can't save this capture as a \"%s\" file.",
2196 ftap_file_type_subtype_short_string(file_type));
2198 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2199 "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
2203 errmsg = errmsg_errno;
2206 case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
2208 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2209 "TFShark can't save this capture as a \"%s\" file.",
2210 ftap_file_type_subtype_short_string(file_type));
2211 errmsg = errmsg_errno;
2213 errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
2216 case FTAP_ERR_BAD_FILE:
2217 /* Seen only when opening a capture file for reading. */
2218 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2219 "The file \"%%s\" appears to be damaged or corrupt.\n"
2222 errmsg = errmsg_errno;
2225 case FTAP_ERR_CANT_OPEN:
2227 errmsg = "The file \"%s\" could not be created for some unknown reason.";
2229 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
2232 case FTAP_ERR_SHORT_READ:
2233 errmsg = "The file \"%s\" appears to have been cut short"
2234 " in the middle of a packet or other data.";
2237 case FTAP_ERR_SHORT_WRITE:
2238 errmsg = "A full header couldn't be written to the file \"%s\".";
2241 case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
2242 errmsg = "This file type cannot be written as a compressed file.";
2245 case FTAP_ERR_DECOMPRESS:
2246 /* Seen only when opening a capture file for reading. */
2247 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2248 "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
2251 errmsg = errmsg_errno;
2255 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2256 "The file \"%%s\" could not be %s: %s.",
2257 for_writing ? "created" : "opened",
2258 ftap_strerror(err));
2259 errmsg = errmsg_errno;
2264 errmsg = file_open_error_message(err, for_writing);
2269 * General errors and warnings are reported with an console message
2273 failure_warning_message(const char *msg_format, va_list ap)
2275 fprintf(stderr, "tfshark: ");
2276 vfprintf(stderr, msg_format, ap);
2277 fprintf(stderr, "\n");
2281 * Open/create errors are reported with an console message in TFShark.
2284 open_failure_message(const char *filename, int err, gboolean for_writing)
2286 fprintf(stderr, "tfshark: ");
2287 fprintf(stderr, file_open_error_message(err, for_writing), filename);
2288 fprintf(stderr, "\n");
2292 * Read errors are reported with an console message in TFShark.
2295 read_failure_message(const char *filename, int err)
2297 cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
2298 filename, g_strerror(err));
2302 * Write errors are reported with an console message in TFShark.
2305 write_failure_message(const char *filename, int err)
2307 cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
2308 filename, g_strerror(err));
2312 * Report additional information for an error in command-line arguments.
2315 failure_message_cont(const char *msg_format, va_list ap)
2317 vfprintf(stderr, msg_format, ap);
2318 fprintf(stderr, "\n");
2322 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2327 * indent-tabs-mode: nil
2330 * vi: set shiftwidth=2 tabstop=8 expandtab:
2331 * :indentSize=2:tabSize=8:noTabs=true: