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_err.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 static guint32 cum_bytes;
98 static const frame_data *ref;
99 static frame_data ref_frame;
100 static frame_data *prev_dis;
101 static frame_data prev_dis_frame;
102 static frame_data *prev_cap;
103 static frame_data prev_cap_frame;
105 static gboolean perform_two_pass_analysis;
108 * The way the packet decode is to be written.
111 WRITE_TEXT, /* summary or detail text */
112 WRITE_XML, /* PDML or PSML */
113 WRITE_FIELDS /* User defined list of fields */
114 /* Add CSV and the like here */
117 static output_action_e output_action;
118 static gboolean do_dissection; /* TRUE if we have to dissect each packet */
119 static gboolean print_packet_info; /* TRUE if we're to print packet information */
120 static gint print_summary = -1; /* TRUE if we're to print packet summary information */
121 static gboolean print_details; /* TRUE if we're to print packet details information */
122 static gboolean print_hex; /* TRUE if we're to print hex/ascci information */
123 static gboolean line_buffered;
124 static gboolean really_quiet = FALSE;
126 static print_format_e print_format = PR_FMT_TEXT;
127 static print_stream_t *print_stream;
129 static output_fields_t* output_fields = NULL;
131 /* The line separator used between packets, changeable via the -S option */
132 static const char *separator = "";
134 static int load_cap_file(capture_file *, int, gint64);
135 static gboolean process_packet(capture_file *cf, epan_dissect_t *edt, gint64 offset,
136 struct wtap_pkthdr *whdr, const guchar *pd, guint tap_flags);
137 static void show_print_file_io_error(int err);
138 static gboolean write_preamble(capture_file *cf);
139 static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
140 static gboolean write_finale(void);
141 static const char *cf_open_error_message(int err, gchar *err_info,
142 gboolean for_writing, int file_type);
144 static void open_failure_message(const char *filename, int err,
145 gboolean for_writing);
146 static void failure_message(const char *msg_format, va_list ap);
147 static void read_failure_message(const char *filename, int err);
148 static void write_failure_message(const char *filename, int err);
149 static void failure_message_cont(const char *msg_format, va_list ap);
153 static GHashTable *output_only_tables = NULL;
157 const char *sstr; /* The short string */
158 const char *lstr; /* The long string */
162 string_compare(gconstpointer a, gconstpointer b)
164 return strcmp(((const struct string_elem *)a)->sstr,
165 ((const struct string_elem *)b)->sstr);
169 string_elem_print(gpointer data, gpointer not_used _U_)
171 fprintf(stderr, " %s - %s\n",
172 ((struct string_elem *)data)->sstr,
173 ((struct string_elem *)data)->lstr);
178 print_usage(FILE *output)
180 fprintf(output, "\n");
181 fprintf(output, "Usage: tfshark [options] ...\n");
182 fprintf(output, "\n");
184 /*fprintf(output, "\n");*/
185 fprintf(output, "Input file:\n");
186 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin!)\n");
188 fprintf(output, "\n");
189 fprintf(output, "Processing:\n");
190 fprintf(output, " -2 perform a two-pass analysis\n");
191 fprintf(output, " -R <read filter> packet Read filter in Wireshark display filter syntax\n");
192 fprintf(output, " -Y <display filter> packet displaY filter in Wireshark display filter\n");
193 fprintf(output, " syntax\n");
194 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
195 fprintf(output, " \"Decode As\", see the man page for details\n");
196 fprintf(output, " Example: tcp.port==8888,http\n");
198 /*fprintf(output, "\n");*/
199 fprintf(output, "Output:\n");
200 fprintf(output, " -C <config profile> start with specified configuration profile\n");
201 fprintf(output, " -V add output of packet tree (Packet Details)\n");
202 fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
203 fprintf(output, " separated\n");
204 fprintf(output, " -S <separator> the line separator to print between packets\n");
205 fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
206 fprintf(output, " -T pdml|ps|psml|text|fields\n");
207 fprintf(output, " format of text output (def: text)\n");
208 fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
209 fprintf(output, " _ws.col.Info)\n");
210 fprintf(output, " this option can be repeated to print multiple fields\n");
211 fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
212 fprintf(output, " header=y|n switch headers on and off\n");
213 fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
214 fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
215 fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
216 fprintf(output, " aggregator\n");
217 fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
218 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
219 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
220 fprintf(output, " -l flush standard output after each packet\n");
221 fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
222 fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
223 fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
224 fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
226 fprintf(output, "\n");
227 fprintf(output, "Miscellaneous:\n");
228 fprintf(output, " -h display this help and exit\n");
229 fprintf(output, " -v display version info and exit\n");
230 fprintf(output, " -o <name>:<value> ... override preference setting\n");
231 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
232 fprintf(output, " -G [report] dump one of several available reports and exit\n");
233 fprintf(output, " default report=\"fields\"\n");
234 fprintf(output, " use \"-G ?\" for more help\n");
238 glossary_option_help(void)
244 fprintf(output, "TFShark (Wireshark) %s\n", get_ws_vcs_version_info());
246 fprintf(output, "\n");
247 fprintf(output, "Usage: tfshark -G [report]\n");
248 fprintf(output, "\n");
249 fprintf(output, "Glossary table reports:\n");
250 fprintf(output, " -G column-formats dump column format codes and exit\n");
251 fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
252 fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
253 fprintf(output, " -G fields dump fields glossary and exit\n");
254 fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
255 fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
256 fprintf(output, " -G plugins dump installed plugins and exit\n");
257 fprintf(output, " -G protocols dump protocols in registration database and exit\n");
258 fprintf(output, " -G values dump value, range, true/false strings and exit\n");
259 fprintf(output, "\n");
260 fprintf(output, "Preference reports:\n");
261 fprintf(output, " -G currentprefs dump current preferences and exit\n");
262 fprintf(output, " -G defaultprefs dump default preferences and exit\n");
263 fprintf(output, "\n");
267 tfshark_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
268 const gchar *message, gpointer user_data)
270 /* ignore log message, if log_level isn't interesting based
271 upon the console log preferences.
272 If the preferences haven't been loaded loaded yet, display the
275 The default console_log_level preference value is such that only
276 ERROR, CRITICAL and WARNING level messages are processed;
277 MESSAGE, INFO and DEBUG level messages are ignored.
279 XXX: Aug 07, 2009: Prior tshark g_log code was hardwired to process only
280 ERROR and CRITICAL level messages so the current code is a behavioral
281 change. The current behavior is the same as in Wireshark.
283 if ((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
284 prefs.console_log_level != 0) {
288 g_log_default_handler(log_domain, log_level, message, user_data);
293 print_current_user(void) {
294 gchar *cur_user, *cur_group;
296 if (started_with_special_privs()) {
297 cur_user = get_cur_username();
298 cur_group = get_cur_groupname();
299 fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
300 cur_user, cur_group);
303 if (running_with_special_privs()) {
304 fprintf(stderr, " This could be dangerous.");
306 fprintf(stderr, "\n");
311 get_tfshark_runtime_version_info(GString *str)
313 /* stuff used by libwireshark */
314 epan_get_runtime_version_info(str);
318 main(int argc, char *argv[])
320 GString *comp_info_str;
321 GString *runtime_info_str;
322 char *init_progfile_dir_error;
324 static const struct option long_options[] = {
325 {"help", no_argument, NULL, 'h'},
326 {"version", no_argument, NULL, 'v'},
329 gboolean arg_error = FALSE;
331 char *gpf_path, *pf_path;
332 char *gdp_path, *dp_path;
333 int gpf_open_errno, gpf_read_errno;
334 int pf_open_errno, pf_read_errno;
335 int gdp_open_errno, gdp_read_errno;
336 int dp_open_errno, dp_read_errno;
338 volatile int exit_status = 0;
339 gboolean quiet = FALSE;
340 gchar *volatile cf_name = NULL;
341 gchar *rfilter = NULL;
342 gchar *dfilter = NULL;
343 dfilter_t *rfcode = NULL;
344 dfilter_t *dfcode = NULL;
348 gchar *output_only = NULL;
351 * The leading + ensures that getopt_long() does not permute the argv[]
354 * We have to make sure that the first getopt_long() preserves the content
355 * of argv[] for the subsequent getopt_long() call.
357 * We use getopt_long() in both cases to ensure that we're using a routine
358 * whose permutation behavior we can control in the same fashion on all
359 * platforms, and so that, if we ever need to process a long argument before
360 * doing further initialization, we can do so.
362 * Glibc and Solaris libc document that a leading + disables permutation
363 * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
364 * and OS X don't document it, but do so anyway.
366 * We do *not* use a leading - because the behavior of a leading - is
367 * platform-dependent.
369 #define OPTSTRING "+2C:d:e:E:hK:lo:O:qQr:R:S:t:T:u:vVxX:Y:z:"
371 static const char optstring[] = OPTSTRING;
373 /* Set the C-language locale to the native environment. */
374 setlocale(LC_ALL, "");
376 cmdarg_err_init(failure_message, failure_message_cont);
379 arg_list_utf_16to8(argc, argv);
380 create_app_running_mutex();
381 #if !GLIB_CHECK_VERSION(2,31,0)
387 * Get credential information for later use, and drop privileges
388 * before doing anything else.
389 * Let the user know if anything happened.
391 init_process_policies();
392 relinquish_special_privs_perm();
393 print_current_user();
396 * Attempt to get the pathname of the executable file.
398 init_progfile_dir_error = init_progfile_dir(argv[0], main);
399 if (init_progfile_dir_error != NULL) {
400 fprintf(stderr, "tfshark: Can't get pathname of tfshark program: %s.\n",
401 init_progfile_dir_error);
404 initialize_funnel_ops();
406 /* Get the compile-time version information string */
407 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
409 /* Get the run-time version information string */
410 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
412 /* Add it to the information to be reported on a crash. */
413 ws_add_crash_info("TFShark (Wireshark) %s\n"
418 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
419 g_string_free(comp_info_str, TRUE);
420 g_string_free(runtime_info_str, TRUE);
423 * In order to have the -X opts assigned before the wslua machine starts
424 * we need to call getopts before epan_init() gets called.
426 * In order to handle, for example, -o options, we also need to call it
427 * *after* epan_init() gets called, so that the dissectors have had a
428 * chance to register their preferences.
430 * XXX - can we do this all with one getopt_long() call, saving the
431 * arguments we can't handle until after initializing libwireshark,
432 * and then process them after initializing libwireshark?
436 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
438 case 'C': /* Configuration Profile */
439 if (profile_exists (optarg, FALSE)) {
440 set_profile_name (optarg);
442 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
446 case 'O': /* Only output these protocols */
447 output_only = g_strdup(optarg);
449 case 'V': /* Verbose */
450 print_details = TRUE;
451 print_packet_info = TRUE;
453 case 'x': /* Print packet data in hex (and ASCII) */
455 /* The user asked for hex output, so let's ensure they get it,
456 * even if they're writing to a file.
458 print_packet_info = TRUE;
469 * Print packet summary information is the default, unless either -V or -x
470 * were specified. Note that this is new behavior, which
471 * allows for the possibility of printing only hex/ascii output without
472 * necessarily requiring that either the summary or details be printed too.
474 if (print_summary == -1)
475 print_summary = (print_details || print_hex) ? FALSE : TRUE;
477 /** Send All g_log messages to our own handler **/
481 G_LOG_LEVEL_CRITICAL|
486 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
488 g_log_set_handler(NULL,
489 (GLogLevelFlags)log_flags,
490 tfshark_log_handler, NULL /* user_data */);
491 g_log_set_handler(LOG_DOMAIN_MAIN,
492 (GLogLevelFlags)log_flags,
493 tfshark_log_handler, NULL /* user_data */);
495 init_report_err(failure_message, open_failure_message, read_failure_message,
496 write_failure_message);
498 timestamp_set_type(TS_RELATIVE);
499 timestamp_set_precision(TS_PREC_AUTO);
500 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
505 /* Register all the plugin types we have. */
506 epan_register_plugin_types(); /* Types known to libwireshark */
508 /* Scan for plugins. This does *not* call their registration routines;
509 that's done later. */
510 scan_plugins(REPORT_LOAD_FAILURE);
514 /* Register all dissectors; we must do this before checking for the
515 "-G" flag, as the "-G" flag dumps information registered by the
516 dissectors, and we must do it before we read the preferences, in
517 case any dissectors register preferences. */
518 if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
522 /* Register all tap listeners; we do this before we parse the arguments,
523 as the "-z" argument can specify a registered tap. */
525 /* we register the plugin taps before the other taps because
526 stats_tree taps plugins will be registered as tap listeners
527 by stats_tree_stat.c and need to registered before that */
529 /* XXX Disable tap registration for now until we can get tfshark set up with
530 * its own set of taps and the necessary registration function etc.
532 register_all_plugin_tap_listeners();
534 register_all_tap_listeners();
537 /* If invoked with the "-G" flag, we dump out information based on
538 the argument to the "-G" flag; if no argument is specified,
539 for backwards compatibility we dump out a glossary of display
542 XXX - we do this here, for now, to support "-G" with no arguments.
543 If none of our build or other processes uses "-G" with no arguments,
544 we can just process it with the other arguments. */
545 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
546 proto_initialize_all_prefixes();
549 proto_registrar_dump_fields();
551 if (strcmp(argv[2], "column-formats") == 0)
552 column_dump_column_formats();
553 else if (strcmp(argv[2], "currentprefs") == 0) {
554 read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
555 &pf_open_errno, &pf_read_errno, &pf_path);
558 else if (strcmp(argv[2], "decodes") == 0)
559 dissector_dump_decodes();
560 else if (strcmp(argv[2], "defaultprefs") == 0)
562 else if (strcmp(argv[2], "dissector-tables") == 0)
563 dissector_dump_dissector_tables();
564 else if (strcmp(argv[2], "fields") == 0)
565 proto_registrar_dump_fields();
566 else if (strcmp(argv[2], "ftypes") == 0)
567 proto_registrar_dump_ftypes();
568 else if (strcmp(argv[2], "heuristic-decodes") == 0)
569 dissector_dump_heur_decodes();
570 else if (strcmp(argv[2], "plugins") == 0) {
575 wslua_plugins_dump_all();
578 else if (strcmp(argv[2], "protocols") == 0)
579 proto_registrar_dump_protocols();
580 else if (strcmp(argv[2], "values") == 0)
581 proto_registrar_dump_values();
582 else if (strcmp(argv[2], "?") == 0)
583 glossary_option_help();
584 else if (strcmp(argv[2], "-?") == 0)
585 glossary_option_help();
587 cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
594 prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
595 &pf_open_errno, &pf_read_errno, &pf_path);
596 if (gpf_path != NULL) {
597 if (gpf_open_errno != 0) {
598 cmdarg_err("Can't open global preferences file \"%s\": %s.",
599 pf_path, g_strerror(gpf_open_errno));
601 if (gpf_read_errno != 0) {
602 cmdarg_err("I/O error reading global preferences file \"%s\": %s.",
603 pf_path, g_strerror(gpf_read_errno));
606 if (pf_path != NULL) {
607 if (pf_open_errno != 0) {
608 cmdarg_err("Can't open your preferences file \"%s\": %s.", pf_path,
609 g_strerror(pf_open_errno));
611 if (pf_read_errno != 0) {
612 cmdarg_err("I/O error reading your preferences file \"%s\": %s.",
613 pf_path, g_strerror(pf_read_errno));
619 /* Read the disabled protocols file. */
620 read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
621 &dp_path, &dp_open_errno, &dp_read_errno);
622 read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
623 &dp_path, &dp_open_errno, &dp_read_errno);
624 if (gdp_path != NULL) {
625 if (gdp_open_errno != 0) {
626 cmdarg_err("Could not open global disabled protocols file\n\"%s\": %s.",
627 gdp_path, g_strerror(gdp_open_errno));
629 if (gdp_read_errno != 0) {
630 cmdarg_err("I/O error reading global disabled protocols file\n\"%s\": %s.",
631 gdp_path, g_strerror(gdp_read_errno));
635 if (dp_path != NULL) {
636 if (dp_open_errno != 0) {
638 "Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
639 g_strerror(dp_open_errno));
641 if (dp_read_errno != 0) {
643 "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
644 g_strerror(dp_read_errno));
649 cap_file_init(&cfile);
651 /* Print format defaults to this. */
652 print_format = PR_FMT_TEXT;
654 output_fields = output_fields_new();
657 * To reset the options parser, set optreset to 1 on platforms that
658 * have optreset (documented in *BSD and OS X, apparently present but
659 * not documented in Solaris - the Illumos repository seems to
660 * suggest that the first Solaris getopt_long(), at least as of 2004,
661 * was based on the NetBSD one, it had optreset) and set optind to 1,
662 * and set optind to 0 otherwise (documented as working in the GNU
663 * getopt_long(). Setting optind to 0 didn't originally work in the
664 * NetBSD one, but that was added later - we don't want to depend on
665 * it if we have optreset).
667 * Also reset opterr to 1, so that error messages are printed by
678 /* Now get our args */
679 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
681 case '2': /* Perform two pass analysis */
682 perform_two_pass_analysis = TRUE;
685 /* already processed; just ignore it now */
689 output_fields_add(output_fields, optarg);
693 if (!output_fields_set_option(output_fields, optarg)) {
694 cmdarg_err("\"%s\" is not a valid field output option=value pair.", optarg);
695 output_fields_list_options(stderr);
700 case 'h': /* Print help and exit */
701 printf("TFShark (Wireshark) %s\n"
702 "Dump and analyze network traffic.\n"
703 "See https://www.wireshark.org for more information.\n",
704 get_ws_vcs_version_info());
708 case 'l': /* "Line-buffer" standard output */
709 /* This isn't line-buffering, strictly speaking, it's just
710 flushing the standard output after the information for
711 each packet is printed; however, that should be good
712 enough for all the purposes to which "-l" is put (and
713 is probably actually better for "-V", as it does fewer
716 See the comment in "process_packet()" for an explanation of
717 why we do that, and why we don't just use "setvbuf()" to
718 make the standard output line-buffered (short version: in
719 Windows, "line-buffered" is the same as "fully-buffered",
720 and the output buffer is only flushed when it fills up). */
721 line_buffered = TRUE;
723 case 'o': /* Override preference from command line */
724 switch (prefs_set_pref(optarg)) {
729 case PREFS_SET_SYNTAX_ERR:
730 cmdarg_err("Invalid -o flag \"%s\"", optarg);
734 case PREFS_SET_NO_SUCH_PREF:
735 case PREFS_SET_OBSOLETE:
736 cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
741 case 'q': /* Quiet */
744 case 'Q': /* Really quiet */
748 case 'r': /* Read capture file x */
749 cf_name = g_strdup(optarg);
751 case 'R': /* Read file filter */
754 case 'S': /* Set the line Separator to be printed between packets */
755 separator = g_strdup(optarg);
757 case 'T': /* printing Type */
758 if (strcmp(optarg, "text") == 0) {
759 output_action = WRITE_TEXT;
760 print_format = PR_FMT_TEXT;
761 } else if (strcmp(optarg, "ps") == 0) {
762 output_action = WRITE_TEXT;
763 print_format = PR_FMT_PS;
764 } else if (strcmp(optarg, "pdml") == 0) {
765 output_action = WRITE_XML;
766 print_details = TRUE; /* Need details */
767 print_summary = FALSE; /* Don't allow summary */
768 } else if (strcmp(optarg, "psml") == 0) {
769 output_action = WRITE_XML;
770 print_details = FALSE; /* Don't allow details */
771 print_summary = TRUE; /* Need summary */
772 } else if (strcmp(optarg, "fields") == 0) {
773 output_action = WRITE_FIELDS;
774 print_details = TRUE; /* Need full tree info */
775 print_summary = FALSE; /* Don't allow summary */
777 cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg); /* x */
778 cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
779 "\t specified by the -E option.\n"
780 "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
781 "\t details of a decoded packet. This information is equivalent to\n"
782 "\t the packet details printed with the -V flag.\n"
783 "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
784 "\t the packets, or a multi-line view of the details of each of\n"
785 "\t the packets, depending on whether the -V flag was specified.\n"
786 "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
787 "\t summary information of a decoded packet. This information is\n"
788 "\t equivalent to the information shown in the one-line summary\n"
789 "\t printed by default.\n"
790 "\t\"text\" Text of a human-readable one-line summary of each of the\n"
791 "\t packets, or a multi-line view of the details of each of the\n"
792 "\t packets, depending on whether the -V flag was specified.\n"
793 "\t This is the default.");
797 case 'v': /* Show version and exit */
798 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
799 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
800 show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
801 g_string_free(comp_info_str, TRUE);
802 g_string_free(runtime_info_str, TRUE);
803 /* We don't really have to cleanup here, but it's a convenient way to test
804 * start-up and shut-down of the epan library without any UI-specific
805 * cruft getting in the way. Makes the results of running
806 * $ ./tools/valgrind-wireshark -n
807 * much more useful. */
813 case 'O': /* Only output these protocols */
814 /* already processed; just ignore it now */
816 case 'V': /* Verbose */
817 /* already processed; just ignore it now */
819 case 'x': /* Print packet data in hex (and ASCII) */
820 /* already processed; just ignore it now */
823 /* already processed; just ignore it now */
829 /* We won't call the init function for the stat this soon
830 as it would disallow MATE's fields (which are registered
831 by the preferences set callback) from being used as
832 part of a tap filter. Instead, we just add the argument
833 to a list of stat arguments. */
834 if (strcmp("help", optarg) == 0) {
835 fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
836 list_stat_cmd_args();
839 if (!process_stat_cmd_arg(optarg)) {
840 cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
841 list_stat_cmd_args();
845 case 'd': /* Decode as rule */
846 case 'K': /* Kerberos keytab file */
847 case 't': /* Time stamp type */
848 case 'u': /* Seconds type */
849 if (!dissect_opts_handle_opt(opt, optarg))
853 case '?': /* Bad flag - print usage message */
860 /* If we specified output fields, but not the output field type... */
861 if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
862 cmdarg_err("Output fields were specified with \"-e\", "
863 "but \"-Tfields\" was not specified.");
865 } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
866 cmdarg_err("\"-Tfields\" was specified, but no fields were "
867 "specified with \"-e\".");
872 /* If no capture filter or display filter has been specified, and there are
873 still command-line arguments, treat them as the tokens of a capture
874 filter (if no "-r" flag was specified) or a display filter (if a "-r"
875 flag was specified. */
877 if (cf_name != NULL) {
878 if (dfilter != NULL) {
879 cmdarg_err("Display filters were specified both with \"-d\" "
880 "and with additional command-line arguments.");
883 dfilter = get_args_as_string(argc, argv, optind);
887 /* if "-q" wasn't specified, we should print packet information */
889 print_packet_info = TRUE;
897 if (output_action != WRITE_TEXT) {
898 cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
903 if (output_only != NULL) {
906 if (!print_details) {
907 cmdarg_err("-O requires -V");
911 output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
912 for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
913 g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
917 if (rfilter != NULL && !perform_two_pass_analysis) {
918 cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
922 /* Notify all registered modules that have had any of their preferences
923 changed either from one of the preferences file or from the command
924 line that their preferences have changed. */
927 /* At this point MATE will have registered its field array so we can
928 have a tap filter with one of MATE's late-registered fields as part
929 of the filter. We can now process all the "-z" arguments. */
930 start_requested_stats();
932 /* disabled protocols as per configuration file */
933 if (gdp_path == NULL && dp_path == NULL) {
934 set_disabled_protos_list();
935 set_disabled_heur_dissector_list();
938 /* Build the column format array */
939 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
941 if (rfilter != NULL) {
942 if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
943 cmdarg_err("%s", err_msg);
952 cfile.rfcode = rfcode;
954 if (dfilter != NULL) {
955 if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
956 cmdarg_err("%s", err_msg);
965 cfile.dfcode = dfcode;
967 if (print_packet_info) {
968 /* If we're printing as text or PostScript, we have
969 to create a print stream. */
970 if (output_action == WRITE_TEXT) {
971 switch (print_format) {
974 print_stream = print_stream_text_stdio_new(stdout);
978 print_stream = print_stream_ps_stdio_new(stdout);
982 g_assert_not_reached();
987 /* We have to dissect each packet if:
989 we're printing information about each packet;
991 we're using a read filter on the packets;
993 we're using a display filter on the packets;
995 we're using any taps that need dissection. */
996 do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
1000 * We're reading a capture file.
1003 /* TODO: if tfshark is ever changed to give the user a choice of which
1004 open_routine reader to use, then the following needs to change. */
1005 if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
1013 /* Process the packets in the file */
1015 /* XXX - for now there is only 1 packet */
1016 err = load_cap_file(&cfile, 1, 0);
1018 CATCH(OutOfMemoryError) {
1022 "Sorry, but TFShark has to terminate now!\n"
1024 "Some infos / workarounds can be found at:\n"
1025 "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
1031 /* We still dump out the results of taps, etc., as we might have
1032 read some packets; however, we exit with an error status. */
1039 if (cfile.frames != NULL) {
1040 free_frame_data_sequence(cfile.frames);
1041 cfile.frames = NULL;
1044 draw_tap_listeners(TRUE);
1045 funnel_dump_all_text_windows();
1046 epan_free(cfile.epan);
1052 output_fields_free(output_fields);
1053 output_fields = NULL;
1058 static const nstime_t *
1059 tfshark_get_frame_ts(void *data, guint32 frame_num)
1061 capture_file *cf = (capture_file *) data;
1063 if (ref && ref->num == frame_num)
1064 return &ref->abs_ts;
1066 if (prev_dis && prev_dis->num == frame_num)
1067 return &prev_dis->abs_ts;
1069 if (prev_cap && prev_cap->num == frame_num)
1070 return &prev_cap->abs_ts;
1073 frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
1075 return (fd) ? &fd->abs_ts : NULL;
1082 no_interface_name(void *data _U_, guint32 interface_id _U_)
1088 tfshark_epan_new(capture_file *cf)
1090 epan_t *epan = epan_new();
1093 epan->get_frame_ts = tfshark_get_frame_ts;
1094 epan->get_interface_name = no_interface_name;
1095 epan->get_user_comment = NULL;
1101 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
1102 gint64 offset, struct wtap_pkthdr *whdr,
1109 /* The frame number of this packet is one more than the count of
1110 frames in this packet. */
1111 framenum = cf->count + 1;
1113 /* If we're not running a display filter and we're not printing any
1114 packet information, we don't need to do a dissection. This means
1115 that all packets can be marked as 'passed'. */
1118 frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
1120 /* If we're going to print packet information, or we're going to
1121 run a read filter, or display filter, or we're going to process taps, set up to
1122 do a dissection and do so. */
1124 /* If we're running a read filter, prime the epan_dissect_t with that
1127 epan_dissect_prime_dfilter(edt, cf->rfcode);
1129 frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
1131 if (ref == &fdlocal) {
1132 ref_frame = fdlocal;
1136 epan_dissect_file_run(edt, whdr, file_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
1138 /* Run the read filter if we have one. */
1140 passed = dfilter_apply_edt(cf->rfcode, edt);
1144 frame_data_set_after_dissect(&fdlocal, &cum_bytes);
1145 prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
1147 /* If we're not doing dissection then there won't be any dependent frames.
1148 * More importantly, edt.pi.dependent_frames won't be initialized because
1149 * epan hasn't been initialized.
1152 g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
1157 /* if we don't add it to the frame_data_sequence, clean it up right now
1159 frame_data_destroy(&fdlocal);
1163 epan_dissect_reset(edt);
1169 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt, frame_data *fdata,
1170 struct wtap_pkthdr *phdr, Buffer *buf,
1176 /* If we're not running a display filter and we're not printing any
1177 packet information, we don't need to do a dissection. This means
1178 that all packets can be marked as 'passed'. */
1181 /* If we're going to print packet information, or we're going to
1182 run a read filter, or we're going to process taps, set up to
1183 do a dissection and do so. */
1186 /* If we're running a display filter, prime the epan_dissect_t with that
1189 epan_dissect_prime_dfilter(edt, cf->dfcode);
1191 col_custom_prime_edt(edt, &cf->cinfo);
1193 /* We only need the columns if either
1194 1) some tap needs the columns
1196 2) we're printing packet info but we're *not* verbose; in verbose
1197 mode, we print the protocol tree, not the protocol summary.
1199 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
1204 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1211 epan_dissect_file_run_with_taps(edt, phdr, file_tvbuff_new_buffer(fdata, buf), fdata, cinfo);
1213 /* Run the read/display filter if we have one. */
1215 passed = dfilter_apply_edt(cf->dfcode, edt);
1219 frame_data_set_after_dissect(fdata, &cum_bytes);
1220 /* Process this packet. */
1221 if (print_packet_info) {
1222 /* We're printing packet information; print the information for
1224 print_packet(cf, edt);
1226 /* The ANSI C standard does not appear to *require* that a line-buffered
1227 stream be flushed to the host environment whenever a newline is
1228 written, it just says that, on such a stream, characters "are
1229 intended to be transmitted to or from the host environment as a
1230 block when a new-line character is encountered".
1232 The Visual C++ 6.0 C implementation doesn't do what is intended;
1233 even if you set a stream to be line-buffered, it still doesn't
1234 flush the buffer at the end of every line.
1236 So, if the "-l" flag was specified, we flush the standard output
1237 at the end of a packet. This will do the right thing if we're
1238 printing packet summary lines, and, as we print the entire protocol
1239 tree for a single packet without waiting for anything to happen,
1240 it should be as good as line-buffered mode if we're printing
1241 protocol trees. (The whole reason for the "-l" flag in either
1242 tcpdump or TShark is to allow the output of a live capture to
1243 be piped to a program or script and to have that script see the
1244 information for the packet as soon as it's printed, rather than
1245 having to wait until a standard I/O buffer fills up. */
1249 if (ferror(stdout)) {
1250 show_print_file_io_error(errno);
1259 epan_dissect_reset(edt);
1261 return passed || fdata->flags.dependent_of_displayed;
1265 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)
1267 /* int bytes_read; */
1268 gint64 packet_size = wtap_file_size(cf->wth, err);
1270 *data_buffer = (guint8*)g_malloc((gsize)packet_size);
1271 /* bytes_read =*/ file_read(*data_buffer, (unsigned int)packet_size, cf->wth->fh);
1273 #if 0 /* no more filetap */
1274 if (bytes_read < 0) {
1275 *err = file_error(cf->wth->fh, err_info);
1277 *err = FTAP_ERR_SHORT_READ;
1279 } else if (bytes_read == 0) {
1280 /* Done with file, no error */
1285 /* XXX - SET FRAME SIZE EQUAL TO TOTAL FILE SIZE */
1286 file_phdr->caplen = (guint32)packet_size;
1287 file_phdr->len = (guint32)packet_size;
1290 * Set the packet encapsulation to the file's encapsulation
1291 * value; if that's not WTAP_ENCAP_PER_PACKET, it's the
1292 * right answer (and means that the read routine for this
1293 * capture file type doesn't have to set it), and if it
1294 * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it
1297 wth->phdr.pkt_encap = wth->file_encap;
1299 if (!wth->subtype_read(wth, err, err_info, data_offset)) {
1301 * If we didn't get an error indication, we read
1302 * the last packet. See if there's any deferred
1303 * error, as might, for example, occur if we're
1304 * reading a compressed file, and we got an error
1305 * reading compressed data from the file, but
1306 * got enough compressed data to decompress the
1307 * last packet of the file.
1310 *err = file_error(wth->fh, err_info);
1311 return FALSE; /* failure */
1315 * It makes no sense for the captured data length to be bigger
1316 * than the actual data length.
1318 if (wth->phdr.caplen > wth->phdr.len)
1319 wth->phdr.caplen = wth->phdr.len;
1322 * Make sure that it's not WTAP_ENCAP_PER_PACKET, as that
1323 * probably means the file has that encapsulation type
1324 * but the read routine didn't set this packet's
1325 * encapsulation type.
1327 g_assert(wth->phdr.pkt_encap != WTAP_ENCAP_PER_PACKET);
1330 return TRUE; /* success */
1334 load_cap_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
1338 gchar *err_info = NULL;
1339 gint64 data_offset = 0;
1340 gboolean filtering_tap_listeners;
1343 epan_dissect_t *edt = NULL;
1344 struct wtap_pkthdr file_phdr;
1347 if (print_packet_info) {
1348 if (!write_preamble(cf)) {
1350 show_print_file_io_error(err);
1355 /* Do we have any tap listeners with filters? */
1356 filtering_tap_listeners = have_filtering_tap_listeners();
1358 /* Get the union of the flags for all tap listeners. */
1359 tap_flags = union_of_tap_listener_flags();
1361 wtap_phdr_init(&file_phdr);
1363 /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1364 file_phdr.pkt_encap = 1234;
1366 if (perform_two_pass_analysis) {
1369 /* Allocate a frame_data_sequence for all the frames. */
1370 cf->frames = new_frame_data_sequence();
1372 if (do_dissection) {
1373 gboolean create_proto_tree = FALSE;
1375 /* If we're going to be applying a filter, we'll need to
1376 create a protocol tree against which to apply the filter. */
1378 create_proto_tree = TRUE;
1380 /* We're not going to display the protocol tree on this pass,
1381 so it's not going to be "visible". */
1382 edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
1384 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1385 if (process_packet_first_pass(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1386 wtap_buf_ptr(cf->wth))) {
1388 /* Stop reading if we have the maximum number of packets;
1389 * When the -c option has not been used, max_packet_count
1390 * starts at 0, which practically means, never stop reading.
1391 * (unless we roll over max_packet_count ?)
1393 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1394 err = 0; /* This is not an error */
1401 epan_dissect_free(edt);
1406 /* Close the sequential I/O side, to free up memory it requires. */
1407 wtap_sequential_close(cf->wth);
1410 /* Allow the protocol dissectors to free up memory that they
1411 * don't need after the sequential run-through of the packets. */
1412 postseq_cleanup_all_protocols();
1416 ws_buffer_init(&buf, 1500);
1418 if (do_dissection) {
1419 gboolean create_proto_tree;
1421 if (cf->dfcode || print_details || filtering_tap_listeners ||
1422 (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo))
1423 create_proto_tree = TRUE;
1425 create_proto_tree = FALSE;
1427 /* The protocol tree will be "visible", i.e., printed, only if we're
1428 printing packet details, which is true if we're printing stuff
1429 ("print_packet_info" is true) and we're in verbose mode
1430 ("packet_details" is true). */
1431 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1434 for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
1435 fdata = frame_data_sequence_find(cf->frames, framenum);
1437 if (wtap_seek_read(cf->wth, fdata->file_off,
1438 &buf, fdata->cap_len, &err, &err_info)) {
1439 process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1442 process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1447 epan_dissect_free(edt);
1451 ws_buffer_free(&buf);
1456 if (do_dissection) {
1457 gboolean create_proto_tree;
1459 if (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
1460 (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo))
1461 create_proto_tree = TRUE;
1463 create_proto_tree = FALSE;
1465 /* The protocol tree will be "visible", i.e., printed, only if we're
1466 printing packet details, which is true if we're printing stuff
1467 ("print_packet_info" is true) and we're in verbose mode
1468 ("packet_details" is true). */
1469 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1472 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1476 process_packet(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1477 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(capture_file *cf, epan_dissect_t *edt, gint64 offset,
1583 struct wtap_pkthdr *whdr, const guchar *pd, guint tap_flags)
1589 /* Count this packet. */
1592 /* If we're not running a display filter and we're not printing any
1593 packet information, we don't need to do a dissection. This means
1594 that all packets can be marked as 'passed'. */
1597 frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
1599 /* If we're going to print packet information, or we're going to
1600 run a read filter, or we're going to process taps, set up to
1601 do a dissection and do so. */
1603 /* If we're running a filter, prime the epan_dissect_t with that
1606 epan_dissect_prime_dfilter(edt, cf->dfcode);
1608 col_custom_prime_edt(edt, &cf->cinfo);
1610 /* We only need the columns if either
1611 1) some tap needs the columns
1613 2) we're printing packet info but we're *not* verbose; in verbose
1614 mode, we print the protocol tree, not the protocol summary.
1616 3) there is a column mapped as an individual field */
1617 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
1622 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
1624 if (ref == &fdata) {
1629 epan_dissect_file_run_with_taps(edt, whdr, frame_tvbuff_new(&fdata, pd), &fdata, cinfo);
1631 /* Run the filter if we have it. */
1633 passed = dfilter_apply_edt(cf->dfcode, edt);
1637 frame_data_set_after_dissect(&fdata, &cum_bytes);
1639 /* Process this packet. */
1640 if (print_packet_info) {
1641 /* We're printing packet information; print the information for
1643 print_packet(cf, edt);
1645 /* The ANSI C standard does not appear to *require* that a line-buffered
1646 stream be flushed to the host environment whenever a newline is
1647 written, it just says that, on such a stream, characters "are
1648 intended to be transmitted to or from the host environment as a
1649 block when a new-line character is encountered".
1651 The Visual C++ 6.0 C implementation doesn't do what is intended;
1652 even if you set a stream to be line-buffered, it still doesn't
1653 flush the buffer at the end of every line.
1655 So, if the "-l" flag was specified, we flush the standard output
1656 at the end of a packet. This will do the right thing if we're
1657 printing packet summary lines, and, as we print the entire protocol
1658 tree for a single packet without waiting for anything to happen,
1659 it should be as good as line-buffered mode if we're printing
1660 protocol trees. (The whole reason for the "-l" flag in either
1661 tcpdump or TShark is to allow the output of a live capture to
1662 be piped to a program or script and to have that script see the
1663 information for the packet as soon as it's printed, rather than
1664 having to wait until a standard I/O buffer fills up. */
1668 if (ferror(stdout)) {
1669 show_print_file_io_error(errno);
1674 /* this must be set after print_packet() [bug #8160] */
1675 prev_dis_frame = fdata;
1676 prev_dis = &prev_dis_frame;
1679 prev_cap_frame = fdata;
1680 prev_cap = &prev_cap_frame;
1683 epan_dissect_reset(edt);
1684 frame_data_destroy(&fdata);
1690 write_preamble(capture_file *cf)
1692 switch (output_action) {
1695 return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
1699 write_pdml_preamble(stdout, cf->filename);
1701 write_psml_preamble(&cf->cinfo, stdout);
1702 return !ferror(stdout);
1705 write_fields_preamble(output_fields, stdout);
1706 return !ferror(stdout);
1709 g_assert_not_reached();
1715 get_line_buf(size_t len)
1717 static char *line_bufp = NULL;
1718 static size_t line_buf_len = 256;
1719 size_t new_line_buf_len;
1721 for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
1722 new_line_buf_len *= 2)
1724 if (line_bufp == NULL) {
1725 line_buf_len = new_line_buf_len;
1726 line_bufp = (char *)g_malloc(line_buf_len + 1);
1728 if (new_line_buf_len > line_buf_len) {
1729 line_buf_len = new_line_buf_len;
1730 line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
1737 put_string(char *dest, const char *str, size_t str_len)
1739 memcpy(dest, str, str_len);
1740 dest[str_len] = '\0';
1744 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1748 for (i = str_len; i < str_with_spaces; i++)
1751 put_string(dest, str, str_len);
1755 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1759 memcpy(dest, str, str_len);
1760 for (i = str_len; i < str_with_spaces; i++)
1763 dest[str_with_spaces] = '\0';
1767 print_columns(capture_file *cf)
1774 col_item_t* col_item;
1776 line_bufp = get_line_buf(256);
1779 for (i = 0; i < cf->cinfo.num_cols; i++) {
1780 col_item = &cf->cinfo.columns[i];
1781 /* Skip columns not marked as visible. */
1782 if (!get_column_visible(i))
1784 switch (col_item->col_fmt) {
1786 column_len = col_len = strlen(col_item->col_data);
1789 line_bufp = get_line_buf(buf_offset + column_len);
1790 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1796 case COL_ABS_YMD_TIME: /* XXX - wider */
1797 case COL_ABS_YDOY_TIME: /* XXX - wider */
1799 case COL_UTC_YMD_TIME: /* XXX - wider */
1800 case COL_UTC_YDOY_TIME: /* XXX - wider */
1801 column_len = col_len = strlen(col_item->col_data);
1802 if (column_len < 10)
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_SRC:
1812 case COL_RES_DL_SRC:
1813 case COL_UNRES_DL_SRC:
1814 case COL_DEF_NET_SRC:
1815 case COL_RES_NET_SRC:
1816 case COL_UNRES_NET_SRC:
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_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1827 case COL_DEF_DL_DST:
1828 case COL_RES_DL_DST:
1829 case COL_UNRES_DL_DST:
1830 case COL_DEF_NET_DST:
1831 case COL_RES_NET_DST:
1832 case COL_UNRES_NET_DST:
1833 column_len = col_len = strlen(col_item->col_data);
1834 if (column_len < 12)
1836 line_bufp = get_line_buf(buf_offset + column_len);
1837 put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1841 column_len = strlen(col_item->col_data);
1842 line_bufp = get_line_buf(buf_offset + column_len);
1843 put_string(line_bufp + buf_offset, col_item->col_data, column_len);
1846 buf_offset += column_len;
1847 if (i != cf->cinfo.num_cols - 1) {
1849 * This isn't the last column, so we need to print a
1850 * separator between this column and the next.
1852 * If we printed a network source and are printing a
1853 * network destination of the same type next, separate
1854 * them with " -> "; if we printed a network destination
1855 * and are printing a network source of the same type
1856 * next, separate them with " <- "; otherwise separate them
1859 * We add enough space to the buffer for " <- " or " -> ",
1860 * even if we're only adding " ".
1862 line_bufp = get_line_buf(buf_offset + 4);
1863 switch (col_item->col_fmt) {
1868 switch (cf->cinfo.columns[i+1].col_fmt) {
1873 put_string(line_bufp + buf_offset, " -> ", 4);
1878 put_string(line_bufp + buf_offset, " ", 1);
1884 case COL_DEF_DL_SRC:
1885 case COL_RES_DL_SRC:
1886 case COL_UNRES_DL_SRC:
1887 switch (cf->cinfo.columns[i+1].col_fmt) {
1889 case COL_DEF_DL_DST:
1890 case COL_RES_DL_DST:
1891 case COL_UNRES_DL_DST:
1892 put_string(line_bufp + buf_offset, " -> ", 4);
1897 put_string(line_bufp + buf_offset, " ", 1);
1903 case COL_DEF_NET_SRC:
1904 case COL_RES_NET_SRC:
1905 case COL_UNRES_NET_SRC:
1906 switch (cf->cinfo.columns[i+1].col_fmt) {
1908 case COL_DEF_NET_DST:
1909 case COL_RES_NET_DST:
1910 case COL_UNRES_NET_DST:
1911 put_string(line_bufp + buf_offset, " -> ", 4);
1916 put_string(line_bufp + buf_offset, " ", 1);
1925 switch (cf->cinfo.columns[i+1].col_fmt) {
1930 put_string(line_bufp + buf_offset, " <- ", 4);
1935 put_string(line_bufp + buf_offset, " ", 1);
1941 case COL_DEF_DL_DST:
1942 case COL_RES_DL_DST:
1943 case COL_UNRES_DL_DST:
1944 switch (cf->cinfo.columns[i+1].col_fmt) {
1946 case COL_DEF_DL_SRC:
1947 case COL_RES_DL_SRC:
1948 case COL_UNRES_DL_SRC:
1949 put_string(line_bufp + buf_offset, " <- ", 4);
1954 put_string(line_bufp + buf_offset, " ", 1);
1960 case COL_DEF_NET_DST:
1961 case COL_RES_NET_DST:
1962 case COL_UNRES_NET_DST:
1963 switch (cf->cinfo.columns[i+1].col_fmt) {
1965 case COL_DEF_NET_SRC:
1966 case COL_RES_NET_SRC:
1967 case COL_UNRES_NET_SRC:
1968 put_string(line_bufp + buf_offset, " <- ", 4);
1973 put_string(line_bufp + buf_offset, " ", 1);
1980 put_string(line_bufp + buf_offset, " ", 1);
1986 return print_line(print_stream, 0, line_bufp);
1990 print_packet(capture_file *cf, epan_dissect_t *edt)
1992 print_args_t print_args;
1994 if (print_summary || output_fields_has_cols(output_fields)) {
1995 /* Just fill in the columns. */
1996 epan_dissect_fill_in_columns(edt, FALSE, TRUE);
1998 if (print_summary) {
1999 /* Now print them. */
2000 switch (output_action) {
2003 if (!print_columns(cf))
2008 write_psml_columns(edt, stdout);
2009 return !ferror(stdout);
2010 case WRITE_FIELDS: /*No non-verbose "fields" format */
2011 g_assert_not_reached();
2016 if (print_details) {
2017 /* Print the information in the protocol tree. */
2018 switch (output_action) {
2021 /* Only initialize the fields that are actually used in proto_tree_print.
2022 * This is particularly important for .range, as that's heap memory which
2023 * we would otherwise have to g_free().
2024 print_args.to_file = TRUE;
2025 print_args.format = print_format;
2026 print_args.print_summary = print_summary;
2027 print_args.print_formfeed = FALSE;
2028 packet_range_init(&print_args.range, &cfile);
2030 print_args.print_hex = print_hex;
2031 print_args.print_dissections = print_details ? print_dissections_expanded : print_dissections_none;
2033 if (!proto_tree_print(&print_args, edt, output_only_tables, print_stream))
2036 if (!print_line(print_stream, 0, separator))
2042 write_pdml_proto_tree(NULL, NULL, edt, stdout);
2044 return !ferror(stdout);
2046 write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
2048 return !ferror(stdout);
2052 if (print_summary || print_details) {
2053 if (!print_line(print_stream, 0, ""))
2056 if (!print_hex_data(print_stream, edt))
2058 if (!print_line(print_stream, 0, separator))
2067 switch (output_action) {
2070 return print_finale(print_stream);
2074 write_pdml_finale(stdout);
2076 write_psml_finale(stdout);
2077 return !ferror(stdout);
2080 write_fields_finale(output_fields, stdout);
2081 return !ferror(stdout);
2084 g_assert_not_reached();
2090 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
2093 char err_msg[2048+1];
2095 /* The open isn't implemented yet. Fill in the information for this file. */
2097 /* Create new epan session for dissection. */
2098 epan_free(cf->epan);
2099 cf->epan = tfshark_epan_new(cf);
2101 cf->wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2102 cf->f_datalen = 0; /* not used, but set it anyway */
2104 /* Set the file name because we need it to set the follow stream filter.
2105 XXX - is that still true? We need it for other reasons, though,
2107 cf->filename = g_strdup(fname);
2109 /* Indicate whether it's a permanent or temporary file. */
2110 cf->is_tempfile = is_tempfile;
2112 /* No user changes yet. */
2113 cf->unsaved_changes = FALSE;
2115 cf->cd_t = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2116 cf->open_type = type;
2118 cf->drops_known = FALSE;
2120 cf->snap = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2121 if (cf->snap == 0) {
2122 /* Snapshot length not known. */
2123 cf->has_snap = FALSE;
2126 cf->has_snap = TRUE;
2127 nstime_set_zero(&cf->elapsed_time);
2132 cf->state = FILE_READ_IN_PROGRESS;
2137 g_snprintf(err_msg, sizeof err_msg,
2138 cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
2139 cmdarg_err("%s", err_msg);
2144 show_print_file_io_error(int err)
2149 cmdarg_err("Not all the packets could be printed because there is "
2150 "no space left on the file system.");
2155 cmdarg_err("Not all the packets could be printed because you are "
2156 "too close to, or over your disk quota.");
2161 cmdarg_err("An error occurred while printing packets: %s.",
2168 cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
2172 /* static char errmsg_errno[1024+1]; */
2176 /* Wiretap error. */
2179 case FTAP_ERR_NOT_REGULAR_FILE:
2180 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
2183 case FTAP_ERR_RANDOM_OPEN_PIPE:
2184 /* Seen only when opening a capture file for reading. */
2185 errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
2188 case FTAP_ERR_FILE_UNKNOWN_FORMAT:
2189 /* Seen only when opening a capture file for reading. */
2190 errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
2193 case FTAP_ERR_UNSUPPORTED:
2194 /* Seen only when opening a capture file for reading. */
2195 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2196 "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
2199 errmsg = errmsg_errno;
2202 case FTAP_ERR_CANT_WRITE_TO_PIPE:
2203 /* Seen only when opening a capture file for writing. */
2204 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2205 "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
2206 "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
2207 errmsg = errmsg_errno;
2210 case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
2211 /* Seen only when opening a capture file for writing. */
2212 errmsg = "TFShark doesn't support writing capture files in that format.";
2215 case FTAP_ERR_UNSUPPORTED_ENCAP:
2217 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2218 "TFShark can't save this capture as a \"%s\" file.",
2219 ftap_file_type_subtype_short_string(file_type));
2221 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2222 "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
2226 errmsg = errmsg_errno;
2229 case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
2231 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2232 "TFShark can't save this capture as a \"%s\" file.",
2233 ftap_file_type_subtype_short_string(file_type));
2234 errmsg = errmsg_errno;
2236 errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
2239 case FTAP_ERR_BAD_FILE:
2240 /* Seen only when opening a capture file for reading. */
2241 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2242 "The file \"%%s\" appears to be damaged or corrupt.\n"
2245 errmsg = errmsg_errno;
2248 case FTAP_ERR_CANT_OPEN:
2250 errmsg = "The file \"%s\" could not be created for some unknown reason.";
2252 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
2255 case FTAP_ERR_SHORT_READ:
2256 errmsg = "The file \"%s\" appears to have been cut short"
2257 " in the middle of a packet or other data.";
2260 case FTAP_ERR_SHORT_WRITE:
2261 errmsg = "A full header couldn't be written to the file \"%s\".";
2264 case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
2265 errmsg = "This file type cannot be written as a compressed file.";
2268 case FTAP_ERR_DECOMPRESS:
2269 /* Seen only when opening a capture file for reading. */
2270 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2271 "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
2274 errmsg = errmsg_errno;
2278 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2279 "The file \"%%s\" could not be %s: %s.",
2280 for_writing ? "created" : "opened",
2281 ftap_strerror(err));
2282 errmsg = errmsg_errno;
2287 errmsg = file_open_error_message(err, for_writing);
2292 * Open/create errors are reported with an console message in TFShark.
2295 open_failure_message(const char *filename, int err, gboolean for_writing)
2297 fprintf(stderr, "tfshark: ");
2298 fprintf(stderr, file_open_error_message(err, for_writing), filename);
2299 fprintf(stderr, "\n");
2304 * General errors are reported with an console message in TFShark.
2307 failure_message(const char *msg_format, va_list ap)
2309 fprintf(stderr, "tfshark: ");
2310 vfprintf(stderr, msg_format, ap);
2311 fprintf(stderr, "\n");
2315 * Read errors are reported with an console message in TFShark.
2318 read_failure_message(const char *filename, int err)
2320 cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
2321 filename, g_strerror(err));
2325 * Write errors are reported with an console message in TFShark.
2328 write_failure_message(const char *filename, int err)
2330 cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
2331 filename, g_strerror(err));
2335 * Report additional information for an error in command-line arguments.
2338 failure_message_cont(const char *msg_format, va_list ap)
2340 vfprintf(stderr, msg_format, ap);
2341 fprintf(stderr, "\n");
2345 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2350 * indent-tabs-mode: nil
2353 * vi: set shiftwidth=2 tabstop=8 expandtab:
2354 * :indentSize=2:tabSize=8:noTabs=true: