3 * Text-mode variant of Fileshark, based off of TShark,
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0+
26 #ifndef HAVE_GETOPT_LONG
27 #include "wsutil/wsgetopt.h"
32 #include <epan/exceptions.h>
33 #include <epan/epan-int.h>
34 #include <epan/epan.h>
36 #include <wsutil/clopts_common.h>
37 #include <wsutil/cmdarg_err.h>
38 #include <wsutil/crash_info.h>
39 #include <wsutil/filesystem.h>
40 #include <wsutil/file_util.h>
41 #include <wsutil/privileges.h>
42 #include <wsutil/report_message.h>
43 #include <version_info.h>
46 #include <epan/timestamp.h>
47 #include <epan/packet.h>
49 #include <epan/wslua/init_wslua.h>
52 #include "frame_tvbuff.h"
53 #include <epan/disabled_protos.h>
54 #include <epan/prefs.h>
55 #include <epan/column.h>
56 #include <epan/print.h>
57 #include <epan/addr_resolv.h>
59 #include "ui/decode_as_utils.h"
60 #include "ui/dissect_opts.h"
61 #include "epan/register.h"
62 #include <epan/epan_dissect.h>
64 #include <epan/stat_tap_ui.h>
65 #include <epan/ex-opt.h>
71 #include <wiretap/wtap-int.h>
72 #include <wiretap/file_wrappers.h>
75 #include <wsutil/unicode-utils.h>
79 #include <epan/funnel.h>
82 #include <wsutil/plugins.h>
85 #define INVALID_OPTION 1
87 #define INVALID_FILTER 2
90 static guint32 cum_bytes;
91 static const frame_data *ref;
92 static frame_data ref_frame;
93 static frame_data *prev_dis;
94 static frame_data prev_dis_frame;
95 static frame_data *prev_cap;
96 static frame_data prev_cap_frame;
98 static gboolean prefs_loaded = FALSE;
100 static gboolean perform_two_pass_analysis;
103 * The way the packet decode is to be written.
106 WRITE_TEXT, /* summary or detail text */
107 WRITE_XML, /* PDML or PSML */
108 WRITE_FIELDS /* User defined list of fields */
109 /* Add CSV and the like here */
112 static output_action_e output_action;
113 static gboolean do_dissection; /* TRUE if we have to dissect each packet */
114 static gboolean print_packet_info; /* TRUE if we're to print packet information */
115 static gint print_summary = -1; /* TRUE if we're to print packet summary information */
116 static gboolean print_details; /* TRUE if we're to print packet details information */
117 static gboolean print_hex; /* TRUE if we're to print hex/ascci information */
118 static gboolean line_buffered;
119 static gboolean really_quiet = FALSE;
121 static print_format_e print_format = PR_FMT_TEXT;
122 static print_stream_t *print_stream;
124 static output_fields_t* output_fields = NULL;
126 /* The line separator used between packets, changeable via the -S option */
127 static const char *separator = "";
129 static gboolean process_file(capture_file *, int, gint64);
130 static gboolean process_packet_single_pass(capture_file *cf,
131 epan_dissect_t *edt, gint64 offset, struct wtap_pkthdr *whdr,
132 const guchar *pd, guint tap_flags);
133 static void show_print_file_io_error(int err);
134 static gboolean write_preamble(capture_file *cf);
135 static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
136 static gboolean write_finale(void);
137 static const char *cf_open_error_message(int err, gchar *err_info,
138 gboolean for_writing, int file_type);
140 static void failure_warning_message(const char *msg_format, va_list ap);
141 static void open_failure_message(const char *filename, int err,
142 gboolean for_writing);
143 static void read_failure_message(const char *filename, int err);
144 static void write_failure_message(const char *filename, int err);
145 static void failure_message_cont(const char *msg_format, va_list ap);
149 static GHashTable *output_only_tables = NULL;
153 const char *sstr; /* The short string */
154 const char *lstr; /* The long string */
158 string_compare(gconstpointer a, gconstpointer b)
160 return strcmp(((const struct string_elem *)a)->sstr,
161 ((const struct string_elem *)b)->sstr);
165 string_elem_print(gpointer data, gpointer not_used _U_)
167 fprintf(stderr, " %s - %s\n",
168 ((struct string_elem *)data)->sstr,
169 ((struct string_elem *)data)->lstr);
174 print_usage(FILE *output)
176 fprintf(output, "\n");
177 fprintf(output, "Usage: tfshark [options] ...\n");
178 fprintf(output, "\n");
180 /*fprintf(output, "\n");*/
181 fprintf(output, "Input file:\n");
182 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin)\n");
184 fprintf(output, "\n");
185 fprintf(output, "Processing:\n");
186 fprintf(output, " -2 perform a two-pass analysis\n");
187 fprintf(output, " -R <read filter> packet Read filter in Wireshark display filter syntax\n");
188 fprintf(output, " (requires -2)\n");
189 fprintf(output, " -Y <display filter> packet displaY filter in Wireshark display filter\n");
190 fprintf(output, " syntax\n");
191 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
192 fprintf(output, " \"Decode As\", see the man page for details\n");
193 fprintf(output, " Example: tcp.port==8888,http\n");
195 /*fprintf(output, "\n");*/
196 fprintf(output, "Output:\n");
197 fprintf(output, " -C <config profile> start with specified configuration profile\n");
198 fprintf(output, " -V add output of packet tree (Packet Details)\n");
199 fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
200 fprintf(output, " separated\n");
201 fprintf(output, " -S <separator> the line separator to print between packets\n");
202 fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
203 fprintf(output, " -T pdml|ps|psml|text|fields\n");
204 fprintf(output, " format of text output (def: text)\n");
205 fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
206 fprintf(output, " _ws.col.Info)\n");
207 fprintf(output, " this option can be repeated to print multiple fields\n");
208 fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
209 fprintf(output, " header=y|n switch headers on and off\n");
210 fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
211 fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
212 fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
213 fprintf(output, " aggregator\n");
214 fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
215 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
216 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
217 fprintf(output, " -l flush standard output after each packet\n");
218 fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
219 fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
220 fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
221 fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
223 fprintf(output, "\n");
224 fprintf(output, "Miscellaneous:\n");
225 fprintf(output, " -h display this help and exit\n");
226 fprintf(output, " -v display version info and exit\n");
227 fprintf(output, " -o <name>:<value> ... override preference setting\n");
228 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
229 fprintf(output, " -G [report] dump one of several available reports and exit\n");
230 fprintf(output, " default report=\"fields\"\n");
231 fprintf(output, " use \"-G ?\" for more help\n");
235 glossary_option_help(void)
241 fprintf(output, "TFShark (Wireshark) %s\n", get_ws_vcs_version_info());
243 fprintf(output, "\n");
244 fprintf(output, "Usage: tfshark -G [report]\n");
245 fprintf(output, "\n");
246 fprintf(output, "Glossary table reports:\n");
247 fprintf(output, " -G column-formats dump column format codes and exit\n");
248 fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
249 fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
250 fprintf(output, " -G fields dump fields glossary and exit\n");
251 fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
252 fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
253 fprintf(output, " -G plugins dump installed plugins and exit\n");
254 fprintf(output, " -G protocols dump protocols in registration database and exit\n");
255 fprintf(output, " -G values dump value, range, true/false strings and exit\n");
256 fprintf(output, "\n");
257 fprintf(output, "Preference reports:\n");
258 fprintf(output, " -G currentprefs dump current preferences and exit\n");
259 fprintf(output, " -G defaultprefs dump default preferences and exit\n");
260 fprintf(output, "\n");
264 tfshark_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
265 const gchar *message, gpointer user_data)
267 /* ignore log message, if log_level isn't interesting based
268 upon the console log preferences.
269 If the preferences haven't been loaded yet, display the
272 The default console_log_level preference value is such that only
273 ERROR, CRITICAL and WARNING level messages are processed;
274 MESSAGE, INFO and DEBUG level messages are ignored.
276 XXX: Aug 07, 2009: Prior tshark g_log code was hardwired to process only
277 ERROR and CRITICAL level messages so the current code is a behavioral
278 change. The current behavior is the same as in Wireshark.
280 if (prefs_loaded && (log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0) {
284 g_log_default_handler(log_domain, log_level, message, user_data);
289 print_current_user(void) {
290 gchar *cur_user, *cur_group;
292 if (started_with_special_privs()) {
293 cur_user = get_cur_username();
294 cur_group = get_cur_groupname();
295 fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
296 cur_user, cur_group);
299 if (running_with_special_privs()) {
300 fprintf(stderr, " This could be dangerous.");
302 fprintf(stderr, "\n");
307 get_tfshark_runtime_version_info(GString *str)
309 /* stuff used by libwireshark */
310 epan_get_runtime_version_info(str);
314 main(int argc, char *argv[])
316 GString *comp_info_str;
317 GString *runtime_info_str;
318 char *init_progfile_dir_error;
320 static const struct option long_options[] = {
321 {"help", no_argument, NULL, 'h'},
322 {"version", no_argument, NULL, 'v'},
325 gboolean arg_error = FALSE;
328 volatile gboolean success;
329 volatile int exit_status = 0;
330 gboolean quiet = FALSE;
331 gchar *volatile cf_name = NULL;
332 gchar *rfilter = NULL;
333 gchar *dfilter = NULL;
334 dfilter_t *rfcode = NULL;
335 dfilter_t *dfcode = NULL;
339 gchar *output_only = NULL;
342 * The leading + ensures that getopt_long() does not permute the argv[]
345 * We have to make sure that the first getopt_long() preserves the content
346 * of argv[] for the subsequent getopt_long() call.
348 * We use getopt_long() in both cases to ensure that we're using a routine
349 * whose permutation behavior we can control in the same fashion on all
350 * platforms, and so that, if we ever need to process a long argument before
351 * doing further initialization, we can do so.
353 * Glibc and Solaris libc document that a leading + disables permutation
354 * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
355 * and macOS don't document it, but do so anyway.
357 * We do *not* use a leading - because the behavior of a leading - is
358 * platform-dependent.
360 #define OPTSTRING "+2C:d:e:E:hK:lo:O:qQr:R:S:t:T:u:vVxX:Y:z:"
362 static const char optstring[] = OPTSTRING;
364 /* Set the C-language locale to the native environment. */
365 setlocale(LC_ALL, "");
367 cmdarg_err_init(failure_warning_message, failure_message_cont);
370 arg_list_utf_16to8(argc, argv);
371 create_app_running_mutex();
372 #if !GLIB_CHECK_VERSION(2,31,0)
378 * Get credential information for later use, and drop privileges
379 * before doing anything else.
380 * Let the user know if anything happened.
382 init_process_policies();
383 relinquish_special_privs_perm();
384 print_current_user();
387 * Attempt to get the pathname of the directory containing the
390 init_progfile_dir_error = init_progfile_dir(argv[0], main);
391 if (init_progfile_dir_error != NULL) {
393 "tfshark: Can't get pathname of directory containing the tfshark program: %s.\n",
394 init_progfile_dir_error);
395 g_free(init_progfile_dir_error);
398 initialize_funnel_ops();
400 /* Get the compile-time version information string */
401 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
403 /* Get the run-time version information string */
404 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
406 /* Add it to the information to be reported on a crash. */
407 ws_add_crash_info("TFShark (Wireshark) %s\n"
412 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
413 g_string_free(comp_info_str, TRUE);
414 g_string_free(runtime_info_str, TRUE);
417 * In order to have the -X opts assigned before the wslua machine starts
418 * we need to call getopts before epan_init() gets called.
420 * In order to handle, for example, -o options, we also need to call it
421 * *after* epan_init() gets called, so that the dissectors have had a
422 * chance to register their preferences.
424 * XXX - can we do this all with one getopt_long() call, saving the
425 * arguments we can't handle until after initializing libwireshark,
426 * and then process them after initializing libwireshark?
430 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
432 case 'C': /* Configuration Profile */
433 if (profile_exists (optarg, FALSE)) {
434 set_profile_name (optarg);
436 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
440 case 'O': /* Only output these protocols */
441 output_only = g_strdup(optarg);
443 case 'V': /* Verbose */
444 print_details = TRUE;
445 print_packet_info = TRUE;
447 case 'x': /* Print packet data in hex (and ASCII) */
449 /* The user asked for hex output, so let's ensure they get it,
450 * even if they're writing to a file.
452 print_packet_info = TRUE;
463 * Print packet summary information is the default, unless either -V or -x
464 * were specified. Note that this is new behavior, which
465 * allows for the possibility of printing only hex/ascii output without
466 * necessarily requiring that either the summary or details be printed too.
468 if (print_summary == -1)
469 print_summary = (print_details || print_hex) ? FALSE : TRUE;
471 /** Send All g_log messages to our own handler **/
475 G_LOG_LEVEL_CRITICAL|
480 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
482 g_log_set_handler(NULL,
483 (GLogLevelFlags)log_flags,
484 tfshark_log_handler, NULL /* user_data */);
485 g_log_set_handler(LOG_DOMAIN_MAIN,
486 (GLogLevelFlags)log_flags,
487 tfshark_log_handler, NULL /* user_data */);
489 init_report_message(failure_warning_message, failure_warning_message,
490 open_failure_message, read_failure_message,
491 write_failure_message);
493 timestamp_set_type(TS_RELATIVE);
494 timestamp_set_precision(TS_PREC_AUTO);
495 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
500 /* Register all the plugin types we have. */
501 epan_register_plugin_types(); /* Types known to libwireshark */
503 /* Scan for plugins. This does *not* call their registration routines;
504 that's done later. */
505 scan_plugins(REPORT_LOAD_FAILURE);
509 /* Register all dissectors; we must do this before checking for the
510 "-G" flag, as the "-G" flag dumps information registered by the
511 dissectors, and we must do it before we read the preferences, in
512 case any dissectors register preferences. */
513 if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
515 exit_status = INIT_ERROR;
519 /* Register all tap listeners; we do this before we parse the arguments,
520 as the "-z" argument can specify a registered tap. */
522 /* we register the plugin taps before the other taps because
523 stats_tree taps plugins will be registered as tap listeners
524 by stats_tree_stat.c and need to registered before that */
526 /* XXX Disable tap registration for now until we can get tfshark set up with
527 * its own set of taps and the necessary registration function etc.
529 register_all_plugin_tap_listeners();
531 register_all_tap_listeners();
534 /* If invoked with the "-G" flag, we dump out information based on
535 the argument to the "-G" flag; if no argument is specified,
536 for backwards compatibility we dump out a glossary of display
539 XXX - we do this here, for now, to support "-G" with no arguments.
540 If none of our build or other processes uses "-G" with no arguments,
541 we can just process it with the other arguments. */
542 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
543 proto_initialize_all_prefixes();
546 proto_registrar_dump_fields();
548 if (strcmp(argv[2], "column-formats") == 0)
549 column_dump_column_formats();
550 else if (strcmp(argv[2], "currentprefs") == 0) {
551 epan_load_settings();
554 else if (strcmp(argv[2], "decodes") == 0)
555 dissector_dump_decodes();
556 else if (strcmp(argv[2], "defaultprefs") == 0)
558 else if (strcmp(argv[2], "dissector-tables") == 0)
559 dissector_dump_dissector_tables();
560 else if (strcmp(argv[2], "fields") == 0)
561 proto_registrar_dump_fields();
562 else if (strcmp(argv[2], "ftypes") == 0)
563 proto_registrar_dump_ftypes();
564 else if (strcmp(argv[2], "heuristic-decodes") == 0)
565 dissector_dump_heur_decodes();
566 else if (strcmp(argv[2], "plugins") == 0) {
571 wslua_plugins_dump_all();
574 else if (strcmp(argv[2], "protocols") == 0)
575 proto_registrar_dump_protocols();
576 else if (strcmp(argv[2], "values") == 0)
577 proto_registrar_dump_values();
578 else if (strcmp(argv[2], "?") == 0)
579 glossary_option_help();
580 else if (strcmp(argv[2], "-?") == 0)
581 glossary_option_help();
583 cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
584 exit_status = INVALID_OPTION;
591 /* Load libwireshark settings from the current profile. */
592 prefs_p = epan_load_settings();
595 cap_file_init(&cfile);
597 /* Print format defaults to this. */
598 print_format = PR_FMT_TEXT;
600 output_fields = output_fields_new();
603 * To reset the options parser, set optreset to 1 on platforms that
604 * have optreset (documented in *BSD and macOS, apparently present but
605 * not documented in Solaris - the Illumos repository seems to
606 * suggest that the first Solaris getopt_long(), at least as of 2004,
607 * was based on the NetBSD one, it had optreset) and set optind to 1,
608 * and set optind to 0 otherwise (documented as working in the GNU
609 * getopt_long(). Setting optind to 0 didn't originally work in the
610 * NetBSD one, but that was added later - we don't want to depend on
611 * it if we have optreset).
613 * Also reset opterr to 1, so that error messages are printed by
624 /* Now get our args */
625 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
627 case '2': /* Perform two pass analysis */
628 perform_two_pass_analysis = TRUE;
631 /* already processed; just ignore it now */
635 output_fields_add(output_fields, optarg);
639 if (!output_fields_set_option(output_fields, optarg)) {
640 cmdarg_err("\"%s\" is not a valid field output option=value pair.", optarg);
641 output_fields_list_options(stderr);
642 exit_status = INVALID_OPTION;
647 case 'h': /* Print help and exit */
648 printf("TFShark (Wireshark) %s\n"
649 "Dump and analyze network traffic.\n"
650 "See https://www.wireshark.org for more information.\n",
651 get_ws_vcs_version_info());
655 case 'l': /* "Line-buffer" standard output */
656 /* The ANSI C standard does not appear to *require* that a line-buffered
657 stream be flushed to the host environment whenever a newline is
658 written, it just says that, on such a stream, characters "are
659 intended to be transmitted to or from the host environment as a
660 block when a new-line character is encountered".
662 The Visual C++ 6.0 C implementation doesn't do what is intended;
663 even if you set a stream to be line-buffered, it still doesn't
664 flush the buffer at the end of every line.
666 The whole reason for the "-l" flag in either tcpdump or TShark
667 is to allow the output of a live capture to be piped to a program
668 or script and to have that script see the information for the
669 packet as soon as it's printed, rather than having to wait until
670 a standard I/O buffer fills up.
672 So, if the "-l" flag is specified, we flush the standard output
673 at the end of a packet. This will do the right thing if we're
674 printing packet summary lines, and, as we print the entire protocol
675 tree for a single packet without waiting for anything to happen,
676 it should be as good as line-buffered mode if we're printing
677 protocol trees - arguably even better, as it may do fewer
679 line_buffered = TRUE;
681 case 'o': /* Override preference from command line */
685 switch (prefs_set_pref(optarg, &errmsg)) {
690 case PREFS_SET_SYNTAX_ERR:
691 cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg,
692 errmsg ? ": " : "", errmsg ? errmsg : "");
697 case PREFS_SET_NO_SUCH_PREF:
698 case PREFS_SET_OBSOLETE:
699 cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
700 exit_status = INVALID_OPTION;
706 case 'q': /* Quiet */
709 case 'Q': /* Really quiet */
713 case 'r': /* Read capture file x */
714 cf_name = g_strdup(optarg);
716 case 'R': /* Read file filter */
719 case 'S': /* Set the line Separator to be printed between packets */
720 separator = g_strdup(optarg);
722 case 'T': /* printing Type */
723 if (strcmp(optarg, "text") == 0) {
724 output_action = WRITE_TEXT;
725 print_format = PR_FMT_TEXT;
726 } else if (strcmp(optarg, "ps") == 0) {
727 output_action = WRITE_TEXT;
728 print_format = PR_FMT_PS;
729 } else if (strcmp(optarg, "pdml") == 0) {
730 output_action = WRITE_XML;
731 print_details = TRUE; /* Need details */
732 print_summary = FALSE; /* Don't allow summary */
733 } else if (strcmp(optarg, "psml") == 0) {
734 output_action = WRITE_XML;
735 print_details = FALSE; /* Don't allow details */
736 print_summary = TRUE; /* Need summary */
737 } else if (strcmp(optarg, "fields") == 0) {
738 output_action = WRITE_FIELDS;
739 print_details = TRUE; /* Need full tree info */
740 print_summary = FALSE; /* Don't allow summary */
742 cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg); /* x */
743 cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
744 "\t specified by the -E option.\n"
745 "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
746 "\t details of a decoded packet. This information is equivalent to\n"
747 "\t the packet details printed with the -V flag.\n"
748 "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
749 "\t the packets, or a multi-line view of the details of each of\n"
750 "\t the packets, depending on whether the -V flag was specified.\n"
751 "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
752 "\t summary information of a decoded packet. This information is\n"
753 "\t equivalent to the information shown in the one-line summary\n"
754 "\t printed by default.\n"
755 "\t\"text\" Text of a human-readable one-line summary of each of the\n"
756 "\t packets, or a multi-line view of the details of each of the\n"
757 "\t packets, depending on whether the -V flag was specified.\n"
758 "\t This is the default.");
759 exit_status = INVALID_OPTION;
763 case 'v': /* Show version and exit */
764 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
765 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
766 show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
767 g_string_free(comp_info_str, TRUE);
768 g_string_free(runtime_info_str, TRUE);
770 case 'O': /* Only output these protocols */
771 /* already processed; just ignore it now */
773 case 'V': /* Verbose */
774 /* already processed; just ignore it now */
776 case 'x': /* Print packet data in hex (and ASCII) */
777 /* already processed; just ignore it now */
780 /* already processed; just ignore it now */
786 /* We won't call the init function for the stat this soon
787 as it would disallow MATE's fields (which are registered
788 by the preferences set callback) from being used as
789 part of a tap filter. Instead, we just add the argument
790 to a list of stat arguments. */
791 if (strcmp("help", optarg) == 0) {
792 fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
793 list_stat_cmd_args();
796 if (!process_stat_cmd_arg(optarg)) {
797 cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
798 list_stat_cmd_args();
799 exit_status = INVALID_OPTION;
803 case 'd': /* Decode as rule */
804 case 'K': /* Kerberos keytab file */
805 case 't': /* Time stamp type */
806 case 'u': /* Seconds type */
807 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
808 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
809 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
810 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
811 if (!dissect_opts_handle_opt(opt, optarg)) {
812 exit_status = INVALID_OPTION;
817 case '?': /* Bad flag - print usage message */
819 exit_status = INVALID_OPTION;
825 /* If we specified output fields, but not the output field type... */
826 if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
827 cmdarg_err("Output fields were specified with \"-e\", "
828 "but \"-Tfields\" was not specified.");
830 } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
831 cmdarg_err("\"-Tfields\" was specified, but no fields were "
832 "specified with \"-e\".");
834 exit_status = INVALID_OPTION;
838 /* If no capture filter or display filter has been specified, and there are
839 still command-line arguments, treat them as the tokens of a capture
840 filter (if no "-r" flag was specified) or a display filter (if a "-r"
841 flag was specified. */
843 if (cf_name != NULL) {
844 if (dfilter != NULL) {
845 cmdarg_err("Display filters were specified both with \"-d\" "
846 "and with additional command-line arguments.");
847 exit_status = INVALID_OPTION;
850 dfilter = get_args_as_string(argc, argv, optind);
854 /* if "-q" wasn't specified, we should print packet information */
856 print_packet_info = TRUE;
860 exit_status = INVALID_OPTION;
865 if (output_action != WRITE_TEXT) {
866 cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
867 exit_status = INVALID_OPTION;
872 if (output_only != NULL) {
875 if (!print_details) {
876 cmdarg_err("-O requires -V");
877 exit_status = INVALID_OPTION;
881 output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
882 for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
883 g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
887 if (rfilter != NULL && !perform_two_pass_analysis) {
888 cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
889 exit_status = INVALID_OPTION;
893 /* Notify all registered modules that have had any of their preferences
894 changed either from one of the preferences file or from the command
895 line that their preferences have changed. */
898 /* At this point MATE will have registered its field array so we can
899 have a tap filter with one of MATE's late-registered fields as part
900 of the filter. We can now process all the "-z" arguments. */
901 start_requested_stats();
904 * Enabled and disabled protocols and heuristic dissectors as per
905 * command-line options.
907 if (!setup_enabled_and_disabled_protocols()) {
908 exit_status = INVALID_OPTION;
912 /* Build the column format array */
913 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
915 if (rfilter != NULL) {
916 if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
917 cmdarg_err("%s", err_msg);
919 exit_status = INVALID_FILTER;
923 cfile.rfcode = rfcode;
925 if (dfilter != NULL) {
926 if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
927 cmdarg_err("%s", err_msg);
929 exit_status = INVALID_FILTER;
933 cfile.dfcode = dfcode;
935 if (print_packet_info) {
936 /* If we're printing as text or PostScript, we have
937 to create a print stream. */
938 if (output_action == WRITE_TEXT) {
939 switch (print_format) {
942 print_stream = print_stream_text_stdio_new(stdout);
946 print_stream = print_stream_ps_stdio_new(stdout);
950 g_assert_not_reached();
955 /* We have to dissect each packet if:
957 we're printing information about each packet;
959 we're using a read filter on the packets;
961 we're using a display filter on the packets;
963 we're using any taps that need dissection. */
964 do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
968 * We're reading a capture file.
971 /* TODO: if tfshark is ever changed to give the user a choice of which
972 open_routine reader to use, then the following needs to change. */
973 if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
974 exit_status = OPEN_ERROR;
978 /* Process the packets in the file */
980 /* XXX - for now there is only 1 packet */
981 success = process_file(&cfile, 1, 0);
983 CATCH(OutOfMemoryError) {
987 "Sorry, but TFShark has to terminate now.\n"
989 "Some infos / workarounds can be found at:\n"
990 "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
996 /* We still dump out the results of taps, etc., as we might have
997 read some packets; however, we exit with an error status. */
1004 if (cfile.frames != NULL) {
1005 free_frame_data_sequence(cfile.frames);
1006 cfile.frames = NULL;
1009 draw_tap_listeners(TRUE);
1010 funnel_dump_all_text_windows();
1013 destroy_print_stream(print_stream);
1014 epan_free(cfile.epan);
1020 output_fields_free(output_fields);
1021 output_fields = NULL;
1023 col_cleanup(&cfile.cinfo);
1028 static const nstime_t *
1029 tfshark_get_frame_ts(struct _capture_file *cf, guint32 frame_num)
1031 if (ref && ref->num == frame_num)
1032 return &ref->abs_ts;
1034 if (prev_dis && prev_dis->num == frame_num)
1035 return &prev_dis->abs_ts;
1037 if (prev_cap && prev_cap->num == frame_num)
1038 return &prev_cap->abs_ts;
1041 frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
1043 return (fd) ? &fd->abs_ts : NULL;
1050 no_interface_name(struct _capture_file *cf _U_, guint32 interface_id _U_)
1056 tfshark_epan_new(capture_file *cf)
1058 epan_t *epan = epan_new();
1061 epan->get_frame_ts = tfshark_get_frame_ts;
1062 epan->get_interface_name = no_interface_name;
1063 epan->get_user_comment = NULL;
1069 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
1070 gint64 offset, struct wtap_pkthdr *whdr,
1077 /* The frame number of this packet is one more than the count of
1078 frames in this packet. */
1079 framenum = cf->count + 1;
1081 /* If we're not running a display filter and we're not printing any
1082 packet information, we don't need to do a dissection. This means
1083 that all packets can be marked as 'passed'. */
1086 frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
1088 /* If we're going to print packet information, or we're going to
1089 run a read filter, or display filter, or we're going to process taps, set up to
1090 do a dissection and do so. */
1092 /* If we're running a read filter, prime the epan_dissect_t with that
1095 epan_dissect_prime_with_dfilter(edt, cf->rfcode);
1097 /* This is the first pass, so prime the epan_dissect_t with the
1098 hfids postdissectors want on the first pass. */
1099 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1101 frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
1103 if (ref == &fdlocal) {
1104 ref_frame = fdlocal;
1108 epan_dissect_file_run(edt, whdr, file_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
1110 /* Run the read filter if we have one. */
1112 passed = dfilter_apply_edt(cf->rfcode, edt);
1116 frame_data_set_after_dissect(&fdlocal, &cum_bytes);
1117 prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
1119 /* If we're not doing dissection then there won't be any dependent frames.
1120 * More importantly, edt.pi.dependent_frames won't be initialized because
1121 * epan hasn't been initialized.
1124 g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
1129 /* if we don't add it to the frame_data_sequence, clean it up right now
1131 frame_data_destroy(&fdlocal);
1135 epan_dissect_reset(edt);
1141 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
1142 frame_data *fdata, struct wtap_pkthdr *phdr,
1143 Buffer *buf, guint tap_flags)
1148 /* If we're not running a display filter and we're not printing any
1149 packet information, we don't need to do a dissection. This means
1150 that all packets can be marked as 'passed'. */
1153 /* If we're going to print packet information, or we're going to
1154 run a read filter, or we're going to process taps, set up to
1155 do a dissection and do so. */
1158 /* If we're running a display filter, prime the epan_dissect_t with that
1161 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1163 /* This is the first and only pass, so prime the epan_dissect_t
1164 with the hfids postdissectors want on the first pass. */
1165 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1167 col_custom_prime_edt(edt, &cf->cinfo);
1169 /* We only need the columns if either
1170 1) some tap needs the columns
1172 2) we're printing packet info but we're *not* verbose; in verbose
1173 mode, we print the protocol tree, not the protocol summary.
1175 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
1180 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1187 epan_dissect_file_run_with_taps(edt, phdr, file_tvbuff_new_buffer(fdata, buf), fdata, cinfo);
1189 /* Run the read/display filter if we have one. */
1191 passed = dfilter_apply_edt(cf->dfcode, edt);
1195 frame_data_set_after_dissect(fdata, &cum_bytes);
1196 /* Process this packet. */
1197 if (print_packet_info) {
1198 /* We're printing packet information; print the information for
1200 print_packet(cf, edt);
1202 /* If we're doing "line-buffering", flush the standard output
1203 after every packet. See the comment above, for the "-l"
1204 option, for an explanation of why we do that. */
1208 if (ferror(stdout)) {
1209 show_print_file_io_error(errno);
1218 epan_dissect_reset(edt);
1220 return passed || fdata->flags.dependent_of_displayed;
1224 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)
1226 /* int bytes_read; */
1227 gint64 packet_size = wtap_file_size(cf->wth, err);
1229 *data_buffer = (guint8*)g_malloc((gsize)packet_size);
1230 /* bytes_read =*/ file_read(*data_buffer, (unsigned int)packet_size, cf->wth->fh);
1232 #if 0 /* no more filetap */
1233 if (bytes_read < 0) {
1234 *err = file_error(cf->wth->fh, err_info);
1236 *err = FTAP_ERR_SHORT_READ;
1238 } else if (bytes_read == 0) {
1239 /* Done with file, no error */
1244 /* XXX - SET FRAME SIZE EQUAL TO TOTAL FILE SIZE */
1245 file_phdr->caplen = (guint32)packet_size;
1246 file_phdr->len = (guint32)packet_size;
1249 * Set the packet encapsulation to the file's encapsulation
1250 * value; if that's not WTAP_ENCAP_PER_PACKET, it's the
1251 * right answer (and means that the read routine for this
1252 * capture file type doesn't have to set it), and if it
1253 * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it
1256 wth->phdr.pkt_encap = wth->file_encap;
1258 if (!wth->subtype_read(wth, err, err_info, data_offset)) {
1260 * If we didn't get an error indication, we read
1261 * the last packet. See if there's any deferred
1262 * error, as might, for example, occur if we're
1263 * reading a compressed file, and we got an error
1264 * reading compressed data from the file, but
1265 * got enough compressed data to decompress the
1266 * last packet of the file.
1269 *err = file_error(wth->fh, err_info);
1270 return FALSE; /* failure */
1274 * It makes no sense for the captured data length to be bigger
1275 * than the actual data length.
1277 if (wth->phdr.caplen > wth->phdr.len)
1278 wth->phdr.caplen = wth->phdr.len;
1281 * Make sure that it's not WTAP_ENCAP_PER_PACKET, as that
1282 * probably means the file has that encapsulation type
1283 * but the read routine didn't set this packet's
1284 * encapsulation type.
1286 g_assert(wth->phdr.pkt_encap != WTAP_ENCAP_PER_PACKET);
1289 return TRUE; /* success */
1293 process_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
1297 gchar *err_info = NULL;
1298 gint64 data_offset = 0;
1299 gboolean filtering_tap_listeners;
1302 epan_dissect_t *edt = NULL;
1303 struct wtap_pkthdr file_phdr;
1306 if (print_packet_info) {
1307 if (!write_preamble(cf)) {
1309 show_print_file_io_error(err);
1314 /* Do we have any tap listeners with filters? */
1315 filtering_tap_listeners = have_filtering_tap_listeners();
1317 /* Get the union of the flags for all tap listeners. */
1318 tap_flags = union_of_tap_listener_flags();
1320 wtap_phdr_init(&file_phdr);
1322 /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1323 file_phdr.pkt_encap = 1234;
1325 if (perform_two_pass_analysis) {
1328 /* Allocate a frame_data_sequence for all the frames. */
1329 cf->frames = new_frame_data_sequence();
1331 if (do_dissection) {
1332 gboolean create_proto_tree;
1335 * Determine whether we need to create a protocol tree.
1338 * we're going to apply a read filter;
1340 * a postdissector wants field values or protocols
1341 * on the first pass.
1344 (cf->rfcode != NULL || postdissectors_want_hfids());
1346 /* We're not going to display the protocol tree on this pass,
1347 so it's not going to be "visible". */
1348 edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
1350 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1351 if (process_packet_first_pass(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1352 wtap_buf_ptr(cf->wth))) {
1354 /* Stop reading if we have the maximum number of packets;
1355 * When the -c option has not been used, max_packet_count
1356 * starts at 0, which practically means, never stop reading.
1357 * (unless we roll over max_packet_count ?)
1359 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1360 err = 0; /* This is not an error */
1367 epan_dissect_free(edt);
1372 /* Close the sequential I/O side, to free up memory it requires. */
1373 wtap_sequential_close(cf->wth);
1376 /* Allow the protocol dissectors to free up memory that they
1377 * don't need after the sequential run-through of the packets. */
1378 postseq_cleanup_all_protocols();
1382 ws_buffer_init(&buf, 1500);
1384 if (do_dissection) {
1385 gboolean create_proto_tree;
1388 * Determine whether we need to create a protocol tree.
1391 * we're going to apply a display filter;
1393 * we're going to print the protocol tree;
1395 * one of the tap listeners requires a protocol tree;
1397 * we have custom columns (which require field values, which
1398 * currently requires that we build a protocol tree).
1401 (cf->dfcode || print_details || filtering_tap_listeners ||
1402 (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo));
1404 /* The protocol tree will be "visible", i.e., printed, only if we're
1405 printing packet details, which is true if we're printing stuff
1406 ("print_packet_info" is true) and we're in verbose mode
1407 ("packet_details" is true). */
1408 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1411 for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
1412 fdata = frame_data_sequence_find(cf->frames, framenum);
1414 if (wtap_seek_read(cf->wth, fdata->file_off,
1415 &buf, fdata->cap_len, &err, &err_info)) {
1416 process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1419 if (!process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf,
1426 epan_dissect_free(edt);
1430 ws_buffer_free(&buf);
1435 if (do_dissection) {
1436 gboolean create_proto_tree;
1439 * Determine whether we need to create a protocol tree.
1442 * we're going to apply a read filter;
1444 * we're going to apply a display filter;
1446 * we're going to print the protocol tree;
1448 * one of the tap listeners is going to apply a filter;
1450 * one of the tap listeners requires a protocol tree;
1452 * a postdissector wants field values or protocols
1453 * on the first pass;
1455 * we have custom columns (which require field values, which
1456 * currently requires that we build a protocol tree).
1459 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
1460 (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
1461 have_custom_cols(&cf->cinfo));
1463 /* The protocol tree will be "visible", i.e., printed, only if we're
1464 printing packet details, which is true if we're printing stuff
1465 ("print_packet_info" is true) and we're in verbose mode
1466 ("packet_details" is true). */
1467 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1470 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1474 if (!process_packet_single_pass(cf, edt, data_offset,
1475 &file_phdr/*wtap_phdr(cf->wth)*/,
1476 raw_data, tap_flags))
1479 /* Stop reading if we have the maximum number of packets;
1480 * When the -c option has not been used, max_packet_count
1481 * starts at 0, which practically means, never stop reading.
1482 * (unless we roll over max_packet_count ?)
1484 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1485 err = 0; /* This is not an error */
1491 epan_dissect_free(edt);
1496 wtap_phdr_cleanup(&file_phdr);
1500 * Print a message noting that the read failed somewhere along the line.
1502 * If we're printing packet data, and the standard output and error are
1503 * going to the same place, flush the standard output, so everything
1504 * buffered up is written, and then print a newline to the standard error
1505 * before printing the error message, to separate it from the packet
1506 * data. (Alas, that only works on UN*X; st_dev is meaningless, and
1507 * the _fstat() documentation at Microsoft doesn't indicate whether
1508 * st_ino is even supported.)
1511 if (print_packet_info) {
1512 ws_statb64 stat_stdout, stat_stderr;
1514 if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
1515 if (stat_stdout.st_dev == stat_stderr.st_dev &&
1516 stat_stdout.st_ino == stat_stderr.st_ino) {
1518 fprintf(stderr, "\n");
1526 case FTAP_ERR_UNSUPPORTED:
1527 cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
1528 cf->filename, err_info);
1532 case FTAP_ERR_UNSUPPORTED_ENCAP:
1533 cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
1534 cf->filename, err_info);
1538 case FTAP_ERR_CANT_READ:
1539 cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
1543 case FTAP_ERR_SHORT_READ:
1544 cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
1548 case FTAP_ERR_BAD_FILE:
1549 cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
1550 cf->filename, err_info);
1554 case FTAP_ERR_DECOMPRESS:
1555 cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
1556 "(%s)", cf->filename, err_info);
1560 cmdarg_err("An error occurred while reading the file \"%s\": %s.",
1561 cf->filename, ftap_strerror(err));
1566 if (print_packet_info) {
1567 if (!write_finale()) {
1569 show_print_file_io_error(err);
1575 wtap_close(cf->wth);
1582 process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset,
1583 struct wtap_pkthdr *whdr, const guchar *pd,
1590 /* Count this packet. */
1593 /* If we're not running a display filter and we're not printing any
1594 packet information, we don't need to do a dissection. This means
1595 that all packets can be marked as 'passed'. */
1598 frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
1600 /* If we're going to print packet information, or we're going to
1601 run a read filter, or we're going to process taps, set up to
1602 do a dissection and do so. */
1604 /* If we're running a filter, prime the epan_dissect_t with that
1607 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1609 col_custom_prime_edt(edt, &cf->cinfo);
1611 /* We only need the columns if either
1612 1) some tap needs the columns
1614 2) we're printing packet info but we're *not* verbose; in verbose
1615 mode, we print the protocol tree, not the protocol summary.
1617 3) there is a column mapped as an individual field */
1618 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
1623 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
1625 if (ref == &fdata) {
1630 epan_dissect_file_run_with_taps(edt, whdr, frame_tvbuff_new(&fdata, pd), &fdata, cinfo);
1632 /* Run the filter if we have it. */
1634 passed = dfilter_apply_edt(cf->dfcode, edt);
1638 frame_data_set_after_dissect(&fdata, &cum_bytes);
1640 /* Process this packet. */
1641 if (print_packet_info) {
1642 /* We're printing packet information; print the information for
1644 print_packet(cf, edt);
1646 /* If we're doing "line-buffering", flush the standard output
1647 after every packet. See the comment above, for the "-l"
1648 option, for an explanation of why we do that. */
1652 if (ferror(stdout)) {
1653 show_print_file_io_error(errno);
1658 /* this must be set after print_packet() [bug #8160] */
1659 prev_dis_frame = fdata;
1660 prev_dis = &prev_dis_frame;
1663 prev_cap_frame = fdata;
1664 prev_cap = &prev_cap_frame;
1667 epan_dissect_reset(edt);
1668 frame_data_destroy(&fdata);
1674 write_preamble(capture_file *cf)
1676 switch (output_action) {
1679 return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
1683 write_pdml_preamble(stdout, cf->filename);
1685 write_psml_preamble(&cf->cinfo, stdout);
1686 return !ferror(stdout);
1689 write_fields_preamble(output_fields, stdout);
1690 return !ferror(stdout);
1693 g_assert_not_reached();
1699 get_line_buf(size_t len)
1701 static char *line_bufp = NULL;
1702 static size_t line_buf_len = 256;
1703 size_t new_line_buf_len;
1705 for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
1706 new_line_buf_len *= 2)
1708 if (line_bufp == NULL) {
1709 line_buf_len = new_line_buf_len;
1710 line_bufp = (char *)g_malloc(line_buf_len + 1);
1712 if (new_line_buf_len > line_buf_len) {
1713 line_buf_len = new_line_buf_len;
1714 line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
1721 put_string(char *dest, const char *str, size_t str_len)
1723 memcpy(dest, str, str_len);
1724 dest[str_len] = '\0';
1728 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1732 for (i = str_len; i < str_with_spaces; i++)
1735 put_string(dest, str, str_len);
1739 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1743 memcpy(dest, str, str_len);
1744 for (i = str_len; i < str_with_spaces; i++)
1747 dest[str_with_spaces] = '\0';
1751 print_columns(capture_file *cf)
1758 col_item_t* col_item;
1760 line_bufp = get_line_buf(256);
1763 for (i = 0; i < cf->cinfo.num_cols; i++) {
1764 col_item = &cf->cinfo.columns[i];
1765 /* Skip columns not marked as visible. */
1766 if (!get_column_visible(i))
1768 switch (col_item->col_fmt) {
1770 column_len = col_len = strlen(col_item->col_data);
1773 line_bufp = get_line_buf(buf_offset + column_len);
1774 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1780 case COL_ABS_YMD_TIME: /* XXX - wider */
1781 case COL_ABS_YDOY_TIME: /* XXX - wider */
1783 case COL_UTC_YMD_TIME: /* XXX - wider */
1784 case COL_UTC_YDOY_TIME: /* XXX - wider */
1785 column_len = col_len = strlen(col_item->col_data);
1786 if (column_len < 10)
1788 line_bufp = get_line_buf(buf_offset + column_len);
1789 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1795 case COL_DEF_DL_SRC:
1796 case COL_RES_DL_SRC:
1797 case COL_UNRES_DL_SRC:
1798 case COL_DEF_NET_SRC:
1799 case COL_RES_NET_SRC:
1800 case COL_UNRES_NET_SRC:
1801 column_len = col_len = strlen(col_item->col_data);
1802 if (column_len < 12)
1804 line_bufp = get_line_buf(buf_offset + column_len);
1805 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1811 case COL_DEF_DL_DST:
1812 case COL_RES_DL_DST:
1813 case COL_UNRES_DL_DST:
1814 case COL_DEF_NET_DST:
1815 case COL_RES_NET_DST:
1816 case COL_UNRES_NET_DST:
1817 column_len = col_len = strlen(col_item->col_data);
1818 if (column_len < 12)
1820 line_bufp = get_line_buf(buf_offset + column_len);
1821 put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1825 column_len = strlen(col_item->col_data);
1826 line_bufp = get_line_buf(buf_offset + column_len);
1827 put_string(line_bufp + buf_offset, col_item->col_data, column_len);
1830 buf_offset += column_len;
1831 if (i != cf->cinfo.num_cols - 1) {
1833 * This isn't the last column, so we need to print a
1834 * separator between this column and the next.
1836 * If we printed a network source and are printing a
1837 * network destination of the same type next, separate
1838 * them with " -> "; if we printed a network destination
1839 * and are printing a network source of the same type
1840 * next, separate them with " <- "; otherwise separate them
1843 * We add enough space to the buffer for " <- " or " -> ",
1844 * even if we're only adding " ".
1846 line_bufp = get_line_buf(buf_offset + 4);
1847 switch (col_item->col_fmt) {
1852 switch (cf->cinfo.columns[i+1].col_fmt) {
1857 put_string(line_bufp + buf_offset, " -> ", 4);
1862 put_string(line_bufp + buf_offset, " ", 1);
1868 case COL_DEF_DL_SRC:
1869 case COL_RES_DL_SRC:
1870 case COL_UNRES_DL_SRC:
1871 switch (cf->cinfo.columns[i+1].col_fmt) {
1873 case COL_DEF_DL_DST:
1874 case COL_RES_DL_DST:
1875 case COL_UNRES_DL_DST:
1876 put_string(line_bufp + buf_offset, " -> ", 4);
1881 put_string(line_bufp + buf_offset, " ", 1);
1887 case COL_DEF_NET_SRC:
1888 case COL_RES_NET_SRC:
1889 case COL_UNRES_NET_SRC:
1890 switch (cf->cinfo.columns[i+1].col_fmt) {
1892 case COL_DEF_NET_DST:
1893 case COL_RES_NET_DST:
1894 case COL_UNRES_NET_DST:
1895 put_string(line_bufp + buf_offset, " -> ", 4);
1900 put_string(line_bufp + buf_offset, " ", 1);
1909 switch (cf->cinfo.columns[i+1].col_fmt) {
1914 put_string(line_bufp + buf_offset, " <- ", 4);
1919 put_string(line_bufp + buf_offset, " ", 1);
1925 case COL_DEF_DL_DST:
1926 case COL_RES_DL_DST:
1927 case COL_UNRES_DL_DST:
1928 switch (cf->cinfo.columns[i+1].col_fmt) {
1930 case COL_DEF_DL_SRC:
1931 case COL_RES_DL_SRC:
1932 case COL_UNRES_DL_SRC:
1933 put_string(line_bufp + buf_offset, " <- ", 4);
1938 put_string(line_bufp + buf_offset, " ", 1);
1944 case COL_DEF_NET_DST:
1945 case COL_RES_NET_DST:
1946 case COL_UNRES_NET_DST:
1947 switch (cf->cinfo.columns[i+1].col_fmt) {
1949 case COL_DEF_NET_SRC:
1950 case COL_RES_NET_SRC:
1951 case COL_UNRES_NET_SRC:
1952 put_string(line_bufp + buf_offset, " <- ", 4);
1957 put_string(line_bufp + buf_offset, " ", 1);
1964 put_string(line_bufp + buf_offset, " ", 1);
1970 return print_line(print_stream, 0, line_bufp);
1974 print_packet(capture_file *cf, epan_dissect_t *edt)
1976 if (print_summary || output_fields_has_cols(output_fields)) {
1977 /* Just fill in the columns. */
1978 epan_dissect_fill_in_columns(edt, FALSE, TRUE);
1980 if (print_summary) {
1981 /* Now print them. */
1982 switch (output_action) {
1985 if (!print_columns(cf))
1990 write_psml_columns(edt, stdout, FALSE);
1991 return !ferror(stdout);
1992 case WRITE_FIELDS: /*No non-verbose "fields" format */
1993 g_assert_not_reached();
1998 if (print_details) {
1999 /* Print the information in the protocol tree. */
2000 switch (output_action) {
2003 if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
2004 print_hex, edt, output_only_tables, print_stream))
2007 if (!print_line(print_stream, 0, separator))
2013 write_pdml_proto_tree(NULL, NULL, PF_NONE, edt, stdout, FALSE);
2015 return !ferror(stdout);
2017 write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
2019 return !ferror(stdout);
2023 if (print_summary || print_details) {
2024 if (!print_line(print_stream, 0, ""))
2027 if (!print_hex_data(print_stream, edt))
2029 if (!print_line(print_stream, 0, separator))
2038 switch (output_action) {
2041 return print_finale(print_stream);
2045 write_pdml_finale(stdout);
2047 write_psml_finale(stdout);
2048 return !ferror(stdout);
2051 write_fields_finale(output_fields, stdout);
2052 return !ferror(stdout);
2055 g_assert_not_reached();
2061 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
2064 char err_msg[2048+1];
2066 /* The open isn't implemented yet. Fill in the information for this file. */
2068 /* Create new epan session for dissection. */
2069 epan_free(cf->epan);
2070 cf->epan = tfshark_epan_new(cf);
2072 cf->wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2073 cf->f_datalen = 0; /* not used, but set it anyway */
2075 /* Set the file name because we need it to set the follow stream filter.
2076 XXX - is that still true? We need it for other reasons, though,
2078 cf->filename = g_strdup(fname);
2080 /* Indicate whether it's a permanent or temporary file. */
2081 cf->is_tempfile = is_tempfile;
2083 /* No user changes yet. */
2084 cf->unsaved_changes = FALSE;
2086 cf->cd_t = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2087 cf->open_type = type;
2089 cf->drops_known = FALSE;
2091 cf->snap = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2092 nstime_set_zero(&cf->elapsed_time);
2097 cf->state = FILE_READ_IN_PROGRESS;
2102 g_snprintf(err_msg, sizeof err_msg,
2103 cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
2104 cmdarg_err("%s", err_msg);
2109 show_print_file_io_error(int err)
2114 cmdarg_err("Not all the packets could be printed because there is "
2115 "no space left on the file system.");
2120 cmdarg_err("Not all the packets could be printed because you are "
2121 "too close to, or over your disk quota.");
2126 cmdarg_err("An error occurred while printing packets: %s.",
2133 cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
2137 /* static char errmsg_errno[1024+1]; */
2141 /* Wiretap error. */
2144 case FTAP_ERR_NOT_REGULAR_FILE:
2145 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
2148 case FTAP_ERR_RANDOM_OPEN_PIPE:
2149 /* Seen only when opening a capture file for reading. */
2150 errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
2153 case FTAP_ERR_FILE_UNKNOWN_FORMAT:
2154 /* Seen only when opening a capture file for reading. */
2155 errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
2158 case FTAP_ERR_UNSUPPORTED:
2159 /* Seen only when opening a capture file for reading. */
2160 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2161 "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
2164 errmsg = errmsg_errno;
2167 case FTAP_ERR_CANT_WRITE_TO_PIPE:
2168 /* Seen only when opening a capture file for writing. */
2169 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2170 "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
2171 "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
2172 errmsg = errmsg_errno;
2175 case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
2176 /* Seen only when opening a capture file for writing. */
2177 errmsg = "TFShark doesn't support writing capture files in that format.";
2180 case FTAP_ERR_UNSUPPORTED_ENCAP:
2182 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2183 "TFShark can't save this capture as a \"%s\" file.",
2184 ftap_file_type_subtype_short_string(file_type));
2186 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2187 "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
2191 errmsg = errmsg_errno;
2194 case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
2196 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2197 "TFShark can't save this capture as a \"%s\" file.",
2198 ftap_file_type_subtype_short_string(file_type));
2199 errmsg = errmsg_errno;
2201 errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
2204 case FTAP_ERR_BAD_FILE:
2205 /* Seen only when opening a capture file for reading. */
2206 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2207 "The file \"%%s\" appears to be damaged or corrupt.\n"
2210 errmsg = errmsg_errno;
2213 case FTAP_ERR_CANT_OPEN:
2215 errmsg = "The file \"%s\" could not be created for some unknown reason.";
2217 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
2220 case FTAP_ERR_SHORT_READ:
2221 errmsg = "The file \"%s\" appears to have been cut short"
2222 " in the middle of a packet or other data.";
2225 case FTAP_ERR_SHORT_WRITE:
2226 errmsg = "A full header couldn't be written to the file \"%s\".";
2229 case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
2230 errmsg = "This file type cannot be written as a compressed file.";
2233 case FTAP_ERR_DECOMPRESS:
2234 /* Seen only when opening a capture file for reading. */
2235 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2236 "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
2239 errmsg = errmsg_errno;
2243 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2244 "The file \"%%s\" could not be %s: %s.",
2245 for_writing ? "created" : "opened",
2246 ftap_strerror(err));
2247 errmsg = errmsg_errno;
2252 errmsg = file_open_error_message(err, for_writing);
2257 * General errors and warnings are reported with an console message
2261 failure_warning_message(const char *msg_format, va_list ap)
2263 fprintf(stderr, "tfshark: ");
2264 vfprintf(stderr, msg_format, ap);
2265 fprintf(stderr, "\n");
2269 * Open/create errors are reported with an console message in TFShark.
2272 open_failure_message(const char *filename, int err, gboolean for_writing)
2274 fprintf(stderr, "tfshark: ");
2275 fprintf(stderr, file_open_error_message(err, for_writing), filename);
2276 fprintf(stderr, "\n");
2280 * Read errors are reported with an console message in TFShark.
2283 read_failure_message(const char *filename, int err)
2285 cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
2286 filename, g_strerror(err));
2290 * Write errors are reported with an console message in TFShark.
2293 write_failure_message(const char *filename, int err)
2295 cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
2296 filename, g_strerror(err));
2300 * Report additional information for an error in command-line arguments.
2303 failure_message_cont(const char *msg_format, va_list ap)
2305 vfprintf(stderr, msg_format, ap);
2306 fprintf(stderr, "\n");
2310 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2315 * indent-tabs-mode: nil
2318 * vi: set shiftwidth=2 tabstop=8 expandtab:
2319 * :indentSize=2:tabSize=8:noTabs=true: