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 */
692 switch (prefs_set_pref(optarg)) {
697 case PREFS_SET_SYNTAX_ERR:
698 cmdarg_err("Invalid -o flag \"%s\"", optarg);
702 case PREFS_SET_NO_SUCH_PREF:
703 case PREFS_SET_OBSOLETE:
704 cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
705 exit_status = INVALID_OPTION;
710 case 'q': /* Quiet */
713 case 'Q': /* Really quiet */
717 case 'r': /* Read capture file x */
718 cf_name = g_strdup(optarg);
720 case 'R': /* Read file filter */
723 case 'S': /* Set the line Separator to be printed between packets */
724 separator = g_strdup(optarg);
726 case 'T': /* printing Type */
727 if (strcmp(optarg, "text") == 0) {
728 output_action = WRITE_TEXT;
729 print_format = PR_FMT_TEXT;
730 } else if (strcmp(optarg, "ps") == 0) {
731 output_action = WRITE_TEXT;
732 print_format = PR_FMT_PS;
733 } else if (strcmp(optarg, "pdml") == 0) {
734 output_action = WRITE_XML;
735 print_details = TRUE; /* Need details */
736 print_summary = FALSE; /* Don't allow summary */
737 } else if (strcmp(optarg, "psml") == 0) {
738 output_action = WRITE_XML;
739 print_details = FALSE; /* Don't allow details */
740 print_summary = TRUE; /* Need summary */
741 } else if (strcmp(optarg, "fields") == 0) {
742 output_action = WRITE_FIELDS;
743 print_details = TRUE; /* Need full tree info */
744 print_summary = FALSE; /* Don't allow summary */
746 cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg); /* x */
747 cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
748 "\t specified by the -E option.\n"
749 "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
750 "\t details of a decoded packet. This information is equivalent to\n"
751 "\t the packet details printed with the -V flag.\n"
752 "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
753 "\t the packets, or a multi-line view of the details of each of\n"
754 "\t the packets, depending on whether the -V flag was specified.\n"
755 "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
756 "\t summary information of a decoded packet. This information is\n"
757 "\t equivalent to the information shown in the one-line summary\n"
758 "\t printed by default.\n"
759 "\t\"text\" Text of a human-readable one-line summary of each of the\n"
760 "\t packets, or a multi-line view of the details of each of the\n"
761 "\t packets, depending on whether the -V flag was specified.\n"
762 "\t This is the default.");
763 exit_status = INVALID_OPTION;
767 case 'v': /* Show version and exit */
768 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
769 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
770 show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
771 g_string_free(comp_info_str, TRUE);
772 g_string_free(runtime_info_str, TRUE);
774 case 'O': /* Only output these protocols */
775 /* already processed; just ignore it now */
777 case 'V': /* Verbose */
778 /* already processed; just ignore it now */
780 case 'x': /* Print packet data in hex (and ASCII) */
781 /* already processed; just ignore it now */
784 /* already processed; just ignore it now */
790 /* We won't call the init function for the stat this soon
791 as it would disallow MATE's fields (which are registered
792 by the preferences set callback) from being used as
793 part of a tap filter. Instead, we just add the argument
794 to a list of stat arguments. */
795 if (strcmp("help", optarg) == 0) {
796 fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
797 list_stat_cmd_args();
800 if (!process_stat_cmd_arg(optarg)) {
801 cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
802 list_stat_cmd_args();
803 exit_status = INVALID_OPTION;
807 case 'd': /* Decode as rule */
808 case 'K': /* Kerberos keytab file */
809 case 't': /* Time stamp type */
810 case 'u': /* Seconds type */
811 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
812 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
813 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
814 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
815 if (!dissect_opts_handle_opt(opt, optarg)) {
816 exit_status = INVALID_OPTION;
821 case '?': /* Bad flag - print usage message */
823 exit_status = INVALID_OPTION;
829 /* If we specified output fields, but not the output field type... */
830 if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
831 cmdarg_err("Output fields were specified with \"-e\", "
832 "but \"-Tfields\" was not specified.");
834 } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
835 cmdarg_err("\"-Tfields\" was specified, but no fields were "
836 "specified with \"-e\".");
838 exit_status = INVALID_OPTION;
842 /* If no capture filter or display filter has been specified, and there are
843 still command-line arguments, treat them as the tokens of a capture
844 filter (if no "-r" flag was specified) or a display filter (if a "-r"
845 flag was specified. */
847 if (cf_name != NULL) {
848 if (dfilter != NULL) {
849 cmdarg_err("Display filters were specified both with \"-d\" "
850 "and with additional command-line arguments.");
851 exit_status = INVALID_OPTION;
854 dfilter = get_args_as_string(argc, argv, optind);
858 /* if "-q" wasn't specified, we should print packet information */
860 print_packet_info = TRUE;
864 exit_status = INVALID_OPTION;
869 if (output_action != WRITE_TEXT) {
870 cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
871 exit_status = INVALID_OPTION;
876 if (output_only != NULL) {
879 if (!print_details) {
880 cmdarg_err("-O requires -V");
881 exit_status = INVALID_OPTION;
885 output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
886 for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
887 g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
891 if (rfilter != NULL && !perform_two_pass_analysis) {
892 cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
893 exit_status = INVALID_OPTION;
897 /* Notify all registered modules that have had any of their preferences
898 changed either from one of the preferences file or from the command
899 line that their preferences have changed. */
902 /* At this point MATE will have registered its field array so we can
903 have a tap filter with one of MATE's late-registered fields as part
904 of the filter. We can now process all the "-z" arguments. */
905 start_requested_stats();
908 * Enabled and disabled protocols and heuristic dissectors as per
909 * command-line options.
911 if (!setup_enabled_and_disabled_protocols()) {
912 exit_status = INVALID_OPTION;
916 /* Build the column format array */
917 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
919 if (rfilter != NULL) {
920 if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
921 cmdarg_err("%s", err_msg);
923 exit_status = INVALID_FILTER;
927 cfile.rfcode = rfcode;
929 if (dfilter != NULL) {
930 if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
931 cmdarg_err("%s", err_msg);
933 exit_status = INVALID_FILTER;
937 cfile.dfcode = dfcode;
939 if (print_packet_info) {
940 /* If we're printing as text or PostScript, we have
941 to create a print stream. */
942 if (output_action == WRITE_TEXT) {
943 switch (print_format) {
946 print_stream = print_stream_text_stdio_new(stdout);
950 print_stream = print_stream_ps_stdio_new(stdout);
954 g_assert_not_reached();
959 /* We have to dissect each packet if:
961 we're printing information about each packet;
963 we're using a read filter on the packets;
965 we're using a display filter on the packets;
967 we're using any taps that need dissection. */
968 do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
972 * We're reading a capture file.
975 /* TODO: if tfshark is ever changed to give the user a choice of which
976 open_routine reader to use, then the following needs to change. */
977 if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
978 exit_status = OPEN_ERROR;
982 /* Process the packets in the file */
984 /* XXX - for now there is only 1 packet */
985 success = process_file(&cfile, 1, 0);
987 CATCH(OutOfMemoryError) {
991 "Sorry, but TFShark has to terminate now.\n"
993 "Some infos / workarounds can be found at:\n"
994 "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
1000 /* We still dump out the results of taps, etc., as we might have
1001 read some packets; however, we exit with an error status. */
1008 if (cfile.frames != NULL) {
1009 free_frame_data_sequence(cfile.frames);
1010 cfile.frames = NULL;
1013 draw_tap_listeners(TRUE);
1014 funnel_dump_all_text_windows();
1017 destroy_print_stream(print_stream);
1018 epan_free(cfile.epan);
1024 output_fields_free(output_fields);
1025 output_fields = NULL;
1027 col_cleanup(&cfile.cinfo);
1032 static const nstime_t *
1033 tfshark_get_frame_ts(void *data, guint32 frame_num)
1035 capture_file *cf = (capture_file *) data;
1037 if (ref && ref->num == frame_num)
1038 return &ref->abs_ts;
1040 if (prev_dis && prev_dis->num == frame_num)
1041 return &prev_dis->abs_ts;
1043 if (prev_cap && prev_cap->num == frame_num)
1044 return &prev_cap->abs_ts;
1047 frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
1049 return (fd) ? &fd->abs_ts : NULL;
1056 no_interface_name(void *data _U_, guint32 interface_id _U_)
1062 tfshark_epan_new(capture_file *cf)
1064 epan_t *epan = epan_new();
1067 epan->get_frame_ts = tfshark_get_frame_ts;
1068 epan->get_interface_name = no_interface_name;
1069 epan->get_user_comment = NULL;
1075 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
1076 gint64 offset, struct wtap_pkthdr *whdr,
1083 /* The frame number of this packet is one more than the count of
1084 frames in this packet. */
1085 framenum = cf->count + 1;
1087 /* If we're not running a display filter and we're not printing any
1088 packet information, we don't need to do a dissection. This means
1089 that all packets can be marked as 'passed'. */
1092 frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
1094 /* If we're going to print packet information, or we're going to
1095 run a read filter, or display filter, or we're going to process taps, set up to
1096 do a dissection and do so. */
1098 /* If we're running a read filter, prime the epan_dissect_t with that
1101 epan_dissect_prime_with_dfilter(edt, cf->rfcode);
1103 /* This is the first pass, so prime the epan_dissect_t with the
1104 hfids postdissectors want on the first pass. */
1105 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1107 frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
1109 if (ref == &fdlocal) {
1110 ref_frame = fdlocal;
1114 epan_dissect_file_run(edt, whdr, file_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
1116 /* Run the read filter if we have one. */
1118 passed = dfilter_apply_edt(cf->rfcode, edt);
1122 frame_data_set_after_dissect(&fdlocal, &cum_bytes);
1123 prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
1125 /* If we're not doing dissection then there won't be any dependent frames.
1126 * More importantly, edt.pi.dependent_frames won't be initialized because
1127 * epan hasn't been initialized.
1130 g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
1135 /* if we don't add it to the frame_data_sequence, clean it up right now
1137 frame_data_destroy(&fdlocal);
1141 epan_dissect_reset(edt);
1147 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
1148 frame_data *fdata, struct wtap_pkthdr *phdr,
1149 Buffer *buf, guint tap_flags)
1154 /* If we're not running a display filter and we're not printing any
1155 packet information, we don't need to do a dissection. This means
1156 that all packets can be marked as 'passed'. */
1159 /* If we're going to print packet information, or we're going to
1160 run a read filter, or we're going to process taps, set up to
1161 do a dissection and do so. */
1164 /* If we're running a display filter, prime the epan_dissect_t with that
1167 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1169 /* This is the first and only pass, so prime the epan_dissect_t
1170 with the hfids postdissectors want on the first pass. */
1171 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1173 col_custom_prime_edt(edt, &cf->cinfo);
1175 /* We only need the columns if either
1176 1) some tap needs the columns
1178 2) we're printing packet info but we're *not* verbose; in verbose
1179 mode, we print the protocol tree, not the protocol summary.
1181 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
1186 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1193 epan_dissect_file_run_with_taps(edt, phdr, file_tvbuff_new_buffer(fdata, buf), fdata, cinfo);
1195 /* Run the read/display filter if we have one. */
1197 passed = dfilter_apply_edt(cf->dfcode, edt);
1201 frame_data_set_after_dissect(fdata, &cum_bytes);
1202 /* Process this packet. */
1203 if (print_packet_info) {
1204 /* We're printing packet information; print the information for
1206 print_packet(cf, edt);
1208 /* If we're doing "line-buffering", flush the standard output
1209 after every packet. See the comment above, for the "-l"
1210 option, for an explanation of why we do that. */
1214 if (ferror(stdout)) {
1215 show_print_file_io_error(errno);
1224 epan_dissect_reset(edt);
1226 return passed || fdata->flags.dependent_of_displayed;
1230 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)
1232 /* int bytes_read; */
1233 gint64 packet_size = wtap_file_size(cf->wth, err);
1235 *data_buffer = (guint8*)g_malloc((gsize)packet_size);
1236 /* bytes_read =*/ file_read(*data_buffer, (unsigned int)packet_size, cf->wth->fh);
1238 #if 0 /* no more filetap */
1239 if (bytes_read < 0) {
1240 *err = file_error(cf->wth->fh, err_info);
1242 *err = FTAP_ERR_SHORT_READ;
1244 } else if (bytes_read == 0) {
1245 /* Done with file, no error */
1250 /* XXX - SET FRAME SIZE EQUAL TO TOTAL FILE SIZE */
1251 file_phdr->caplen = (guint32)packet_size;
1252 file_phdr->len = (guint32)packet_size;
1255 * Set the packet encapsulation to the file's encapsulation
1256 * value; if that's not WTAP_ENCAP_PER_PACKET, it's the
1257 * right answer (and means that the read routine for this
1258 * capture file type doesn't have to set it), and if it
1259 * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it
1262 wth->phdr.pkt_encap = wth->file_encap;
1264 if (!wth->subtype_read(wth, err, err_info, data_offset)) {
1266 * If we didn't get an error indication, we read
1267 * the last packet. See if there's any deferred
1268 * error, as might, for example, occur if we're
1269 * reading a compressed file, and we got an error
1270 * reading compressed data from the file, but
1271 * got enough compressed data to decompress the
1272 * last packet of the file.
1275 *err = file_error(wth->fh, err_info);
1276 return FALSE; /* failure */
1280 * It makes no sense for the captured data length to be bigger
1281 * than the actual data length.
1283 if (wth->phdr.caplen > wth->phdr.len)
1284 wth->phdr.caplen = wth->phdr.len;
1287 * Make sure that it's not WTAP_ENCAP_PER_PACKET, as that
1288 * probably means the file has that encapsulation type
1289 * but the read routine didn't set this packet's
1290 * encapsulation type.
1292 g_assert(wth->phdr.pkt_encap != WTAP_ENCAP_PER_PACKET);
1295 return TRUE; /* success */
1299 process_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
1303 gchar *err_info = NULL;
1304 gint64 data_offset = 0;
1305 gboolean filtering_tap_listeners;
1308 epan_dissect_t *edt = NULL;
1309 struct wtap_pkthdr file_phdr;
1312 if (print_packet_info) {
1313 if (!write_preamble(cf)) {
1315 show_print_file_io_error(err);
1320 /* Do we have any tap listeners with filters? */
1321 filtering_tap_listeners = have_filtering_tap_listeners();
1323 /* Get the union of the flags for all tap listeners. */
1324 tap_flags = union_of_tap_listener_flags();
1326 wtap_phdr_init(&file_phdr);
1328 /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1329 file_phdr.pkt_encap = 1234;
1331 if (perform_two_pass_analysis) {
1334 /* Allocate a frame_data_sequence for all the frames. */
1335 cf->frames = new_frame_data_sequence();
1337 if (do_dissection) {
1338 gboolean create_proto_tree;
1341 * Determine whether we need to create a protocol tree.
1344 * we're going to apply a read filter;
1346 * a postdissector wants field values or protocols
1347 * on the first pass.
1350 (cf->rfcode != NULL || postdissectors_want_hfids());
1352 /* We're not going to display the protocol tree on this pass,
1353 so it's not going to be "visible". */
1354 edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
1356 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1357 if (process_packet_first_pass(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1358 wtap_buf_ptr(cf->wth))) {
1360 /* Stop reading if we have the maximum number of packets;
1361 * When the -c option has not been used, max_packet_count
1362 * starts at 0, which practically means, never stop reading.
1363 * (unless we roll over max_packet_count ?)
1365 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1366 err = 0; /* This is not an error */
1373 epan_dissect_free(edt);
1378 /* Close the sequential I/O side, to free up memory it requires. */
1379 wtap_sequential_close(cf->wth);
1382 /* Allow the protocol dissectors to free up memory that they
1383 * don't need after the sequential run-through of the packets. */
1384 postseq_cleanup_all_protocols();
1388 ws_buffer_init(&buf, 1500);
1390 if (do_dissection) {
1391 gboolean create_proto_tree;
1394 * Determine whether we need to create a protocol tree.
1397 * we're going to apply a display filter;
1399 * we're going to print the protocol tree;
1401 * one of the tap listeners requires a protocol tree;
1403 * we have custom columns (which require field values, which
1404 * currently requires that we build a protocol tree).
1407 (cf->dfcode || print_details || filtering_tap_listeners ||
1408 (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo));
1410 /* The protocol tree will be "visible", i.e., printed, only if we're
1411 printing packet details, which is true if we're printing stuff
1412 ("print_packet_info" is true) and we're in verbose mode
1413 ("packet_details" is true). */
1414 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1417 for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
1418 fdata = frame_data_sequence_find(cf->frames, framenum);
1420 if (wtap_seek_read(cf->wth, fdata->file_off,
1421 &buf, fdata->cap_len, &err, &err_info)) {
1422 process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1425 if (!process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf,
1432 epan_dissect_free(edt);
1436 ws_buffer_free(&buf);
1441 if (do_dissection) {
1442 gboolean create_proto_tree;
1445 * Determine whether we need to create a protocol tree.
1448 * we're going to apply a read filter;
1450 * we're going to apply a display filter;
1452 * we're going to print the protocol tree;
1454 * one of the tap listeners is going to apply a filter;
1456 * one of the tap listeners requires a protocol tree;
1458 * a postdissector wants field values or protocols
1459 * on the first pass;
1461 * we have custom columns (which require field values, which
1462 * currently requires that we build a protocol tree).
1465 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
1466 (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
1467 have_custom_cols(&cf->cinfo));
1469 /* The protocol tree will be "visible", i.e., printed, only if we're
1470 printing packet details, which is true if we're printing stuff
1471 ("print_packet_info" is true) and we're in verbose mode
1472 ("packet_details" is true). */
1473 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1476 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1480 if (!process_packet_single_pass(cf, edt, data_offset,
1481 &file_phdr/*wtap_phdr(cf->wth)*/,
1482 raw_data, tap_flags))
1485 /* Stop reading if we have the maximum number of packets;
1486 * When the -c option has not been used, max_packet_count
1487 * starts at 0, which practically means, never stop reading.
1488 * (unless we roll over max_packet_count ?)
1490 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1491 err = 0; /* This is not an error */
1497 epan_dissect_free(edt);
1502 wtap_phdr_cleanup(&file_phdr);
1506 * Print a message noting that the read failed somewhere along the line.
1508 * If we're printing packet data, and the standard output and error are
1509 * going to the same place, flush the standard output, so everything
1510 * buffered up is written, and then print a newline to the standard error
1511 * before printing the error message, to separate it from the packet
1512 * data. (Alas, that only works on UN*X; st_dev is meaningless, and
1513 * the _fstat() documentation at Microsoft doesn't indicate whether
1514 * st_ino is even supported.)
1517 if (print_packet_info) {
1518 ws_statb64 stat_stdout, stat_stderr;
1520 if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
1521 if (stat_stdout.st_dev == stat_stderr.st_dev &&
1522 stat_stdout.st_ino == stat_stderr.st_ino) {
1524 fprintf(stderr, "\n");
1532 case FTAP_ERR_UNSUPPORTED:
1533 cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
1534 cf->filename, err_info);
1538 case FTAP_ERR_UNSUPPORTED_ENCAP:
1539 cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
1540 cf->filename, err_info);
1544 case FTAP_ERR_CANT_READ:
1545 cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
1549 case FTAP_ERR_SHORT_READ:
1550 cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
1554 case FTAP_ERR_BAD_FILE:
1555 cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
1556 cf->filename, err_info);
1560 case FTAP_ERR_DECOMPRESS:
1561 cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
1562 "(%s)", cf->filename, err_info);
1566 cmdarg_err("An error occurred while reading the file \"%s\": %s.",
1567 cf->filename, ftap_strerror(err));
1572 if (print_packet_info) {
1573 if (!write_finale()) {
1575 show_print_file_io_error(err);
1581 wtap_close(cf->wth);
1588 process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset,
1589 struct wtap_pkthdr *whdr, const guchar *pd,
1596 /* Count this packet. */
1599 /* If we're not running a display filter and we're not printing any
1600 packet information, we don't need to do a dissection. This means
1601 that all packets can be marked as 'passed'. */
1604 frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
1606 /* If we're going to print packet information, or we're going to
1607 run a read filter, or we're going to process taps, set up to
1608 do a dissection and do so. */
1610 /* If we're running a filter, prime the epan_dissect_t with that
1613 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1615 col_custom_prime_edt(edt, &cf->cinfo);
1617 /* We only need the columns if either
1618 1) some tap needs the columns
1620 2) we're printing packet info but we're *not* verbose; in verbose
1621 mode, we print the protocol tree, not the protocol summary.
1623 3) there is a column mapped as an individual field */
1624 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
1629 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
1631 if (ref == &fdata) {
1636 epan_dissect_file_run_with_taps(edt, whdr, frame_tvbuff_new(&fdata, pd), &fdata, cinfo);
1638 /* Run the filter if we have it. */
1640 passed = dfilter_apply_edt(cf->dfcode, edt);
1644 frame_data_set_after_dissect(&fdata, &cum_bytes);
1646 /* Process this packet. */
1647 if (print_packet_info) {
1648 /* We're printing packet information; print the information for
1650 print_packet(cf, edt);
1652 /* If we're doing "line-buffering", flush the standard output
1653 after every packet. See the comment above, for the "-l"
1654 option, for an explanation of why we do that. */
1658 if (ferror(stdout)) {
1659 show_print_file_io_error(errno);
1664 /* this must be set after print_packet() [bug #8160] */
1665 prev_dis_frame = fdata;
1666 prev_dis = &prev_dis_frame;
1669 prev_cap_frame = fdata;
1670 prev_cap = &prev_cap_frame;
1673 epan_dissect_reset(edt);
1674 frame_data_destroy(&fdata);
1680 write_preamble(capture_file *cf)
1682 switch (output_action) {
1685 return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
1689 write_pdml_preamble(stdout, cf->filename);
1691 write_psml_preamble(&cf->cinfo, stdout);
1692 return !ferror(stdout);
1695 write_fields_preamble(output_fields, stdout);
1696 return !ferror(stdout);
1699 g_assert_not_reached();
1705 get_line_buf(size_t len)
1707 static char *line_bufp = NULL;
1708 static size_t line_buf_len = 256;
1709 size_t new_line_buf_len;
1711 for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
1712 new_line_buf_len *= 2)
1714 if (line_bufp == NULL) {
1715 line_buf_len = new_line_buf_len;
1716 line_bufp = (char *)g_malloc(line_buf_len + 1);
1718 if (new_line_buf_len > line_buf_len) {
1719 line_buf_len = new_line_buf_len;
1720 line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
1727 put_string(char *dest, const char *str, size_t str_len)
1729 memcpy(dest, str, str_len);
1730 dest[str_len] = '\0';
1734 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1738 for (i = str_len; i < str_with_spaces; i++)
1741 put_string(dest, str, str_len);
1745 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1749 memcpy(dest, str, str_len);
1750 for (i = str_len; i < str_with_spaces; i++)
1753 dest[str_with_spaces] = '\0';
1757 print_columns(capture_file *cf)
1764 col_item_t* col_item;
1766 line_bufp = get_line_buf(256);
1769 for (i = 0; i < cf->cinfo.num_cols; i++) {
1770 col_item = &cf->cinfo.columns[i];
1771 /* Skip columns not marked as visible. */
1772 if (!get_column_visible(i))
1774 switch (col_item->col_fmt) {
1776 column_len = col_len = strlen(col_item->col_data);
1779 line_bufp = get_line_buf(buf_offset + column_len);
1780 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1786 case COL_ABS_YMD_TIME: /* XXX - wider */
1787 case COL_ABS_YDOY_TIME: /* XXX - wider */
1789 case COL_UTC_YMD_TIME: /* XXX - wider */
1790 case COL_UTC_YDOY_TIME: /* XXX - wider */
1791 column_len = col_len = strlen(col_item->col_data);
1792 if (column_len < 10)
1794 line_bufp = get_line_buf(buf_offset + column_len);
1795 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1801 case COL_DEF_DL_SRC:
1802 case COL_RES_DL_SRC:
1803 case COL_UNRES_DL_SRC:
1804 case COL_DEF_NET_SRC:
1805 case COL_RES_NET_SRC:
1806 case COL_UNRES_NET_SRC:
1807 column_len = col_len = strlen(col_item->col_data);
1808 if (column_len < 12)
1810 line_bufp = get_line_buf(buf_offset + column_len);
1811 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1817 case COL_DEF_DL_DST:
1818 case COL_RES_DL_DST:
1819 case COL_UNRES_DL_DST:
1820 case COL_DEF_NET_DST:
1821 case COL_RES_NET_DST:
1822 case COL_UNRES_NET_DST:
1823 column_len = col_len = strlen(col_item->col_data);
1824 if (column_len < 12)
1826 line_bufp = get_line_buf(buf_offset + column_len);
1827 put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1831 column_len = strlen(col_item->col_data);
1832 line_bufp = get_line_buf(buf_offset + column_len);
1833 put_string(line_bufp + buf_offset, col_item->col_data, column_len);
1836 buf_offset += column_len;
1837 if (i != cf->cinfo.num_cols - 1) {
1839 * This isn't the last column, so we need to print a
1840 * separator between this column and the next.
1842 * If we printed a network source and are printing a
1843 * network destination of the same type next, separate
1844 * them with " -> "; if we printed a network destination
1845 * and are printing a network source of the same type
1846 * next, separate them with " <- "; otherwise separate them
1849 * We add enough space to the buffer for " <- " or " -> ",
1850 * even if we're only adding " ".
1852 line_bufp = get_line_buf(buf_offset + 4);
1853 switch (col_item->col_fmt) {
1858 switch (cf->cinfo.columns[i+1].col_fmt) {
1863 put_string(line_bufp + buf_offset, " -> ", 4);
1868 put_string(line_bufp + buf_offset, " ", 1);
1874 case COL_DEF_DL_SRC:
1875 case COL_RES_DL_SRC:
1876 case COL_UNRES_DL_SRC:
1877 switch (cf->cinfo.columns[i+1].col_fmt) {
1879 case COL_DEF_DL_DST:
1880 case COL_RES_DL_DST:
1881 case COL_UNRES_DL_DST:
1882 put_string(line_bufp + buf_offset, " -> ", 4);
1887 put_string(line_bufp + buf_offset, " ", 1);
1893 case COL_DEF_NET_SRC:
1894 case COL_RES_NET_SRC:
1895 case COL_UNRES_NET_SRC:
1896 switch (cf->cinfo.columns[i+1].col_fmt) {
1898 case COL_DEF_NET_DST:
1899 case COL_RES_NET_DST:
1900 case COL_UNRES_NET_DST:
1901 put_string(line_bufp + buf_offset, " -> ", 4);
1906 put_string(line_bufp + buf_offset, " ", 1);
1915 switch (cf->cinfo.columns[i+1].col_fmt) {
1920 put_string(line_bufp + buf_offset, " <- ", 4);
1925 put_string(line_bufp + buf_offset, " ", 1);
1931 case COL_DEF_DL_DST:
1932 case COL_RES_DL_DST:
1933 case COL_UNRES_DL_DST:
1934 switch (cf->cinfo.columns[i+1].col_fmt) {
1936 case COL_DEF_DL_SRC:
1937 case COL_RES_DL_SRC:
1938 case COL_UNRES_DL_SRC:
1939 put_string(line_bufp + buf_offset, " <- ", 4);
1944 put_string(line_bufp + buf_offset, " ", 1);
1950 case COL_DEF_NET_DST:
1951 case COL_RES_NET_DST:
1952 case COL_UNRES_NET_DST:
1953 switch (cf->cinfo.columns[i+1].col_fmt) {
1955 case COL_DEF_NET_SRC:
1956 case COL_RES_NET_SRC:
1957 case COL_UNRES_NET_SRC:
1958 put_string(line_bufp + buf_offset, " <- ", 4);
1963 put_string(line_bufp + buf_offset, " ", 1);
1970 put_string(line_bufp + buf_offset, " ", 1);
1976 return print_line(print_stream, 0, line_bufp);
1980 print_packet(capture_file *cf, epan_dissect_t *edt)
1982 if (print_summary || output_fields_has_cols(output_fields)) {
1983 /* Just fill in the columns. */
1984 epan_dissect_fill_in_columns(edt, FALSE, TRUE);
1986 if (print_summary) {
1987 /* Now print them. */
1988 switch (output_action) {
1991 if (!print_columns(cf))
1996 write_psml_columns(edt, stdout);
1997 return !ferror(stdout);
1998 case WRITE_FIELDS: /*No non-verbose "fields" format */
1999 g_assert_not_reached();
2004 if (print_details) {
2005 /* Print the information in the protocol tree. */
2006 switch (output_action) {
2009 if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
2010 print_hex, edt, output_only_tables, print_stream))
2013 if (!print_line(print_stream, 0, separator))
2019 write_pdml_proto_tree(NULL, NULL, PF_NONE, edt, stdout);
2021 return !ferror(stdout);
2023 write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
2025 return !ferror(stdout);
2029 if (print_summary || print_details) {
2030 if (!print_line(print_stream, 0, ""))
2033 if (!print_hex_data(print_stream, edt))
2035 if (!print_line(print_stream, 0, separator))
2044 switch (output_action) {
2047 return print_finale(print_stream);
2051 write_pdml_finale(stdout);
2053 write_psml_finale(stdout);
2054 return !ferror(stdout);
2057 write_fields_finale(output_fields, stdout);
2058 return !ferror(stdout);
2061 g_assert_not_reached();
2067 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
2070 char err_msg[2048+1];
2072 /* The open isn't implemented yet. Fill in the information for this file. */
2074 /* Create new epan session for dissection. */
2075 epan_free(cf->epan);
2076 cf->epan = tfshark_epan_new(cf);
2078 cf->wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2079 cf->f_datalen = 0; /* not used, but set it anyway */
2081 /* Set the file name because we need it to set the follow stream filter.
2082 XXX - is that still true? We need it for other reasons, though,
2084 cf->filename = g_strdup(fname);
2086 /* Indicate whether it's a permanent or temporary file. */
2087 cf->is_tempfile = is_tempfile;
2089 /* No user changes yet. */
2090 cf->unsaved_changes = FALSE;
2092 cf->cd_t = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2093 cf->open_type = type;
2095 cf->drops_known = FALSE;
2097 cf->snap = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2098 if (cf->snap == 0) {
2099 /* Snapshot length not known. */
2100 cf->has_snap = FALSE;
2103 cf->has_snap = TRUE;
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: