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 int read_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 int exit_status = 0;
340 gboolean quiet = FALSE;
341 gchar *volatile cf_name = NULL;
342 gchar *rfilter = NULL;
343 gchar *dfilter = NULL;
344 dfilter_t *rfcode = NULL;
345 dfilter_t *dfcode = NULL;
349 gchar *output_only = NULL;
352 * The leading + ensures that getopt_long() does not permute the argv[]
355 * We have to make sure that the first getopt_long() preserves the content
356 * of argv[] for the subsequent getopt_long() call.
358 * We use getopt_long() in both cases to ensure that we're using a routine
359 * whose permutation behavior we can control in the same fashion on all
360 * platforms, and so that, if we ever need to process a long argument before
361 * doing further initialization, we can do so.
363 * Glibc and Solaris libc document that a leading + disables permutation
364 * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
365 * and macOS don't document it, but do so anyway.
367 * We do *not* use a leading - because the behavior of a leading - is
368 * platform-dependent.
370 #define OPTSTRING "+2C:d:e:E:hK:lo:O:qQr:R:S:t:T:u:vVxX:Y:z:"
372 static const char optstring[] = OPTSTRING;
374 /* Set the C-language locale to the native environment. */
375 setlocale(LC_ALL, "");
377 cmdarg_err_init(failure_warning_message, failure_message_cont);
380 arg_list_utf_16to8(argc, argv);
381 create_app_running_mutex();
382 #if !GLIB_CHECK_VERSION(2,31,0)
388 * Get credential information for later use, and drop privileges
389 * before doing anything else.
390 * Let the user know if anything happened.
392 init_process_policies();
393 relinquish_special_privs_perm();
394 print_current_user();
397 * Attempt to get the pathname of the directory containing the
400 init_progfile_dir_error = init_progfile_dir(argv[0], main);
401 if (init_progfile_dir_error != NULL) {
403 "tfshark: Can't get pathname of directory containing the tfshark program: %s.\n",
404 init_progfile_dir_error);
405 g_free(init_progfile_dir_error);
408 initialize_funnel_ops();
410 /* Get the compile-time version information string */
411 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
413 /* Get the run-time version information string */
414 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
416 /* Add it to the information to be reported on a crash. */
417 ws_add_crash_info("TFShark (Wireshark) %s\n"
422 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
423 g_string_free(comp_info_str, TRUE);
424 g_string_free(runtime_info_str, TRUE);
427 * In order to have the -X opts assigned before the wslua machine starts
428 * we need to call getopts before epan_init() gets called.
430 * In order to handle, for example, -o options, we also need to call it
431 * *after* epan_init() gets called, so that the dissectors have had a
432 * chance to register their preferences.
434 * XXX - can we do this all with one getopt_long() call, saving the
435 * arguments we can't handle until after initializing libwireshark,
436 * and then process them after initializing libwireshark?
440 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
442 case 'C': /* Configuration Profile */
443 if (profile_exists (optarg, FALSE)) {
444 set_profile_name (optarg);
446 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
450 case 'O': /* Only output these protocols */
451 output_only = g_strdup(optarg);
453 case 'V': /* Verbose */
454 print_details = TRUE;
455 print_packet_info = TRUE;
457 case 'x': /* Print packet data in hex (and ASCII) */
459 /* The user asked for hex output, so let's ensure they get it,
460 * even if they're writing to a file.
462 print_packet_info = TRUE;
473 * Print packet summary information is the default, unless either -V or -x
474 * were specified. Note that this is new behavior, which
475 * allows for the possibility of printing only hex/ascii output without
476 * necessarily requiring that either the summary or details be printed too.
478 if (print_summary == -1)
479 print_summary = (print_details || print_hex) ? FALSE : TRUE;
481 /** Send All g_log messages to our own handler **/
485 G_LOG_LEVEL_CRITICAL|
490 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
492 g_log_set_handler(NULL,
493 (GLogLevelFlags)log_flags,
494 tfshark_log_handler, NULL /* user_data */);
495 g_log_set_handler(LOG_DOMAIN_MAIN,
496 (GLogLevelFlags)log_flags,
497 tfshark_log_handler, NULL /* user_data */);
499 init_report_message(failure_warning_message, failure_warning_message,
500 open_failure_message, read_failure_message,
501 write_failure_message);
503 timestamp_set_type(TS_RELATIVE);
504 timestamp_set_precision(TS_PREC_AUTO);
505 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
510 /* Register all the plugin types we have. */
511 epan_register_plugin_types(); /* Types known to libwireshark */
513 /* Scan for plugins. This does *not* call their registration routines;
514 that's done later. */
515 scan_plugins(REPORT_LOAD_FAILURE);
519 /* Register all dissectors; we must do this before checking for the
520 "-G" flag, as the "-G" flag dumps information registered by the
521 dissectors, and we must do it before we read the preferences, in
522 case any dissectors register preferences. */
523 if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
525 exit_status = INIT_ERROR;
529 /* Register all tap listeners; we do this before we parse the arguments,
530 as the "-z" argument can specify a registered tap. */
532 /* we register the plugin taps before the other taps because
533 stats_tree taps plugins will be registered as tap listeners
534 by stats_tree_stat.c and need to registered before that */
536 /* XXX Disable tap registration for now until we can get tfshark set up with
537 * its own set of taps and the necessary registration function etc.
539 register_all_plugin_tap_listeners();
541 register_all_tap_listeners();
544 /* If invoked with the "-G" flag, we dump out information based on
545 the argument to the "-G" flag; if no argument is specified,
546 for backwards compatibility we dump out a glossary of display
549 XXX - we do this here, for now, to support "-G" with no arguments.
550 If none of our build or other processes uses "-G" with no arguments,
551 we can just process it with the other arguments. */
552 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
553 proto_initialize_all_prefixes();
556 proto_registrar_dump_fields();
558 if (strcmp(argv[2], "column-formats") == 0)
559 column_dump_column_formats();
560 else if (strcmp(argv[2], "currentprefs") == 0) {
561 epan_load_settings();
564 else if (strcmp(argv[2], "decodes") == 0)
565 dissector_dump_decodes();
566 else if (strcmp(argv[2], "defaultprefs") == 0)
568 else if (strcmp(argv[2], "dissector-tables") == 0)
569 dissector_dump_dissector_tables();
570 else if (strcmp(argv[2], "fields") == 0)
571 proto_registrar_dump_fields();
572 else if (strcmp(argv[2], "ftypes") == 0)
573 proto_registrar_dump_ftypes();
574 else if (strcmp(argv[2], "heuristic-decodes") == 0)
575 dissector_dump_heur_decodes();
576 else if (strcmp(argv[2], "plugins") == 0) {
581 wslua_plugins_dump_all();
584 else if (strcmp(argv[2], "protocols") == 0)
585 proto_registrar_dump_protocols();
586 else if (strcmp(argv[2], "values") == 0)
587 proto_registrar_dump_values();
588 else if (strcmp(argv[2], "?") == 0)
589 glossary_option_help();
590 else if (strcmp(argv[2], "-?") == 0)
591 glossary_option_help();
593 cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
594 exit_status = INVALID_OPTION;
601 /* Load libwireshark settings from the current profile. */
602 prefs_p = epan_load_settings();
604 cap_file_init(&cfile);
606 /* Print format defaults to this. */
607 print_format = PR_FMT_TEXT;
609 output_fields = output_fields_new();
612 * To reset the options parser, set optreset to 1 on platforms that
613 * have optreset (documented in *BSD and macOS, apparently present but
614 * not documented in Solaris - the Illumos repository seems to
615 * suggest that the first Solaris getopt_long(), at least as of 2004,
616 * was based on the NetBSD one, it had optreset) and set optind to 1,
617 * and set optind to 0 otherwise (documented as working in the GNU
618 * getopt_long(). Setting optind to 0 didn't originally work in the
619 * NetBSD one, but that was added later - we don't want to depend on
620 * it if we have optreset).
622 * Also reset opterr to 1, so that error messages are printed by
633 /* Now get our args */
634 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
636 case '2': /* Perform two pass analysis */
637 perform_two_pass_analysis = TRUE;
640 /* already processed; just ignore it now */
644 output_fields_add(output_fields, optarg);
648 if (!output_fields_set_option(output_fields, optarg)) {
649 cmdarg_err("\"%s\" is not a valid field output option=value pair.", optarg);
650 output_fields_list_options(stderr);
651 exit_status = INVALID_OPTION;
656 case 'h': /* Print help and exit */
657 printf("TFShark (Wireshark) %s\n"
658 "Dump and analyze network traffic.\n"
659 "See https://www.wireshark.org for more information.\n",
660 get_ws_vcs_version_info());
664 case 'l': /* "Line-buffer" standard output */
665 /* The ANSI C standard does not appear to *require* that a line-buffered
666 stream be flushed to the host environment whenever a newline is
667 written, it just says that, on such a stream, characters "are
668 intended to be transmitted to or from the host environment as a
669 block when a new-line character is encountered".
671 The Visual C++ 6.0 C implementation doesn't do what is intended;
672 even if you set a stream to be line-buffered, it still doesn't
673 flush the buffer at the end of every line.
675 The whole reason for the "-l" flag in either tcpdump or TShark
676 is to allow the output of a live capture to be piped to a program
677 or script and to have that script see the information for the
678 packet as soon as it's printed, rather than having to wait until
679 a standard I/O buffer fills up.
681 So, if the "-l" flag is specified, we flush the standard output
682 at the end of a packet. This will do the right thing if we're
683 printing packet summary lines, and, as we print the entire protocol
684 tree for a single packet without waiting for anything to happen,
685 it should be as good as line-buffered mode if we're printing
686 protocol trees - arguably even better, as it may do fewer
688 line_buffered = TRUE;
690 case 'o': /* Override preference from command line */
691 switch (prefs_set_pref(optarg)) {
696 case PREFS_SET_SYNTAX_ERR:
697 cmdarg_err("Invalid -o flag \"%s\"", optarg);
701 case PREFS_SET_NO_SUCH_PREF:
702 case PREFS_SET_OBSOLETE:
703 cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
704 exit_status = INVALID_OPTION;
709 case 'q': /* Quiet */
712 case 'Q': /* Really quiet */
716 case 'r': /* Read capture file x */
717 cf_name = g_strdup(optarg);
719 case 'R': /* Read file filter */
722 case 'S': /* Set the line Separator to be printed between packets */
723 separator = g_strdup(optarg);
725 case 'T': /* printing Type */
726 if (strcmp(optarg, "text") == 0) {
727 output_action = WRITE_TEXT;
728 print_format = PR_FMT_TEXT;
729 } else if (strcmp(optarg, "ps") == 0) {
730 output_action = WRITE_TEXT;
731 print_format = PR_FMT_PS;
732 } else if (strcmp(optarg, "pdml") == 0) {
733 output_action = WRITE_XML;
734 print_details = TRUE; /* Need details */
735 print_summary = FALSE; /* Don't allow summary */
736 } else if (strcmp(optarg, "psml") == 0) {
737 output_action = WRITE_XML;
738 print_details = FALSE; /* Don't allow details */
739 print_summary = TRUE; /* Need summary */
740 } else if (strcmp(optarg, "fields") == 0) {
741 output_action = WRITE_FIELDS;
742 print_details = TRUE; /* Need full tree info */
743 print_summary = FALSE; /* Don't allow summary */
745 cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg); /* x */
746 cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
747 "\t specified by the -E option.\n"
748 "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
749 "\t details of a decoded packet. This information is equivalent to\n"
750 "\t the packet details printed with the -V flag.\n"
751 "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
752 "\t the packets, or a multi-line view of the details of each of\n"
753 "\t the packets, depending on whether the -V flag was specified.\n"
754 "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
755 "\t summary information of a decoded packet. This information is\n"
756 "\t equivalent to the information shown in the one-line summary\n"
757 "\t printed by default.\n"
758 "\t\"text\" Text of a human-readable one-line summary of each of the\n"
759 "\t packets, or a multi-line view of the details of each of the\n"
760 "\t packets, depending on whether the -V flag was specified.\n"
761 "\t This is the default.");
762 exit_status = INVALID_OPTION;
766 case 'v': /* Show version and exit */
767 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
768 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
769 show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
770 g_string_free(comp_info_str, TRUE);
771 g_string_free(runtime_info_str, TRUE);
773 case 'O': /* Only output these protocols */
774 /* already processed; just ignore it now */
776 case 'V': /* Verbose */
777 /* already processed; just ignore it now */
779 case 'x': /* Print packet data in hex (and ASCII) */
780 /* already processed; just ignore it now */
783 /* already processed; just ignore it now */
789 /* We won't call the init function for the stat this soon
790 as it would disallow MATE's fields (which are registered
791 by the preferences set callback) from being used as
792 part of a tap filter. Instead, we just add the argument
793 to a list of stat arguments. */
794 if (strcmp("help", optarg) == 0) {
795 fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
796 list_stat_cmd_args();
799 if (!process_stat_cmd_arg(optarg)) {
800 cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
801 list_stat_cmd_args();
802 exit_status = INVALID_OPTION;
806 case 'd': /* Decode as rule */
807 case 'K': /* Kerberos keytab file */
808 case 't': /* Time stamp type */
809 case 'u': /* Seconds type */
810 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
811 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
812 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
813 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
814 if (!dissect_opts_handle_opt(opt, optarg)) {
815 exit_status = INVALID_OPTION;
820 case '?': /* Bad flag - print usage message */
822 exit_status = INVALID_OPTION;
828 /* If we specified output fields, but not the output field type... */
829 if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
830 cmdarg_err("Output fields were specified with \"-e\", "
831 "but \"-Tfields\" was not specified.");
833 } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
834 cmdarg_err("\"-Tfields\" was specified, but no fields were "
835 "specified with \"-e\".");
837 exit_status = INVALID_OPTION;
841 /* If no capture filter or display filter has been specified, and there are
842 still command-line arguments, treat them as the tokens of a capture
843 filter (if no "-r" flag was specified) or a display filter (if a "-r"
844 flag was specified. */
846 if (cf_name != NULL) {
847 if (dfilter != NULL) {
848 cmdarg_err("Display filters were specified both with \"-d\" "
849 "and with additional command-line arguments.");
850 exit_status = INVALID_OPTION;
853 dfilter = get_args_as_string(argc, argv, optind);
857 /* if "-q" wasn't specified, we should print packet information */
859 print_packet_info = TRUE;
863 exit_status = INVALID_OPTION;
868 if (output_action != WRITE_TEXT) {
869 cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
870 exit_status = INVALID_OPTION;
875 if (output_only != NULL) {
878 if (!print_details) {
879 cmdarg_err("-O requires -V");
880 exit_status = INVALID_OPTION;
884 output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
885 for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
886 g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
890 if (rfilter != NULL && !perform_two_pass_analysis) {
891 cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
892 exit_status = INVALID_OPTION;
896 /* Notify all registered modules that have had any of their preferences
897 changed either from one of the preferences file or from the command
898 line that their preferences have changed. */
901 /* At this point MATE will have registered its field array so we can
902 have a tap filter with one of MATE's late-registered fields as part
903 of the filter. We can now process all the "-z" arguments. */
904 start_requested_stats();
907 * Enabled and disabled protocols and heuristic dissectors as per
908 * command-line options.
910 if (!setup_enabled_and_disabled_protocols()) {
911 exit_status = INVALID_OPTION;
915 /* Build the column format array */
916 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
918 if (rfilter != NULL) {
919 if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
920 cmdarg_err("%s", err_msg);
922 exit_status = INVALID_FILTER;
926 cfile.rfcode = rfcode;
928 if (dfilter != NULL) {
929 if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
930 cmdarg_err("%s", err_msg);
932 exit_status = INVALID_FILTER;
936 cfile.dfcode = dfcode;
938 if (print_packet_info) {
939 /* If we're printing as text or PostScript, we have
940 to create a print stream. */
941 if (output_action == WRITE_TEXT) {
942 switch (print_format) {
945 print_stream = print_stream_text_stdio_new(stdout);
949 print_stream = print_stream_ps_stdio_new(stdout);
953 g_assert_not_reached();
958 /* We have to dissect each packet if:
960 we're printing information about each packet;
962 we're using a read filter on the packets;
964 we're using a display filter on the packets;
966 we're using any taps that need dissection. */
967 do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
971 * We're reading a capture file.
974 /* TODO: if tfshark is ever changed to give the user a choice of which
975 open_routine reader to use, then the following needs to change. */
976 if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
977 exit_status = OPEN_ERROR;
981 /* Process the packets in the file */
983 /* XXX - for now there is only 1 packet */
984 err = read_file(&cfile, 1, 0);
986 CATCH(OutOfMemoryError) {
990 "Sorry, but TFShark has to terminate now.\n"
992 "Some infos / workarounds can be found at:\n"
993 "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
999 /* We still dump out the results of taps, etc., as we might have
1000 read some packets; however, we exit with an error status. */
1007 if (cfile.frames != NULL) {
1008 free_frame_data_sequence(cfile.frames);
1009 cfile.frames = NULL;
1012 draw_tap_listeners(TRUE);
1013 funnel_dump_all_text_windows();
1016 destroy_print_stream(print_stream);
1017 epan_free(cfile.epan);
1023 output_fields_free(output_fields);
1024 output_fields = NULL;
1026 col_cleanup(&cfile.cinfo);
1031 static const nstime_t *
1032 tfshark_get_frame_ts(void *data, guint32 frame_num)
1034 capture_file *cf = (capture_file *) data;
1036 if (ref && ref->num == frame_num)
1037 return &ref->abs_ts;
1039 if (prev_dis && prev_dis->num == frame_num)
1040 return &prev_dis->abs_ts;
1042 if (prev_cap && prev_cap->num == frame_num)
1043 return &prev_cap->abs_ts;
1046 frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
1048 return (fd) ? &fd->abs_ts : NULL;
1055 no_interface_name(void *data _U_, guint32 interface_id _U_)
1061 tfshark_epan_new(capture_file *cf)
1063 epan_t *epan = epan_new();
1066 epan->get_frame_ts = tfshark_get_frame_ts;
1067 epan->get_interface_name = no_interface_name;
1068 epan->get_user_comment = NULL;
1074 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
1075 gint64 offset, struct wtap_pkthdr *whdr,
1082 /* The frame number of this packet is one more than the count of
1083 frames in this packet. */
1084 framenum = cf->count + 1;
1086 /* If we're not running a display filter and we're not printing any
1087 packet information, we don't need to do a dissection. This means
1088 that all packets can be marked as 'passed'. */
1091 frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
1093 /* If we're going to print packet information, or we're going to
1094 run a read filter, or display filter, or we're going to process taps, set up to
1095 do a dissection and do so. */
1097 /* If we're running a read filter, prime the epan_dissect_t with that
1100 epan_dissect_prime_with_dfilter(edt, cf->rfcode);
1102 /* This is the first pass, so prime the epan_dissect_t with the
1103 hfids postdissectors want on the first pass. */
1104 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1106 frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
1108 if (ref == &fdlocal) {
1109 ref_frame = fdlocal;
1113 epan_dissect_file_run(edt, whdr, file_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
1115 /* Run the read filter if we have one. */
1117 passed = dfilter_apply_edt(cf->rfcode, edt);
1121 frame_data_set_after_dissect(&fdlocal, &cum_bytes);
1122 prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
1124 /* If we're not doing dissection then there won't be any dependent frames.
1125 * More importantly, edt.pi.dependent_frames won't be initialized because
1126 * epan hasn't been initialized.
1129 g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
1134 /* if we don't add it to the frame_data_sequence, clean it up right now
1136 frame_data_destroy(&fdlocal);
1140 epan_dissect_reset(edt);
1146 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
1147 frame_data *fdata, struct wtap_pkthdr *phdr,
1148 Buffer *buf, guint tap_flags)
1153 /* If we're not running a display filter and we're not printing any
1154 packet information, we don't need to do a dissection. This means
1155 that all packets can be marked as 'passed'. */
1158 /* If we're going to print packet information, or we're going to
1159 run a read filter, or we're going to process taps, set up to
1160 do a dissection and do so. */
1163 /* If we're running a display filter, prime the epan_dissect_t with that
1166 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1168 /* This is the first and only pass, so prime the epan_dissect_t
1169 with the hfids postdissectors want on the first pass. */
1170 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1172 col_custom_prime_edt(edt, &cf->cinfo);
1174 /* We only need the columns if either
1175 1) some tap needs the columns
1177 2) we're printing packet info but we're *not* verbose; in verbose
1178 mode, we print the protocol tree, not the protocol summary.
1180 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
1185 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1192 epan_dissect_file_run_with_taps(edt, phdr, file_tvbuff_new_buffer(fdata, buf), fdata, cinfo);
1194 /* Run the read/display filter if we have one. */
1196 passed = dfilter_apply_edt(cf->dfcode, edt);
1200 frame_data_set_after_dissect(fdata, &cum_bytes);
1201 /* Process this packet. */
1202 if (print_packet_info) {
1203 /* We're printing packet information; print the information for
1205 print_packet(cf, edt);
1207 /* If we're doing "line-buffering", flush the standard output
1208 after every packet. See the comment above, for the "-l"
1209 option, for an explanation of why we do that. */
1213 if (ferror(stdout)) {
1214 show_print_file_io_error(errno);
1223 epan_dissect_reset(edt);
1225 return passed || fdata->flags.dependent_of_displayed;
1229 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)
1231 /* int bytes_read; */
1232 gint64 packet_size = wtap_file_size(cf->wth, err);
1234 *data_buffer = (guint8*)g_malloc((gsize)packet_size);
1235 /* bytes_read =*/ file_read(*data_buffer, (unsigned int)packet_size, cf->wth->fh);
1237 #if 0 /* no more filetap */
1238 if (bytes_read < 0) {
1239 *err = file_error(cf->wth->fh, err_info);
1241 *err = FTAP_ERR_SHORT_READ;
1243 } else if (bytes_read == 0) {
1244 /* Done with file, no error */
1249 /* XXX - SET FRAME SIZE EQUAL TO TOTAL FILE SIZE */
1250 file_phdr->caplen = (guint32)packet_size;
1251 file_phdr->len = (guint32)packet_size;
1254 * Set the packet encapsulation to the file's encapsulation
1255 * value; if that's not WTAP_ENCAP_PER_PACKET, it's the
1256 * right answer (and means that the read routine for this
1257 * capture file type doesn't have to set it), and if it
1258 * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it
1261 wth->phdr.pkt_encap = wth->file_encap;
1263 if (!wth->subtype_read(wth, err, err_info, data_offset)) {
1265 * If we didn't get an error indication, we read
1266 * the last packet. See if there's any deferred
1267 * error, as might, for example, occur if we're
1268 * reading a compressed file, and we got an error
1269 * reading compressed data from the file, but
1270 * got enough compressed data to decompress the
1271 * last packet of the file.
1274 *err = file_error(wth->fh, err_info);
1275 return FALSE; /* failure */
1279 * It makes no sense for the captured data length to be bigger
1280 * than the actual data length.
1282 if (wth->phdr.caplen > wth->phdr.len)
1283 wth->phdr.caplen = wth->phdr.len;
1286 * Make sure that it's not WTAP_ENCAP_PER_PACKET, as that
1287 * probably means the file has that encapsulation type
1288 * but the read routine didn't set this packet's
1289 * encapsulation type.
1291 g_assert(wth->phdr.pkt_encap != WTAP_ENCAP_PER_PACKET);
1294 return TRUE; /* success */
1298 read_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
1302 gchar *err_info = NULL;
1303 gint64 data_offset = 0;
1304 gboolean filtering_tap_listeners;
1307 epan_dissect_t *edt = NULL;
1308 struct wtap_pkthdr file_phdr;
1311 if (print_packet_info) {
1312 if (!write_preamble(cf)) {
1314 show_print_file_io_error(err);
1319 /* Do we have any tap listeners with filters? */
1320 filtering_tap_listeners = have_filtering_tap_listeners();
1322 /* Get the union of the flags for all tap listeners. */
1323 tap_flags = union_of_tap_listener_flags();
1325 wtap_phdr_init(&file_phdr);
1327 /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1328 file_phdr.pkt_encap = 1234;
1330 if (perform_two_pass_analysis) {
1333 /* Allocate a frame_data_sequence for all the frames. */
1334 cf->frames = new_frame_data_sequence();
1336 if (do_dissection) {
1337 gboolean create_proto_tree;
1340 * Determine whether we need to create a protocol tree.
1343 * we're going to apply a read filter;
1345 * a postdissector wants field values or protocols
1346 * on the first pass.
1349 (cf->rfcode != NULL || postdissectors_want_hfids());
1351 /* We're not going to display the protocol tree on this pass,
1352 so it's not going to be "visible". */
1353 edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
1355 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1356 if (process_packet_first_pass(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1357 wtap_buf_ptr(cf->wth))) {
1359 /* Stop reading if we have the maximum number of packets;
1360 * When the -c option has not been used, max_packet_count
1361 * starts at 0, which practically means, never stop reading.
1362 * (unless we roll over max_packet_count ?)
1364 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1365 err = 0; /* This is not an error */
1372 epan_dissect_free(edt);
1377 /* Close the sequential I/O side, to free up memory it requires. */
1378 wtap_sequential_close(cf->wth);
1381 /* Allow the protocol dissectors to free up memory that they
1382 * don't need after the sequential run-through of the packets. */
1383 postseq_cleanup_all_protocols();
1387 ws_buffer_init(&buf, 1500);
1389 if (do_dissection) {
1390 gboolean create_proto_tree;
1393 * Determine whether we need to create a protocol tree.
1396 * we're going to apply a display filter;
1398 * we're going to print the protocol tree;
1400 * one of the tap listeners requires a protocol tree;
1402 * we have custom columns (which require field values, which
1403 * currently requires that we build a protocol tree).
1406 (cf->dfcode || print_details || filtering_tap_listeners ||
1407 (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo));
1409 /* The protocol tree will be "visible", i.e., printed, only if we're
1410 printing packet details, which is true if we're printing stuff
1411 ("print_packet_info" is true) and we're in verbose mode
1412 ("packet_details" is true). */
1413 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1416 for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
1417 fdata = frame_data_sequence_find(cf->frames, framenum);
1419 if (wtap_seek_read(cf->wth, fdata->file_off,
1420 &buf, fdata->cap_len, &err, &err_info)) {
1421 process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1424 if (!process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf,
1431 epan_dissect_free(edt);
1435 ws_buffer_free(&buf);
1440 if (do_dissection) {
1441 gboolean create_proto_tree;
1444 * Determine whether we need to create a protocol tree.
1447 * we're going to apply a read filter;
1449 * we're going to apply a display filter;
1451 * we're going to print the protocol tree;
1453 * one of the tap listeners is going to apply a filter;
1455 * one of the tap listeners requires a protocol tree;
1457 * a postdissector wants field values or protocols
1458 * on the first pass;
1460 * we have custom columns (which require field values, which
1461 * currently requires that we build a protocol tree).
1464 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
1465 (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
1466 have_custom_cols(&cf->cinfo));
1468 /* The protocol tree will be "visible", i.e., printed, only if we're
1469 printing packet details, which is true if we're printing stuff
1470 ("print_packet_info" is true) and we're in verbose mode
1471 ("packet_details" is true). */
1472 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1475 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1479 if (!process_packet_single_pass(cf, edt, data_offset,
1480 &file_phdr/*wtap_phdr(cf->wth)*/,
1481 raw_data, tap_flags))
1484 /* Stop reading if we have the maximum number of packets;
1485 * When the -c option has not been used, max_packet_count
1486 * starts at 0, which practically means, never stop reading.
1487 * (unless we roll over max_packet_count ?)
1489 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1490 err = 0; /* This is not an error */
1496 epan_dissect_free(edt);
1501 wtap_phdr_cleanup(&file_phdr);
1505 * Print a message noting that the read failed somewhere along the line.
1507 * If we're printing packet data, and the standard output and error are
1508 * going to the same place, flush the standard output, so everything
1509 * buffered up is written, and then print a newline to the standard error
1510 * before printing the error message, to separate it from the packet
1511 * data. (Alas, that only works on UN*X; st_dev is meaningless, and
1512 * the _fstat() documentation at Microsoft doesn't indicate whether
1513 * st_ino is even supported.)
1516 if (print_packet_info) {
1517 ws_statb64 stat_stdout, stat_stderr;
1519 if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
1520 if (stat_stdout.st_dev == stat_stderr.st_dev &&
1521 stat_stdout.st_ino == stat_stderr.st_ino) {
1523 fprintf(stderr, "\n");
1531 case FTAP_ERR_UNSUPPORTED:
1532 cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
1533 cf->filename, err_info);
1537 case FTAP_ERR_UNSUPPORTED_ENCAP:
1538 cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
1539 cf->filename, err_info);
1543 case FTAP_ERR_CANT_READ:
1544 cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
1548 case FTAP_ERR_SHORT_READ:
1549 cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
1553 case FTAP_ERR_BAD_FILE:
1554 cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
1555 cf->filename, err_info);
1559 case FTAP_ERR_DECOMPRESS:
1560 cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
1561 "(%s)", cf->filename, err_info);
1565 cmdarg_err("An error occurred while reading the file \"%s\": %s.",
1566 cf->filename, ftap_strerror(err));
1571 if (print_packet_info) {
1572 if (!write_finale()) {
1574 show_print_file_io_error(err);
1580 wtap_close(cf->wth);
1587 process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset,
1588 struct wtap_pkthdr *whdr, const guchar *pd,
1595 /* Count this packet. */
1598 /* If we're not running a display filter and we're not printing any
1599 packet information, we don't need to do a dissection. This means
1600 that all packets can be marked as 'passed'. */
1603 frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
1605 /* If we're going to print packet information, or we're going to
1606 run a read filter, or we're going to process taps, set up to
1607 do a dissection and do so. */
1609 /* If we're running a filter, prime the epan_dissect_t with that
1612 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1614 col_custom_prime_edt(edt, &cf->cinfo);
1616 /* We only need the columns if either
1617 1) some tap needs the columns
1619 2) we're printing packet info but we're *not* verbose; in verbose
1620 mode, we print the protocol tree, not the protocol summary.
1622 3) there is a column mapped as an individual field */
1623 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
1628 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
1630 if (ref == &fdata) {
1635 epan_dissect_file_run_with_taps(edt, whdr, frame_tvbuff_new(&fdata, pd), &fdata, cinfo);
1637 /* Run the filter if we have it. */
1639 passed = dfilter_apply_edt(cf->dfcode, edt);
1643 frame_data_set_after_dissect(&fdata, &cum_bytes);
1645 /* Process this packet. */
1646 if (print_packet_info) {
1647 /* We're printing packet information; print the information for
1649 print_packet(cf, edt);
1651 /* If we're doing "line-buffering", flush the standard output
1652 after every packet. See the comment above, for the "-l"
1653 option, for an explanation of why we do that. */
1657 if (ferror(stdout)) {
1658 show_print_file_io_error(errno);
1663 /* this must be set after print_packet() [bug #8160] */
1664 prev_dis_frame = fdata;
1665 prev_dis = &prev_dis_frame;
1668 prev_cap_frame = fdata;
1669 prev_cap = &prev_cap_frame;
1672 epan_dissect_reset(edt);
1673 frame_data_destroy(&fdata);
1679 write_preamble(capture_file *cf)
1681 switch (output_action) {
1684 return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
1688 write_pdml_preamble(stdout, cf->filename);
1690 write_psml_preamble(&cf->cinfo, stdout);
1691 return !ferror(stdout);
1694 write_fields_preamble(output_fields, stdout);
1695 return !ferror(stdout);
1698 g_assert_not_reached();
1704 get_line_buf(size_t len)
1706 static char *line_bufp = NULL;
1707 static size_t line_buf_len = 256;
1708 size_t new_line_buf_len;
1710 for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
1711 new_line_buf_len *= 2)
1713 if (line_bufp == NULL) {
1714 line_buf_len = new_line_buf_len;
1715 line_bufp = (char *)g_malloc(line_buf_len + 1);
1717 if (new_line_buf_len > line_buf_len) {
1718 line_buf_len = new_line_buf_len;
1719 line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
1726 put_string(char *dest, const char *str, size_t str_len)
1728 memcpy(dest, str, str_len);
1729 dest[str_len] = '\0';
1733 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1737 for (i = str_len; i < str_with_spaces; i++)
1740 put_string(dest, str, str_len);
1744 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1748 memcpy(dest, str, str_len);
1749 for (i = str_len; i < str_with_spaces; i++)
1752 dest[str_with_spaces] = '\0';
1756 print_columns(capture_file *cf)
1763 col_item_t* col_item;
1765 line_bufp = get_line_buf(256);
1768 for (i = 0; i < cf->cinfo.num_cols; i++) {
1769 col_item = &cf->cinfo.columns[i];
1770 /* Skip columns not marked as visible. */
1771 if (!get_column_visible(i))
1773 switch (col_item->col_fmt) {
1775 column_len = col_len = strlen(col_item->col_data);
1778 line_bufp = get_line_buf(buf_offset + column_len);
1779 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1785 case COL_ABS_YMD_TIME: /* XXX - wider */
1786 case COL_ABS_YDOY_TIME: /* XXX - wider */
1788 case COL_UTC_YMD_TIME: /* XXX - wider */
1789 case COL_UTC_YDOY_TIME: /* XXX - wider */
1790 column_len = col_len = strlen(col_item->col_data);
1791 if (column_len < 10)
1793 line_bufp = get_line_buf(buf_offset + column_len);
1794 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1800 case COL_DEF_DL_SRC:
1801 case COL_RES_DL_SRC:
1802 case COL_UNRES_DL_SRC:
1803 case COL_DEF_NET_SRC:
1804 case COL_RES_NET_SRC:
1805 case COL_UNRES_NET_SRC:
1806 column_len = col_len = strlen(col_item->col_data);
1807 if (column_len < 12)
1809 line_bufp = get_line_buf(buf_offset + column_len);
1810 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1816 case COL_DEF_DL_DST:
1817 case COL_RES_DL_DST:
1818 case COL_UNRES_DL_DST:
1819 case COL_DEF_NET_DST:
1820 case COL_RES_NET_DST:
1821 case COL_UNRES_NET_DST:
1822 column_len = col_len = strlen(col_item->col_data);
1823 if (column_len < 12)
1825 line_bufp = get_line_buf(buf_offset + column_len);
1826 put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1830 column_len = strlen(col_item->col_data);
1831 line_bufp = get_line_buf(buf_offset + column_len);
1832 put_string(line_bufp + buf_offset, col_item->col_data, column_len);
1835 buf_offset += column_len;
1836 if (i != cf->cinfo.num_cols - 1) {
1838 * This isn't the last column, so we need to print a
1839 * separator between this column and the next.
1841 * If we printed a network source and are printing a
1842 * network destination of the same type next, separate
1843 * them with " -> "; if we printed a network destination
1844 * and are printing a network source of the same type
1845 * next, separate them with " <- "; otherwise separate them
1848 * We add enough space to the buffer for " <- " or " -> ",
1849 * even if we're only adding " ".
1851 line_bufp = get_line_buf(buf_offset + 4);
1852 switch (col_item->col_fmt) {
1857 switch (cf->cinfo.columns[i+1].col_fmt) {
1862 put_string(line_bufp + buf_offset, " -> ", 4);
1867 put_string(line_bufp + buf_offset, " ", 1);
1873 case COL_DEF_DL_SRC:
1874 case COL_RES_DL_SRC:
1875 case COL_UNRES_DL_SRC:
1876 switch (cf->cinfo.columns[i+1].col_fmt) {
1878 case COL_DEF_DL_DST:
1879 case COL_RES_DL_DST:
1880 case COL_UNRES_DL_DST:
1881 put_string(line_bufp + buf_offset, " -> ", 4);
1886 put_string(line_bufp + buf_offset, " ", 1);
1892 case COL_DEF_NET_SRC:
1893 case COL_RES_NET_SRC:
1894 case COL_UNRES_NET_SRC:
1895 switch (cf->cinfo.columns[i+1].col_fmt) {
1897 case COL_DEF_NET_DST:
1898 case COL_RES_NET_DST:
1899 case COL_UNRES_NET_DST:
1900 put_string(line_bufp + buf_offset, " -> ", 4);
1905 put_string(line_bufp + buf_offset, " ", 1);
1914 switch (cf->cinfo.columns[i+1].col_fmt) {
1919 put_string(line_bufp + buf_offset, " <- ", 4);
1924 put_string(line_bufp + buf_offset, " ", 1);
1930 case COL_DEF_DL_DST:
1931 case COL_RES_DL_DST:
1932 case COL_UNRES_DL_DST:
1933 switch (cf->cinfo.columns[i+1].col_fmt) {
1935 case COL_DEF_DL_SRC:
1936 case COL_RES_DL_SRC:
1937 case COL_UNRES_DL_SRC:
1938 put_string(line_bufp + buf_offset, " <- ", 4);
1943 put_string(line_bufp + buf_offset, " ", 1);
1949 case COL_DEF_NET_DST:
1950 case COL_RES_NET_DST:
1951 case COL_UNRES_NET_DST:
1952 switch (cf->cinfo.columns[i+1].col_fmt) {
1954 case COL_DEF_NET_SRC:
1955 case COL_RES_NET_SRC:
1956 case COL_UNRES_NET_SRC:
1957 put_string(line_bufp + buf_offset, " <- ", 4);
1962 put_string(line_bufp + buf_offset, " ", 1);
1969 put_string(line_bufp + buf_offset, " ", 1);
1975 return print_line(print_stream, 0, line_bufp);
1979 print_packet(capture_file *cf, epan_dissect_t *edt)
1981 print_args_t print_args;
1983 if (print_summary || output_fields_has_cols(output_fields)) {
1984 /* Just fill in the columns. */
1985 epan_dissect_fill_in_columns(edt, FALSE, TRUE);
1987 if (print_summary) {
1988 /* Now print them. */
1989 switch (output_action) {
1992 if (!print_columns(cf))
1997 write_psml_columns(edt, stdout);
1998 return !ferror(stdout);
1999 case WRITE_FIELDS: /*No non-verbose "fields" format */
2000 g_assert_not_reached();
2005 if (print_details) {
2006 /* Print the information in the protocol tree. */
2007 switch (output_action) {
2010 /* Only initialize the fields that are actually used in proto_tree_print.
2011 * This is particularly important for .range, as that's heap memory which
2012 * we would otherwise have to g_free().
2013 print_args.to_file = TRUE;
2014 print_args.format = print_format;
2015 print_args.print_summary = print_summary;
2016 print_args.print_formfeed = FALSE;
2017 packet_range_init(&print_args.range, &cfile);
2019 print_args.print_hex = print_hex;
2020 print_args.print_dissections = print_details ? print_dissections_expanded : print_dissections_none;
2022 if (!proto_tree_print(&print_args, edt, output_only_tables, print_stream))
2025 if (!print_line(print_stream, 0, separator))
2031 write_pdml_proto_tree(NULL, NULL, PF_NONE, edt, stdout);
2033 return !ferror(stdout);
2035 write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
2037 return !ferror(stdout);
2041 if (print_summary || print_details) {
2042 if (!print_line(print_stream, 0, ""))
2045 if (!print_hex_data(print_stream, edt))
2047 if (!print_line(print_stream, 0, separator))
2056 switch (output_action) {
2059 return print_finale(print_stream);
2063 write_pdml_finale(stdout);
2065 write_psml_finale(stdout);
2066 return !ferror(stdout);
2069 write_fields_finale(output_fields, stdout);
2070 return !ferror(stdout);
2073 g_assert_not_reached();
2079 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
2082 char err_msg[2048+1];
2084 /* The open isn't implemented yet. Fill in the information for this file. */
2086 /* Create new epan session for dissection. */
2087 epan_free(cf->epan);
2088 cf->epan = tfshark_epan_new(cf);
2090 cf->wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2091 cf->f_datalen = 0; /* not used, but set it anyway */
2093 /* Set the file name because we need it to set the follow stream filter.
2094 XXX - is that still true? We need it for other reasons, though,
2096 cf->filename = g_strdup(fname);
2098 /* Indicate whether it's a permanent or temporary file. */
2099 cf->is_tempfile = is_tempfile;
2101 /* No user changes yet. */
2102 cf->unsaved_changes = FALSE;
2104 cf->cd_t = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2105 cf->open_type = type;
2107 cf->drops_known = FALSE;
2109 cf->snap = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2110 if (cf->snap == 0) {
2111 /* Snapshot length not known. */
2112 cf->has_snap = FALSE;
2115 cf->has_snap = TRUE;
2116 nstime_set_zero(&cf->elapsed_time);
2121 cf->state = FILE_READ_IN_PROGRESS;
2126 g_snprintf(err_msg, sizeof err_msg,
2127 cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
2128 cmdarg_err("%s", err_msg);
2133 show_print_file_io_error(int err)
2138 cmdarg_err("Not all the packets could be printed because there is "
2139 "no space left on the file system.");
2144 cmdarg_err("Not all the packets could be printed because you are "
2145 "too close to, or over your disk quota.");
2150 cmdarg_err("An error occurred while printing packets: %s.",
2157 cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
2161 /* static char errmsg_errno[1024+1]; */
2165 /* Wiretap error. */
2168 case FTAP_ERR_NOT_REGULAR_FILE:
2169 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
2172 case FTAP_ERR_RANDOM_OPEN_PIPE:
2173 /* Seen only when opening a capture file for reading. */
2174 errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
2177 case FTAP_ERR_FILE_UNKNOWN_FORMAT:
2178 /* Seen only when opening a capture file for reading. */
2179 errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
2182 case FTAP_ERR_UNSUPPORTED:
2183 /* Seen only when opening a capture file for reading. */
2184 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2185 "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
2188 errmsg = errmsg_errno;
2191 case FTAP_ERR_CANT_WRITE_TO_PIPE:
2192 /* Seen only when opening a capture file for writing. */
2193 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2194 "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
2195 "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
2196 errmsg = errmsg_errno;
2199 case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
2200 /* Seen only when opening a capture file for writing. */
2201 errmsg = "TFShark doesn't support writing capture files in that format.";
2204 case FTAP_ERR_UNSUPPORTED_ENCAP:
2206 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2207 "TFShark can't save this capture as a \"%s\" file.",
2208 ftap_file_type_subtype_short_string(file_type));
2210 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2211 "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
2215 errmsg = errmsg_errno;
2218 case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
2220 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2221 "TFShark can't save this capture as a \"%s\" file.",
2222 ftap_file_type_subtype_short_string(file_type));
2223 errmsg = errmsg_errno;
2225 errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
2228 case FTAP_ERR_BAD_FILE:
2229 /* Seen only when opening a capture file for reading. */
2230 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2231 "The file \"%%s\" appears to be damaged or corrupt.\n"
2234 errmsg = errmsg_errno;
2237 case FTAP_ERR_CANT_OPEN:
2239 errmsg = "The file \"%s\" could not be created for some unknown reason.";
2241 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
2244 case FTAP_ERR_SHORT_READ:
2245 errmsg = "The file \"%s\" appears to have been cut short"
2246 " in the middle of a packet or other data.";
2249 case FTAP_ERR_SHORT_WRITE:
2250 errmsg = "A full header couldn't be written to the file \"%s\".";
2253 case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
2254 errmsg = "This file type cannot be written as a compressed file.";
2257 case FTAP_ERR_DECOMPRESS:
2258 /* Seen only when opening a capture file for reading. */
2259 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2260 "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
2263 errmsg = errmsg_errno;
2267 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2268 "The file \"%%s\" could not be %s: %s.",
2269 for_writing ? "created" : "opened",
2270 ftap_strerror(err));
2271 errmsg = errmsg_errno;
2276 errmsg = file_open_error_message(err, for_writing);
2281 * General errors and warnings are reported with an console message
2285 failure_warning_message(const char *msg_format, va_list ap)
2287 fprintf(stderr, "tfshark: ");
2288 vfprintf(stderr, msg_format, ap);
2289 fprintf(stderr, "\n");
2293 * Open/create errors are reported with an console message in TFShark.
2296 open_failure_message(const char *filename, int err, gboolean for_writing)
2298 fprintf(stderr, "tfshark: ");
2299 fprintf(stderr, file_open_error_message(err, for_writing), filename);
2300 fprintf(stderr, "\n");
2304 * Read errors are reported with an console message in TFShark.
2307 read_failure_message(const char *filename, int err)
2309 cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
2310 filename, g_strerror(err));
2314 * Write errors are reported with an console message in TFShark.
2317 write_failure_message(const char *filename, int err)
2319 cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
2320 filename, g_strerror(err));
2324 * Report additional information for an error in command-line arguments.
2327 failure_message_cont(const char *msg_format, va_list ap)
2329 vfprintf(stderr, msg_format, ap);
2330 fprintf(stderr, "\n");
2334 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2339 * indent-tabs-mode: nil
2342 * vi: set shiftwidth=2 tabstop=8 expandtab:
2343 * :indentSize=2:tabSize=8:noTabs=true: