3 * Text-mode variant of Fileshark, based off of TShark,
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
38 #ifndef HAVE_GETOPT_LONG
39 #include "wsutil/wsgetopt.h"
44 #include <epan/exceptions.h>
45 #include <epan/epan-int.h>
46 #include <epan/epan.h>
48 #include <wsutil/clopts_common.h>
49 #include <wsutil/cmdarg_err.h>
50 #include <wsutil/crash_info.h>
51 #include <wsutil/filesystem.h>
52 #include <wsutil/file_util.h>
53 #include <wsutil/privileges.h>
54 #include <wsutil/report_message.h>
55 #include <ws_version_info.h>
58 #include <epan/timestamp.h>
59 #include <epan/packet.h>
61 #include <epan/wslua/init_wslua.h>
64 #include "frame_tvbuff.h"
65 #include <epan/disabled_protos.h>
66 #include <epan/prefs.h>
67 #include <epan/column.h>
68 #include <epan/print.h>
69 #include <epan/addr_resolv.h>
71 #include "ui/decode_as_utils.h"
72 #include "ui/dissect_opts.h"
74 #include <epan/epan_dissect.h>
76 #include <epan/stat_tap_ui.h>
77 #include <epan/ex-opt.h>
83 #include <wiretap/wtap-int.h>
84 #include <wiretap/file_wrappers.h>
87 #include <wsutil/unicode-utils.h>
91 #include <epan/funnel.h>
94 #include <wsutil/plugins.h>
97 #define INVALID_OPTION 1
99 #define INVALID_FILTER 2
102 static guint32 cum_bytes;
103 static const frame_data *ref;
104 static frame_data ref_frame;
105 static frame_data *prev_dis;
106 static frame_data prev_dis_frame;
107 static frame_data *prev_cap;
108 static frame_data prev_cap_frame;
110 static gboolean perform_two_pass_analysis;
113 * The way the packet decode is to be written.
116 WRITE_TEXT, /* summary or detail text */
117 WRITE_XML, /* PDML or PSML */
118 WRITE_FIELDS /* User defined list of fields */
119 /* Add CSV and the like here */
122 static output_action_e output_action;
123 static gboolean do_dissection; /* TRUE if we have to dissect each packet */
124 static gboolean print_packet_info; /* TRUE if we're to print packet information */
125 static gint print_summary = -1; /* TRUE if we're to print packet summary information */
126 static gboolean print_details; /* TRUE if we're to print packet details information */
127 static gboolean print_hex; /* TRUE if we're to print hex/ascci information */
128 static gboolean line_buffered;
129 static gboolean really_quiet = FALSE;
131 static print_format_e print_format = PR_FMT_TEXT;
132 static print_stream_t *print_stream;
134 static output_fields_t* output_fields = NULL;
136 /* The line separator used between packets, changeable via the -S option */
137 static const char *separator = "";
139 static int load_cap_file(capture_file *, int, gint64);
140 static gboolean process_packet(capture_file *cf, epan_dissect_t *edt, gint64 offset,
141 struct wtap_pkthdr *whdr, const guchar *pd, guint tap_flags);
142 static void show_print_file_io_error(int err);
143 static gboolean write_preamble(capture_file *cf);
144 static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
145 static gboolean write_finale(void);
146 static const char *cf_open_error_message(int err, gchar *err_info,
147 gboolean for_writing, int file_type);
149 static void failure_warning_message(const char *msg_format, va_list ap);
150 static void open_failure_message(const char *filename, int err,
151 gboolean for_writing);
152 static void read_failure_message(const char *filename, int err);
153 static void write_failure_message(const char *filename, int err);
154 static void failure_message_cont(const char *msg_format, va_list ap);
158 static GHashTable *output_only_tables = NULL;
162 const char *sstr; /* The short string */
163 const char *lstr; /* The long string */
167 string_compare(gconstpointer a, gconstpointer b)
169 return strcmp(((const struct string_elem *)a)->sstr,
170 ((const struct string_elem *)b)->sstr);
174 string_elem_print(gpointer data, gpointer not_used _U_)
176 fprintf(stderr, " %s - %s\n",
177 ((struct string_elem *)data)->sstr,
178 ((struct string_elem *)data)->lstr);
183 print_usage(FILE *output)
185 fprintf(output, "\n");
186 fprintf(output, "Usage: tfshark [options] ...\n");
187 fprintf(output, "\n");
189 /*fprintf(output, "\n");*/
190 fprintf(output, "Input file:\n");
191 fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin)\n");
193 fprintf(output, "\n");
194 fprintf(output, "Processing:\n");
195 fprintf(output, " -2 perform a two-pass analysis\n");
196 fprintf(output, " -R <read filter> packet Read filter in Wireshark display filter syntax\n");
197 fprintf(output, " (requires -2)\n");
198 fprintf(output, " -Y <display filter> packet displaY filter in Wireshark display filter\n");
199 fprintf(output, " syntax\n");
200 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
201 fprintf(output, " \"Decode As\", see the man page for details\n");
202 fprintf(output, " Example: tcp.port==8888,http\n");
204 /*fprintf(output, "\n");*/
205 fprintf(output, "Output:\n");
206 fprintf(output, " -C <config profile> start with specified configuration profile\n");
207 fprintf(output, " -V add output of packet tree (Packet Details)\n");
208 fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
209 fprintf(output, " separated\n");
210 fprintf(output, " -S <separator> the line separator to print between packets\n");
211 fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
212 fprintf(output, " -T pdml|ps|psml|text|fields\n");
213 fprintf(output, " format of text output (def: text)\n");
214 fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
215 fprintf(output, " _ws.col.Info)\n");
216 fprintf(output, " this option can be repeated to print multiple fields\n");
217 fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
218 fprintf(output, " header=y|n switch headers on and off\n");
219 fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
220 fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
221 fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
222 fprintf(output, " aggregator\n");
223 fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
224 fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
225 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
226 fprintf(output, " -l flush standard output after each packet\n");
227 fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
228 fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
229 fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
230 fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
232 fprintf(output, "\n");
233 fprintf(output, "Miscellaneous:\n");
234 fprintf(output, " -h display this help and exit\n");
235 fprintf(output, " -v display version info and exit\n");
236 fprintf(output, " -o <name>:<value> ... override preference setting\n");
237 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
238 fprintf(output, " -G [report] dump one of several available reports and exit\n");
239 fprintf(output, " default report=\"fields\"\n");
240 fprintf(output, " use \"-G ?\" for more help\n");
244 glossary_option_help(void)
250 fprintf(output, "TFShark (Wireshark) %s\n", get_ws_vcs_version_info());
252 fprintf(output, "\n");
253 fprintf(output, "Usage: tfshark -G [report]\n");
254 fprintf(output, "\n");
255 fprintf(output, "Glossary table reports:\n");
256 fprintf(output, " -G column-formats dump column format codes and exit\n");
257 fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
258 fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
259 fprintf(output, " -G fields dump fields glossary and exit\n");
260 fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
261 fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
262 fprintf(output, " -G plugins dump installed plugins and exit\n");
263 fprintf(output, " -G protocols dump protocols in registration database and exit\n");
264 fprintf(output, " -G values dump value, range, true/false strings and exit\n");
265 fprintf(output, "\n");
266 fprintf(output, "Preference reports:\n");
267 fprintf(output, " -G currentprefs dump current preferences and exit\n");
268 fprintf(output, " -G defaultprefs dump default preferences and exit\n");
269 fprintf(output, "\n");
273 tfshark_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
274 const gchar *message, gpointer user_data)
276 /* ignore log message, if log_level isn't interesting based
277 upon the console log preferences.
278 If the preferences haven't been loaded loaded yet, display the
281 The default console_log_level preference value is such that only
282 ERROR, CRITICAL and WARNING level messages are processed;
283 MESSAGE, INFO and DEBUG level messages are ignored.
285 XXX: Aug 07, 2009: Prior tshark g_log code was hardwired to process only
286 ERROR and CRITICAL level messages so the current code is a behavioral
287 change. The current behavior is the same as in Wireshark.
289 if ((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
290 prefs.console_log_level != 0) {
294 g_log_default_handler(log_domain, log_level, message, user_data);
299 print_current_user(void) {
300 gchar *cur_user, *cur_group;
302 if (started_with_special_privs()) {
303 cur_user = get_cur_username();
304 cur_group = get_cur_groupname();
305 fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
306 cur_user, cur_group);
309 if (running_with_special_privs()) {
310 fprintf(stderr, " This could be dangerous.");
312 fprintf(stderr, "\n");
317 get_tfshark_runtime_version_info(GString *str)
319 /* stuff used by libwireshark */
320 epan_get_runtime_version_info(str);
324 main(int argc, char *argv[])
326 GString *comp_info_str;
327 GString *runtime_info_str;
328 char *init_progfile_dir_error;
330 static const struct option long_options[] = {
331 {"help", no_argument, NULL, 'h'},
332 {"version", no_argument, NULL, 'v'},
335 gboolean arg_error = FALSE;
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 macOS 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_warning_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 directory containing the
399 init_progfile_dir_error = init_progfile_dir(argv[0], main);
400 if (init_progfile_dir_error != NULL) {
402 "tfshark: Can't get pathname of directory containing the tfshark program: %s.\n",
403 init_progfile_dir_error);
404 g_free(init_progfile_dir_error);
407 initialize_funnel_ops();
409 /* Get the compile-time version information string */
410 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
412 /* Get the run-time version information string */
413 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
415 /* Add it to the information to be reported on a crash. */
416 ws_add_crash_info("TFShark (Wireshark) %s\n"
421 get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
422 g_string_free(comp_info_str, TRUE);
423 g_string_free(runtime_info_str, TRUE);
426 * In order to have the -X opts assigned before the wslua machine starts
427 * we need to call getopts before epan_init() gets called.
429 * In order to handle, for example, -o options, we also need to call it
430 * *after* epan_init() gets called, so that the dissectors have had a
431 * chance to register their preferences.
433 * XXX - can we do this all with one getopt_long() call, saving the
434 * arguments we can't handle until after initializing libwireshark,
435 * and then process them after initializing libwireshark?
439 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
441 case 'C': /* Configuration Profile */
442 if (profile_exists (optarg, FALSE)) {
443 set_profile_name (optarg);
445 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
449 case 'O': /* Only output these protocols */
450 output_only = g_strdup(optarg);
452 case 'V': /* Verbose */
453 print_details = TRUE;
454 print_packet_info = TRUE;
456 case 'x': /* Print packet data in hex (and ASCII) */
458 /* The user asked for hex output, so let's ensure they get it,
459 * even if they're writing to a file.
461 print_packet_info = TRUE;
472 * Print packet summary information is the default, unless either -V or -x
473 * were specified. Note that this is new behavior, which
474 * allows for the possibility of printing only hex/ascii output without
475 * necessarily requiring that either the summary or details be printed too.
477 if (print_summary == -1)
478 print_summary = (print_details || print_hex) ? FALSE : TRUE;
480 /** Send All g_log messages to our own handler **/
484 G_LOG_LEVEL_CRITICAL|
489 G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
491 g_log_set_handler(NULL,
492 (GLogLevelFlags)log_flags,
493 tfshark_log_handler, NULL /* user_data */);
494 g_log_set_handler(LOG_DOMAIN_MAIN,
495 (GLogLevelFlags)log_flags,
496 tfshark_log_handler, NULL /* user_data */);
498 init_report_message(failure_warning_message, failure_warning_message,
499 open_failure_message, read_failure_message,
500 write_failure_message);
502 timestamp_set_type(TS_RELATIVE);
503 timestamp_set_precision(TS_PREC_AUTO);
504 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
509 /* Register all the plugin types we have. */
510 epan_register_plugin_types(); /* Types known to libwireshark */
512 /* Scan for plugins. This does *not* call their registration routines;
513 that's done later. */
514 scan_plugins(REPORT_LOAD_FAILURE);
518 /* Register all dissectors; we must do this before checking for the
519 "-G" flag, as the "-G" flag dumps information registered by the
520 dissectors, and we must do it before we read the preferences, in
521 case any dissectors register preferences. */
522 if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
524 exit_status = INIT_ERROR;
528 /* Register all tap listeners; we do this before we parse the arguments,
529 as the "-z" argument can specify a registered tap. */
531 /* we register the plugin taps before the other taps because
532 stats_tree taps plugins will be registered as tap listeners
533 by stats_tree_stat.c and need to registered before that */
535 /* XXX Disable tap registration for now until we can get tfshark set up with
536 * its own set of taps and the necessary registration function etc.
538 register_all_plugin_tap_listeners();
540 register_all_tap_listeners();
543 /* If invoked with the "-G" flag, we dump out information based on
544 the argument to the "-G" flag; if no argument is specified,
545 for backwards compatibility we dump out a glossary of display
548 XXX - we do this here, for now, to support "-G" with no arguments.
549 If none of our build or other processes uses "-G" with no arguments,
550 we can just process it with the other arguments. */
551 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
552 proto_initialize_all_prefixes();
555 proto_registrar_dump_fields();
557 if (strcmp(argv[2], "column-formats") == 0)
558 column_dump_column_formats();
559 else if (strcmp(argv[2], "currentprefs") == 0) {
560 epan_load_settings();
563 else if (strcmp(argv[2], "decodes") == 0)
564 dissector_dump_decodes();
565 else if (strcmp(argv[2], "defaultprefs") == 0)
567 else if (strcmp(argv[2], "dissector-tables") == 0)
568 dissector_dump_dissector_tables();
569 else if (strcmp(argv[2], "fields") == 0)
570 proto_registrar_dump_fields();
571 else if (strcmp(argv[2], "ftypes") == 0)
572 proto_registrar_dump_ftypes();
573 else if (strcmp(argv[2], "heuristic-decodes") == 0)
574 dissector_dump_heur_decodes();
575 else if (strcmp(argv[2], "plugins") == 0) {
580 wslua_plugins_dump_all();
583 else if (strcmp(argv[2], "protocols") == 0)
584 proto_registrar_dump_protocols();
585 else if (strcmp(argv[2], "values") == 0)
586 proto_registrar_dump_values();
587 else if (strcmp(argv[2], "?") == 0)
588 glossary_option_help();
589 else if (strcmp(argv[2], "-?") == 0)
590 glossary_option_help();
592 cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
593 exit_status = INVALID_OPTION;
600 /* Load libwireshark settings from the current profile. */
601 prefs_p = epan_load_settings();
603 cap_file_init(&cfile);
605 /* Print format defaults to this. */
606 print_format = PR_FMT_TEXT;
608 output_fields = output_fields_new();
611 * To reset the options parser, set optreset to 1 on platforms that
612 * have optreset (documented in *BSD and macOS, apparently present but
613 * not documented in Solaris - the Illumos repository seems to
614 * suggest that the first Solaris getopt_long(), at least as of 2004,
615 * was based on the NetBSD one, it had optreset) and set optind to 1,
616 * and set optind to 0 otherwise (documented as working in the GNU
617 * getopt_long(). Setting optind to 0 didn't originally work in the
618 * NetBSD one, but that was added later - we don't want to depend on
619 * it if we have optreset).
621 * Also reset opterr to 1, so that error messages are printed by
632 /* Now get our args */
633 while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
635 case '2': /* Perform two pass analysis */
636 perform_two_pass_analysis = TRUE;
639 /* already processed; just ignore it now */
643 output_fields_add(output_fields, optarg);
647 if (!output_fields_set_option(output_fields, optarg)) {
648 cmdarg_err("\"%s\" is not a valid field output option=value pair.", optarg);
649 output_fields_list_options(stderr);
650 exit_status = INVALID_OPTION;
655 case 'h': /* Print help and exit */
656 printf("TFShark (Wireshark) %s\n"
657 "Dump and analyze network traffic.\n"
658 "See https://www.wireshark.org for more information.\n",
659 get_ws_vcs_version_info());
663 case 'l': /* "Line-buffer" standard output */
664 /* This isn't line-buffering, strictly speaking, it's just
665 flushing the standard output after the information for
666 each packet is printed; however, that should be good
667 enough for all the purposes to which "-l" is put (and
668 is probably actually better for "-V", as it does fewer
671 See the comment in "process_packet()" for an explanation of
672 why we do that, and why we don't just use "setvbuf()" to
673 make the standard output line-buffered (short version: in
674 Windows, "line-buffered" is the same as "fully-buffered",
675 and the output buffer is only flushed when it fills up). */
676 line_buffered = TRUE;
678 case 'o': /* Override preference from command line */
679 switch (prefs_set_pref(optarg)) {
684 case PREFS_SET_SYNTAX_ERR:
685 cmdarg_err("Invalid -o flag \"%s\"", optarg);
689 case PREFS_SET_NO_SUCH_PREF:
690 case PREFS_SET_OBSOLETE:
691 cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
692 exit_status = INVALID_OPTION;
697 case 'q': /* Quiet */
700 case 'Q': /* Really quiet */
704 case 'r': /* Read capture file x */
705 cf_name = g_strdup(optarg);
707 case 'R': /* Read file filter */
710 case 'S': /* Set the line Separator to be printed between packets */
711 separator = g_strdup(optarg);
713 case 'T': /* printing Type */
714 if (strcmp(optarg, "text") == 0) {
715 output_action = WRITE_TEXT;
716 print_format = PR_FMT_TEXT;
717 } else if (strcmp(optarg, "ps") == 0) {
718 output_action = WRITE_TEXT;
719 print_format = PR_FMT_PS;
720 } else if (strcmp(optarg, "pdml") == 0) {
721 output_action = WRITE_XML;
722 print_details = TRUE; /* Need details */
723 print_summary = FALSE; /* Don't allow summary */
724 } else if (strcmp(optarg, "psml") == 0) {
725 output_action = WRITE_XML;
726 print_details = FALSE; /* Don't allow details */
727 print_summary = TRUE; /* Need summary */
728 } else if (strcmp(optarg, "fields") == 0) {
729 output_action = WRITE_FIELDS;
730 print_details = TRUE; /* Need full tree info */
731 print_summary = FALSE; /* Don't allow summary */
733 cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg); /* x */
734 cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
735 "\t specified by the -E option.\n"
736 "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
737 "\t details of a decoded packet. This information is equivalent to\n"
738 "\t the packet details printed with the -V flag.\n"
739 "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
740 "\t the packets, or a multi-line view of the details of each of\n"
741 "\t the packets, depending on whether the -V flag was specified.\n"
742 "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
743 "\t summary information of a decoded packet. This information is\n"
744 "\t equivalent to the information shown in the one-line summary\n"
745 "\t printed by default.\n"
746 "\t\"text\" Text of a human-readable one-line summary of each of the\n"
747 "\t packets, or a multi-line view of the details of each of the\n"
748 "\t packets, depending on whether the -V flag was specified.\n"
749 "\t This is the default.");
750 exit_status = INVALID_OPTION;
754 case 'v': /* Show version and exit */
755 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
756 runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
757 show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
758 g_string_free(comp_info_str, TRUE);
759 g_string_free(runtime_info_str, TRUE);
761 case 'O': /* Only output these protocols */
762 /* already processed; just ignore it now */
764 case 'V': /* Verbose */
765 /* already processed; just ignore it now */
767 case 'x': /* Print packet data in hex (and ASCII) */
768 /* already processed; just ignore it now */
771 /* already processed; just ignore it now */
777 /* We won't call the init function for the stat this soon
778 as it would disallow MATE's fields (which are registered
779 by the preferences set callback) from being used as
780 part of a tap filter. Instead, we just add the argument
781 to a list of stat arguments. */
782 if (strcmp("help", optarg) == 0) {
783 fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
784 list_stat_cmd_args();
787 if (!process_stat_cmd_arg(optarg)) {
788 cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
789 list_stat_cmd_args();
790 exit_status = INVALID_OPTION;
794 case 'd': /* Decode as rule */
795 case 'K': /* Kerberos keytab file */
796 case 't': /* Time stamp type */
797 case 'u': /* Seconds type */
798 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
799 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
800 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
801 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
802 if (!dissect_opts_handle_opt(opt, optarg)) {
803 exit_status = INVALID_OPTION;
808 case '?': /* Bad flag - print usage message */
810 exit_status = INVALID_OPTION;
816 /* If we specified output fields, but not the output field type... */
817 if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
818 cmdarg_err("Output fields were specified with \"-e\", "
819 "but \"-Tfields\" was not specified.");
821 } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
822 cmdarg_err("\"-Tfields\" was specified, but no fields were "
823 "specified with \"-e\".");
825 exit_status = INVALID_OPTION;
829 /* If no capture filter or display filter has been specified, and there are
830 still command-line arguments, treat them as the tokens of a capture
831 filter (if no "-r" flag was specified) or a display filter (if a "-r"
832 flag was specified. */
834 if (cf_name != NULL) {
835 if (dfilter != NULL) {
836 cmdarg_err("Display filters were specified both with \"-d\" "
837 "and with additional command-line arguments.");
838 exit_status = INVALID_OPTION;
841 dfilter = get_args_as_string(argc, argv, optind);
845 /* if "-q" wasn't specified, we should print packet information */
847 print_packet_info = TRUE;
851 exit_status = INVALID_OPTION;
856 if (output_action != WRITE_TEXT) {
857 cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
858 exit_status = INVALID_OPTION;
863 if (output_only != NULL) {
866 if (!print_details) {
867 cmdarg_err("-O requires -V");
868 exit_status = INVALID_OPTION;
872 output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
873 for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
874 g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
878 if (rfilter != NULL && !perform_two_pass_analysis) {
879 cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
880 exit_status = INVALID_OPTION;
884 /* Notify all registered modules that have had any of their preferences
885 changed either from one of the preferences file or from the command
886 line that their preferences have changed. */
889 /* At this point MATE will have registered its field array so we can
890 have a tap filter with one of MATE's late-registered fields as part
891 of the filter. We can now process all the "-z" arguments. */
892 start_requested_stats();
895 * Enabled and disabled protocols and heuristic dissectors as per
896 * command-line options.
898 if (!setup_enabled_and_disabled_protocols()) {
899 exit_status = INVALID_OPTION;
903 /* Build the column format array */
904 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
906 if (rfilter != NULL) {
907 if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
908 cmdarg_err("%s", err_msg);
910 exit_status = INVALID_FILTER;
914 cfile.rfcode = rfcode;
916 if (dfilter != NULL) {
917 if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
918 cmdarg_err("%s", err_msg);
920 exit_status = INVALID_FILTER;
924 cfile.dfcode = dfcode;
926 if (print_packet_info) {
927 /* If we're printing as text or PostScript, we have
928 to create a print stream. */
929 if (output_action == WRITE_TEXT) {
930 switch (print_format) {
933 print_stream = print_stream_text_stdio_new(stdout);
937 print_stream = print_stream_ps_stdio_new(stdout);
941 g_assert_not_reached();
946 /* We have to dissect each packet if:
948 we're printing information about each packet;
950 we're using a read filter on the packets;
952 we're using a display filter on the packets;
954 we're using any taps that need dissection. */
955 do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
959 * We're reading a capture file.
962 /* TODO: if tfshark is ever changed to give the user a choice of which
963 open_routine reader to use, then the following needs to change. */
964 if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
965 exit_status = OPEN_ERROR;
969 /* Process the packets in the file */
971 /* XXX - for now there is only 1 packet */
972 err = load_cap_file(&cfile, 1, 0);
974 CATCH(OutOfMemoryError) {
978 "Sorry, but TFShark has to terminate now.\n"
980 "Some infos / workarounds can be found at:\n"
981 "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
987 /* We still dump out the results of taps, etc., as we might have
988 read some packets; however, we exit with an error status. */
995 if (cfile.frames != NULL) {
996 free_frame_data_sequence(cfile.frames);
1000 draw_tap_listeners(TRUE);
1001 funnel_dump_all_text_windows();
1004 destroy_print_stream(print_stream);
1005 epan_free(cfile.epan);
1011 output_fields_free(output_fields);
1012 output_fields = NULL;
1014 col_cleanup(&cfile.cinfo);
1019 static const nstime_t *
1020 tfshark_get_frame_ts(void *data, guint32 frame_num)
1022 capture_file *cf = (capture_file *) data;
1024 if (ref && ref->num == frame_num)
1025 return &ref->abs_ts;
1027 if (prev_dis && prev_dis->num == frame_num)
1028 return &prev_dis->abs_ts;
1030 if (prev_cap && prev_cap->num == frame_num)
1031 return &prev_cap->abs_ts;
1034 frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
1036 return (fd) ? &fd->abs_ts : NULL;
1043 no_interface_name(void *data _U_, guint32 interface_id _U_)
1049 tfshark_epan_new(capture_file *cf)
1051 epan_t *epan = epan_new();
1054 epan->get_frame_ts = tfshark_get_frame_ts;
1055 epan->get_interface_name = no_interface_name;
1056 epan->get_user_comment = NULL;
1062 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
1063 gint64 offset, struct wtap_pkthdr *whdr,
1070 /* The frame number of this packet is one more than the count of
1071 frames in this packet. */
1072 framenum = cf->count + 1;
1074 /* If we're not running a display filter and we're not printing any
1075 packet information, we don't need to do a dissection. This means
1076 that all packets can be marked as 'passed'. */
1079 frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
1081 /* If we're going to print packet information, or we're going to
1082 run a read filter, or display filter, or we're going to process taps, set up to
1083 do a dissection and do so. */
1085 /* If we're running a read filter, prime the epan_dissect_t with that
1088 epan_dissect_prime_dfilter(edt, cf->rfcode);
1090 frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
1092 if (ref == &fdlocal) {
1093 ref_frame = fdlocal;
1097 epan_dissect_file_run(edt, whdr, file_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
1099 /* Run the read filter if we have one. */
1101 passed = dfilter_apply_edt(cf->rfcode, edt);
1105 frame_data_set_after_dissect(&fdlocal, &cum_bytes);
1106 prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
1108 /* If we're not doing dissection then there won't be any dependent frames.
1109 * More importantly, edt.pi.dependent_frames won't be initialized because
1110 * epan hasn't been initialized.
1113 g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
1118 /* if we don't add it to the frame_data_sequence, clean it up right now
1120 frame_data_destroy(&fdlocal);
1124 epan_dissect_reset(edt);
1130 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt, frame_data *fdata,
1131 struct wtap_pkthdr *phdr, Buffer *buf,
1137 /* If we're not running a display filter and we're not printing any
1138 packet information, we don't need to do a dissection. This means
1139 that all packets can be marked as 'passed'. */
1142 /* If we're going to print packet information, or we're going to
1143 run a read filter, or we're going to process taps, set up to
1144 do a dissection and do so. */
1147 /* If we're running a display filter, prime the epan_dissect_t with that
1150 epan_dissect_prime_dfilter(edt, cf->dfcode);
1152 col_custom_prime_edt(edt, &cf->cinfo);
1154 /* We only need the columns if either
1155 1) some tap needs the columns
1157 2) we're printing packet info but we're *not* verbose; in verbose
1158 mode, we print the protocol tree, not the protocol summary.
1160 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
1165 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1172 epan_dissect_file_run_with_taps(edt, phdr, file_tvbuff_new_buffer(fdata, buf), fdata, cinfo);
1174 /* Run the read/display filter if we have one. */
1176 passed = dfilter_apply_edt(cf->dfcode, edt);
1180 frame_data_set_after_dissect(fdata, &cum_bytes);
1181 /* Process this packet. */
1182 if (print_packet_info) {
1183 /* We're printing packet information; print the information for
1185 print_packet(cf, edt);
1187 /* The ANSI C standard does not appear to *require* that a line-buffered
1188 stream be flushed to the host environment whenever a newline is
1189 written, it just says that, on such a stream, characters "are
1190 intended to be transmitted to or from the host environment as a
1191 block when a new-line character is encountered".
1193 The Visual C++ 6.0 C implementation doesn't do what is intended;
1194 even if you set a stream to be line-buffered, it still doesn't
1195 flush the buffer at the end of every line.
1197 So, if the "-l" flag was specified, we flush the standard output
1198 at the end of a packet. This will do the right thing if we're
1199 printing packet summary lines, and, as we print the entire protocol
1200 tree for a single packet without waiting for anything to happen,
1201 it should be as good as line-buffered mode if we're printing
1202 protocol trees. (The whole reason for the "-l" flag in either
1203 tcpdump or TShark is to allow the output of a live capture to
1204 be piped to a program or script and to have that script see the
1205 information for the packet as soon as it's printed, rather than
1206 having to wait until a standard I/O buffer fills up. */
1210 if (ferror(stdout)) {
1211 show_print_file_io_error(errno);
1220 epan_dissect_reset(edt);
1222 return passed || fdata->flags.dependent_of_displayed;
1226 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)
1228 /* int bytes_read; */
1229 gint64 packet_size = wtap_file_size(cf->wth, err);
1231 *data_buffer = (guint8*)g_malloc((gsize)packet_size);
1232 /* bytes_read =*/ file_read(*data_buffer, (unsigned int)packet_size, cf->wth->fh);
1234 #if 0 /* no more filetap */
1235 if (bytes_read < 0) {
1236 *err = file_error(cf->wth->fh, err_info);
1238 *err = FTAP_ERR_SHORT_READ;
1240 } else if (bytes_read == 0) {
1241 /* Done with file, no error */
1246 /* XXX - SET FRAME SIZE EQUAL TO TOTAL FILE SIZE */
1247 file_phdr->caplen = (guint32)packet_size;
1248 file_phdr->len = (guint32)packet_size;
1251 * Set the packet encapsulation to the file's encapsulation
1252 * value; if that's not WTAP_ENCAP_PER_PACKET, it's the
1253 * right answer (and means that the read routine for this
1254 * capture file type doesn't have to set it), and if it
1255 * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it
1258 wth->phdr.pkt_encap = wth->file_encap;
1260 if (!wth->subtype_read(wth, err, err_info, data_offset)) {
1262 * If we didn't get an error indication, we read
1263 * the last packet. See if there's any deferred
1264 * error, as might, for example, occur if we're
1265 * reading a compressed file, and we got an error
1266 * reading compressed data from the file, but
1267 * got enough compressed data to decompress the
1268 * last packet of the file.
1271 *err = file_error(wth->fh, err_info);
1272 return FALSE; /* failure */
1276 * It makes no sense for the captured data length to be bigger
1277 * than the actual data length.
1279 if (wth->phdr.caplen > wth->phdr.len)
1280 wth->phdr.caplen = wth->phdr.len;
1283 * Make sure that it's not WTAP_ENCAP_PER_PACKET, as that
1284 * probably means the file has that encapsulation type
1285 * but the read routine didn't set this packet's
1286 * encapsulation type.
1288 g_assert(wth->phdr.pkt_encap != WTAP_ENCAP_PER_PACKET);
1291 return TRUE; /* success */
1295 load_cap_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
1299 gchar *err_info = NULL;
1300 gint64 data_offset = 0;
1301 gboolean filtering_tap_listeners;
1304 epan_dissect_t *edt = NULL;
1305 struct wtap_pkthdr file_phdr;
1308 if (print_packet_info) {
1309 if (!write_preamble(cf)) {
1311 show_print_file_io_error(err);
1316 /* Do we have any tap listeners with filters? */
1317 filtering_tap_listeners = have_filtering_tap_listeners();
1319 /* Get the union of the flags for all tap listeners. */
1320 tap_flags = union_of_tap_listener_flags();
1322 wtap_phdr_init(&file_phdr);
1324 /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1325 file_phdr.pkt_encap = 1234;
1327 if (perform_two_pass_analysis) {
1330 /* Allocate a frame_data_sequence for all the frames. */
1331 cf->frames = new_frame_data_sequence();
1333 if (do_dissection) {
1334 gboolean create_proto_tree = FALSE;
1336 /* If we're going to be applying a filter, we'll need to
1337 create a protocol tree against which to apply the filter. */
1339 create_proto_tree = TRUE;
1341 /* We're not going to display the protocol tree on this pass,
1342 so it's not going to be "visible". */
1343 edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
1345 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1346 if (process_packet_first_pass(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1347 wtap_buf_ptr(cf->wth))) {
1349 /* Stop reading if we have the maximum number of packets;
1350 * When the -c option has not been used, max_packet_count
1351 * starts at 0, which practically means, never stop reading.
1352 * (unless we roll over max_packet_count ?)
1354 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1355 err = 0; /* This is not an error */
1362 epan_dissect_free(edt);
1367 /* Close the sequential I/O side, to free up memory it requires. */
1368 wtap_sequential_close(cf->wth);
1371 /* Allow the protocol dissectors to free up memory that they
1372 * don't need after the sequential run-through of the packets. */
1373 postseq_cleanup_all_protocols();
1377 ws_buffer_init(&buf, 1500);
1379 if (do_dissection) {
1380 gboolean create_proto_tree;
1382 if (cf->dfcode || print_details || filtering_tap_listeners ||
1383 (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo))
1384 create_proto_tree = TRUE;
1386 create_proto_tree = FALSE;
1388 /* The protocol tree will be "visible", i.e., printed, only if we're
1389 printing packet details, which is true if we're printing stuff
1390 ("print_packet_info" is true) and we're in verbose mode
1391 ("packet_details" is true). */
1392 edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1395 for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
1396 fdata = frame_data_sequence_find(cf->frames, framenum);
1398 if (wtap_seek_read(cf->wth, fdata->file_off,
1399 &buf, fdata->cap_len, &err, &err_info)) {
1400 process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1403 if (!process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags))
1409 epan_dissect_free(edt);
1413 ws_buffer_free(&buf);
1418 if (do_dissection) {
1419 gboolean create_proto_tree;
1421 if (cf->rfcode || 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 while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1438 if (!process_packet(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1439 raw_data, tap_flags))
1442 /* Stop reading if we have the maximum number of packets;
1443 * When the -c option has not been used, max_packet_count
1444 * starts at 0, which practically means, never stop reading.
1445 * (unless we roll over max_packet_count ?)
1447 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1448 err = 0; /* This is not an error */
1454 epan_dissect_free(edt);
1459 wtap_phdr_cleanup(&file_phdr);
1463 * Print a message noting that the read failed somewhere along the line.
1465 * If we're printing packet data, and the standard output and error are
1466 * going to the same place, flush the standard output, so everything
1467 * buffered up is written, and then print a newline to the standard error
1468 * before printing the error message, to separate it from the packet
1469 * data. (Alas, that only works on UN*X; st_dev is meaningless, and
1470 * the _fstat() documentation at Microsoft doesn't indicate whether
1471 * st_ino is even supported.)
1474 if (print_packet_info) {
1475 ws_statb64 stat_stdout, stat_stderr;
1477 if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
1478 if (stat_stdout.st_dev == stat_stderr.st_dev &&
1479 stat_stdout.st_ino == stat_stderr.st_ino) {
1481 fprintf(stderr, "\n");
1489 case FTAP_ERR_UNSUPPORTED:
1490 cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
1491 cf->filename, err_info);
1495 case FTAP_ERR_UNSUPPORTED_ENCAP:
1496 cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
1497 cf->filename, err_info);
1501 case FTAP_ERR_CANT_READ:
1502 cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
1506 case FTAP_ERR_SHORT_READ:
1507 cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
1511 case FTAP_ERR_BAD_FILE:
1512 cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
1513 cf->filename, err_info);
1517 case FTAP_ERR_DECOMPRESS:
1518 cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
1519 "(%s)", cf->filename, err_info);
1523 cmdarg_err("An error occurred while reading the file \"%s\": %s.",
1524 cf->filename, ftap_strerror(err));
1529 if (print_packet_info) {
1530 if (!write_finale()) {
1532 show_print_file_io_error(err);
1538 wtap_close(cf->wth);
1545 process_packet(capture_file *cf, epan_dissect_t *edt, gint64 offset,
1546 struct wtap_pkthdr *whdr, const guchar *pd, guint tap_flags)
1552 /* Count this packet. */
1555 /* If we're not running a display filter and we're not printing any
1556 packet information, we don't need to do a dissection. This means
1557 that all packets can be marked as 'passed'. */
1560 frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
1562 /* If we're going to print packet information, or we're going to
1563 run a read filter, or we're going to process taps, set up to
1564 do a dissection and do so. */
1566 /* If we're running a filter, prime the epan_dissect_t with that
1569 epan_dissect_prime_dfilter(edt, cf->dfcode);
1571 col_custom_prime_edt(edt, &cf->cinfo);
1573 /* We only need the columns if either
1574 1) some tap needs the columns
1576 2) we're printing packet info but we're *not* verbose; in verbose
1577 mode, we print the protocol tree, not the protocol summary.
1579 3) there is a column mapped as an individual field */
1580 if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
1585 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
1587 if (ref == &fdata) {
1592 epan_dissect_file_run_with_taps(edt, whdr, frame_tvbuff_new(&fdata, pd), &fdata, cinfo);
1594 /* Run the filter if we have it. */
1596 passed = dfilter_apply_edt(cf->dfcode, edt);
1600 frame_data_set_after_dissect(&fdata, &cum_bytes);
1602 /* Process this packet. */
1603 if (print_packet_info) {
1604 /* We're printing packet information; print the information for
1606 print_packet(cf, edt);
1608 /* The ANSI C standard does not appear to *require* that a line-buffered
1609 stream be flushed to the host environment whenever a newline is
1610 written, it just says that, on such a stream, characters "are
1611 intended to be transmitted to or from the host environment as a
1612 block when a new-line character is encountered".
1614 The Visual C++ 6.0 C implementation doesn't do what is intended;
1615 even if you set a stream to be line-buffered, it still doesn't
1616 flush the buffer at the end of every line.
1618 So, if the "-l" flag was specified, we flush the standard output
1619 at the end of a packet. This will do the right thing if we're
1620 printing packet summary lines, and, as we print the entire protocol
1621 tree for a single packet without waiting for anything to happen,
1622 it should be as good as line-buffered mode if we're printing
1623 protocol trees. (The whole reason for the "-l" flag in either
1624 tcpdump or TShark is to allow the output of a live capture to
1625 be piped to a program or script and to have that script see the
1626 information for the packet as soon as it's printed, rather than
1627 having to wait until a standard I/O buffer fills up. */
1631 if (ferror(stdout)) {
1632 show_print_file_io_error(errno);
1637 /* this must be set after print_packet() [bug #8160] */
1638 prev_dis_frame = fdata;
1639 prev_dis = &prev_dis_frame;
1642 prev_cap_frame = fdata;
1643 prev_cap = &prev_cap_frame;
1646 epan_dissect_reset(edt);
1647 frame_data_destroy(&fdata);
1653 write_preamble(capture_file *cf)
1655 switch (output_action) {
1658 return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
1662 write_pdml_preamble(stdout, cf->filename);
1664 write_psml_preamble(&cf->cinfo, stdout);
1665 return !ferror(stdout);
1668 write_fields_preamble(output_fields, stdout);
1669 return !ferror(stdout);
1672 g_assert_not_reached();
1678 get_line_buf(size_t len)
1680 static char *line_bufp = NULL;
1681 static size_t line_buf_len = 256;
1682 size_t new_line_buf_len;
1684 for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
1685 new_line_buf_len *= 2)
1687 if (line_bufp == NULL) {
1688 line_buf_len = new_line_buf_len;
1689 line_bufp = (char *)g_malloc(line_buf_len + 1);
1691 if (new_line_buf_len > line_buf_len) {
1692 line_buf_len = new_line_buf_len;
1693 line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
1700 put_string(char *dest, const char *str, size_t str_len)
1702 memcpy(dest, str, str_len);
1703 dest[str_len] = '\0';
1707 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1711 for (i = str_len; i < str_with_spaces; i++)
1714 put_string(dest, str, str_len);
1718 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1722 memcpy(dest, str, str_len);
1723 for (i = str_len; i < str_with_spaces; i++)
1726 dest[str_with_spaces] = '\0';
1730 print_columns(capture_file *cf)
1737 col_item_t* col_item;
1739 line_bufp = get_line_buf(256);
1742 for (i = 0; i < cf->cinfo.num_cols; i++) {
1743 col_item = &cf->cinfo.columns[i];
1744 /* Skip columns not marked as visible. */
1745 if (!get_column_visible(i))
1747 switch (col_item->col_fmt) {
1749 column_len = col_len = strlen(col_item->col_data);
1752 line_bufp = get_line_buf(buf_offset + column_len);
1753 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1759 case COL_ABS_YMD_TIME: /* XXX - wider */
1760 case COL_ABS_YDOY_TIME: /* XXX - wider */
1762 case COL_UTC_YMD_TIME: /* XXX - wider */
1763 case COL_UTC_YDOY_TIME: /* XXX - wider */
1764 column_len = col_len = strlen(col_item->col_data);
1765 if (column_len < 10)
1767 line_bufp = get_line_buf(buf_offset + column_len);
1768 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1774 case COL_DEF_DL_SRC:
1775 case COL_RES_DL_SRC:
1776 case COL_UNRES_DL_SRC:
1777 case COL_DEF_NET_SRC:
1778 case COL_RES_NET_SRC:
1779 case COL_UNRES_NET_SRC:
1780 column_len = col_len = strlen(col_item->col_data);
1781 if (column_len < 12)
1783 line_bufp = get_line_buf(buf_offset + column_len);
1784 put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1790 case COL_DEF_DL_DST:
1791 case COL_RES_DL_DST:
1792 case COL_UNRES_DL_DST:
1793 case COL_DEF_NET_DST:
1794 case COL_RES_NET_DST:
1795 case COL_UNRES_NET_DST:
1796 column_len = col_len = strlen(col_item->col_data);
1797 if (column_len < 12)
1799 line_bufp = get_line_buf(buf_offset + column_len);
1800 put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1804 column_len = strlen(col_item->col_data);
1805 line_bufp = get_line_buf(buf_offset + column_len);
1806 put_string(line_bufp + buf_offset, col_item->col_data, column_len);
1809 buf_offset += column_len;
1810 if (i != cf->cinfo.num_cols - 1) {
1812 * This isn't the last column, so we need to print a
1813 * separator between this column and the next.
1815 * If we printed a network source and are printing a
1816 * network destination of the same type next, separate
1817 * them with " -> "; if we printed a network destination
1818 * and are printing a network source of the same type
1819 * next, separate them with " <- "; otherwise separate them
1822 * We add enough space to the buffer for " <- " or " -> ",
1823 * even if we're only adding " ".
1825 line_bufp = get_line_buf(buf_offset + 4);
1826 switch (col_item->col_fmt) {
1831 switch (cf->cinfo.columns[i+1].col_fmt) {
1836 put_string(line_bufp + buf_offset, " -> ", 4);
1841 put_string(line_bufp + buf_offset, " ", 1);
1847 case COL_DEF_DL_SRC:
1848 case COL_RES_DL_SRC:
1849 case COL_UNRES_DL_SRC:
1850 switch (cf->cinfo.columns[i+1].col_fmt) {
1852 case COL_DEF_DL_DST:
1853 case COL_RES_DL_DST:
1854 case COL_UNRES_DL_DST:
1855 put_string(line_bufp + buf_offset, " -> ", 4);
1860 put_string(line_bufp + buf_offset, " ", 1);
1866 case COL_DEF_NET_SRC:
1867 case COL_RES_NET_SRC:
1868 case COL_UNRES_NET_SRC:
1869 switch (cf->cinfo.columns[i+1].col_fmt) {
1871 case COL_DEF_NET_DST:
1872 case COL_RES_NET_DST:
1873 case COL_UNRES_NET_DST:
1874 put_string(line_bufp + buf_offset, " -> ", 4);
1879 put_string(line_bufp + buf_offset, " ", 1);
1888 switch (cf->cinfo.columns[i+1].col_fmt) {
1893 put_string(line_bufp + buf_offset, " <- ", 4);
1898 put_string(line_bufp + buf_offset, " ", 1);
1904 case COL_DEF_DL_DST:
1905 case COL_RES_DL_DST:
1906 case COL_UNRES_DL_DST:
1907 switch (cf->cinfo.columns[i+1].col_fmt) {
1909 case COL_DEF_DL_SRC:
1910 case COL_RES_DL_SRC:
1911 case COL_UNRES_DL_SRC:
1912 put_string(line_bufp + buf_offset, " <- ", 4);
1917 put_string(line_bufp + buf_offset, " ", 1);
1923 case COL_DEF_NET_DST:
1924 case COL_RES_NET_DST:
1925 case COL_UNRES_NET_DST:
1926 switch (cf->cinfo.columns[i+1].col_fmt) {
1928 case COL_DEF_NET_SRC:
1929 case COL_RES_NET_SRC:
1930 case COL_UNRES_NET_SRC:
1931 put_string(line_bufp + buf_offset, " <- ", 4);
1936 put_string(line_bufp + buf_offset, " ", 1);
1943 put_string(line_bufp + buf_offset, " ", 1);
1949 return print_line(print_stream, 0, line_bufp);
1953 print_packet(capture_file *cf, epan_dissect_t *edt)
1955 print_args_t print_args;
1957 if (print_summary || output_fields_has_cols(output_fields)) {
1958 /* Just fill in the columns. */
1959 epan_dissect_fill_in_columns(edt, FALSE, TRUE);
1961 if (print_summary) {
1962 /* Now print them. */
1963 switch (output_action) {
1966 if (!print_columns(cf))
1971 write_psml_columns(edt, stdout);
1972 return !ferror(stdout);
1973 case WRITE_FIELDS: /*No non-verbose "fields" format */
1974 g_assert_not_reached();
1979 if (print_details) {
1980 /* Print the information in the protocol tree. */
1981 switch (output_action) {
1984 /* Only initialize the fields that are actually used in proto_tree_print.
1985 * This is particularly important for .range, as that's heap memory which
1986 * we would otherwise have to g_free().
1987 print_args.to_file = TRUE;
1988 print_args.format = print_format;
1989 print_args.print_summary = print_summary;
1990 print_args.print_formfeed = FALSE;
1991 packet_range_init(&print_args.range, &cfile);
1993 print_args.print_hex = print_hex;
1994 print_args.print_dissections = print_details ? print_dissections_expanded : print_dissections_none;
1996 if (!proto_tree_print(&print_args, edt, output_only_tables, print_stream))
1999 if (!print_line(print_stream, 0, separator))
2005 write_pdml_proto_tree(NULL, NULL, PF_NONE, edt, stdout);
2007 return !ferror(stdout);
2009 write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
2011 return !ferror(stdout);
2015 if (print_summary || print_details) {
2016 if (!print_line(print_stream, 0, ""))
2019 if (!print_hex_data(print_stream, edt))
2021 if (!print_line(print_stream, 0, separator))
2030 switch (output_action) {
2033 return print_finale(print_stream);
2037 write_pdml_finale(stdout);
2039 write_psml_finale(stdout);
2040 return !ferror(stdout);
2043 write_fields_finale(output_fields, stdout);
2044 return !ferror(stdout);
2047 g_assert_not_reached();
2053 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
2056 char err_msg[2048+1];
2058 /* The open isn't implemented yet. Fill in the information for this file. */
2060 /* Create new epan session for dissection. */
2061 epan_free(cf->epan);
2062 cf->epan = tfshark_epan_new(cf);
2064 cf->wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2065 cf->f_datalen = 0; /* not used, but set it anyway */
2067 /* Set the file name because we need it to set the follow stream filter.
2068 XXX - is that still true? We need it for other reasons, though,
2070 cf->filename = g_strdup(fname);
2072 /* Indicate whether it's a permanent or temporary file. */
2073 cf->is_tempfile = is_tempfile;
2075 /* No user changes yet. */
2076 cf->unsaved_changes = FALSE;
2078 cf->cd_t = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2079 cf->open_type = type;
2081 cf->drops_known = FALSE;
2083 cf->snap = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2084 if (cf->snap == 0) {
2085 /* Snapshot length not known. */
2086 cf->has_snap = FALSE;
2089 cf->has_snap = TRUE;
2090 nstime_set_zero(&cf->elapsed_time);
2095 cf->state = FILE_READ_IN_PROGRESS;
2100 g_snprintf(err_msg, sizeof err_msg,
2101 cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
2102 cmdarg_err("%s", err_msg);
2107 show_print_file_io_error(int err)
2112 cmdarg_err("Not all the packets could be printed because there is "
2113 "no space left on the file system.");
2118 cmdarg_err("Not all the packets could be printed because you are "
2119 "too close to, or over your disk quota.");
2124 cmdarg_err("An error occurred while printing packets: %s.",
2131 cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
2135 /* static char errmsg_errno[1024+1]; */
2139 /* Wiretap error. */
2142 case FTAP_ERR_NOT_REGULAR_FILE:
2143 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
2146 case FTAP_ERR_RANDOM_OPEN_PIPE:
2147 /* Seen only when opening a capture file for reading. */
2148 errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
2151 case FTAP_ERR_FILE_UNKNOWN_FORMAT:
2152 /* Seen only when opening a capture file for reading. */
2153 errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
2156 case FTAP_ERR_UNSUPPORTED:
2157 /* Seen only when opening a capture file for reading. */
2158 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2159 "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
2162 errmsg = errmsg_errno;
2165 case FTAP_ERR_CANT_WRITE_TO_PIPE:
2166 /* Seen only when opening a capture file for writing. */
2167 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2168 "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
2169 "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
2170 errmsg = errmsg_errno;
2173 case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
2174 /* Seen only when opening a capture file for writing. */
2175 errmsg = "TFShark doesn't support writing capture files in that format.";
2178 case FTAP_ERR_UNSUPPORTED_ENCAP:
2180 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2181 "TFShark can't save this capture as a \"%s\" file.",
2182 ftap_file_type_subtype_short_string(file_type));
2184 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2185 "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
2189 errmsg = errmsg_errno;
2192 case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
2194 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2195 "TFShark can't save this capture as a \"%s\" file.",
2196 ftap_file_type_subtype_short_string(file_type));
2197 errmsg = errmsg_errno;
2199 errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
2202 case FTAP_ERR_BAD_FILE:
2203 /* Seen only when opening a capture file for reading. */
2204 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2205 "The file \"%%s\" appears to be damaged or corrupt.\n"
2208 errmsg = errmsg_errno;
2211 case FTAP_ERR_CANT_OPEN:
2213 errmsg = "The file \"%s\" could not be created for some unknown reason.";
2215 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
2218 case FTAP_ERR_SHORT_READ:
2219 errmsg = "The file \"%s\" appears to have been cut short"
2220 " in the middle of a packet or other data.";
2223 case FTAP_ERR_SHORT_WRITE:
2224 errmsg = "A full header couldn't be written to the file \"%s\".";
2227 case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
2228 errmsg = "This file type cannot be written as a compressed file.";
2231 case FTAP_ERR_DECOMPRESS:
2232 /* Seen only when opening a capture file for reading. */
2233 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2234 "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
2237 errmsg = errmsg_errno;
2241 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2242 "The file \"%%s\" could not be %s: %s.",
2243 for_writing ? "created" : "opened",
2244 ftap_strerror(err));
2245 errmsg = errmsg_errno;
2250 errmsg = file_open_error_message(err, for_writing);
2255 * General errors and warnings are reported with an console message
2259 failure_warning_message(const char *msg_format, va_list ap)
2261 fprintf(stderr, "tfshark: ");
2262 vfprintf(stderr, msg_format, ap);
2263 fprintf(stderr, "\n");
2267 * Open/create errors are reported with an console message in TFShark.
2270 open_failure_message(const char *filename, int err, gboolean for_writing)
2272 fprintf(stderr, "tfshark: ");
2273 fprintf(stderr, file_open_error_message(err, for_writing), filename);
2274 fprintf(stderr, "\n");
2278 * Read errors are reported with an console message in TFShark.
2281 read_failure_message(const char *filename, int err)
2283 cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
2284 filename, g_strerror(err));
2288 * Write errors are reported with an console message in TFShark.
2291 write_failure_message(const char *filename, int err)
2293 cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
2294 filename, g_strerror(err));
2298 * Report additional information for an error in command-line arguments.
2301 failure_message_cont(const char *msg_format, va_list ap)
2303 vfprintf(stderr, msg_format, ap);
2304 fprintf(stderr, "\n");
2308 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2313 * indent-tabs-mode: nil
2316 * vi: set shiftwidth=2 tabstop=8 expandtab:
2317 * :indentSize=2:tabSize=8:noTabs=true: