CMake,editcap: avoid noise with editcap -F and -T options
[metze/wireshark/wip.git] / tfshark.c
1 /* tfshark.c
2  *
3  * Text-mode variant of Fileshark, based off of TShark,
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0+
10  */
11
12 #include <config.h>
13
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <locale.h>
18 #include <limits.h>
19
20 #ifdef HAVE_GETOPT_H
21 #include <getopt.h>
22 #endif
23
24 #include <errno.h>
25
26 #ifndef HAVE_GETOPT_LONG
27 #include "wsutil/wsgetopt.h"
28 #endif
29
30 #include <glib.h>
31
32 #include <epan/exceptions.h>
33 #include <epan/epan-int.h>
34 #include <epan/epan.h>
35
36 #include <wsutil/clopts_common.h>
37 #include <wsutil/cmdarg_err.h>
38 #include <wsutil/crash_info.h>
39 #include <wsutil/filesystem.h>
40 #include <wsutil/file_util.h>
41 #include <wsutil/privileges.h>
42 #include <wsutil/report_message.h>
43 #include <version_info.h>
44
45 #include "globals.h"
46 #include <epan/timestamp.h>
47 #include <epan/packet.h>
48 #ifdef HAVE_LUA
49 #include <epan/wslua/init_wslua.h>
50 #endif
51 #include "file.h"
52 #include "frame_tvbuff.h"
53 #include <epan/disabled_protos.h>
54 #include <epan/prefs.h>
55 #include <epan/column.h>
56 #include <epan/print.h>
57 #include <epan/addr_resolv.h>
58 #include "ui/util.h"
59 #include "ui/decode_as_utils.h"
60 #include "ui/dissect_opts.h"
61 #include "register.h"
62 #include <epan/epan_dissect.h>
63 #include <epan/tap.h>
64 #include <epan/stat_tap_ui.h>
65 #include <epan/ex-opt.h>
66
67 #ifdef HAVE_EXTCAP
68 #include "extcap.h"
69 #endif
70
71 #include <wiretap/wtap-int.h>
72 #include <wiretap/file_wrappers.h>
73
74 #ifdef _WIN32
75 #include <wsutil/unicode-utils.h>
76 #endif /* _WIN32 */
77
78 #include "log.h"
79 #include <epan/funnel.h>
80
81 #ifdef HAVE_PLUGINS
82 #include <wsutil/plugins.h>
83 #endif
84
85 #define INVALID_OPTION 1
86 #define INIT_ERROR 2
87 #define INVALID_FILTER 2
88 #define OPEN_ERROR 2
89
90 static guint32 cum_bytes;
91 static const frame_data *ref;
92 static frame_data ref_frame;
93 static frame_data *prev_dis;
94 static frame_data prev_dis_frame;
95 static frame_data *prev_cap;
96 static frame_data prev_cap_frame;
97
98 static gboolean prefs_loaded = FALSE;
99
100 static gboolean perform_two_pass_analysis;
101
102 /*
103  * The way the packet decode is to be written.
104  */
105 typedef enum {
106   WRITE_TEXT,   /* summary or detail text */
107   WRITE_XML,    /* PDML or PSML */
108   WRITE_FIELDS  /* User defined list of fields */
109   /* Add CSV and the like here */
110 } output_action_e;
111
112 static output_action_e output_action;
113 static gboolean do_dissection;     /* TRUE if we have to dissect each packet */
114 static gboolean print_packet_info; /* TRUE if we're to print packet information */
115 static gint print_summary = -1;    /* TRUE if we're to print packet summary information */
116 static gboolean print_details;     /* TRUE if we're to print packet details information */
117 static gboolean print_hex;         /* TRUE if we're to print hex/ascci information */
118 static gboolean line_buffered;
119 static gboolean really_quiet = FALSE;
120
121 static print_format_e print_format = PR_FMT_TEXT;
122 static print_stream_t *print_stream;
123
124 static output_fields_t* output_fields  = NULL;
125
126 /* The line separator used between packets, changeable via the -S option */
127 static const char *separator = "";
128
129 static gboolean process_file(capture_file *, int, gint64);
130 static gboolean process_packet_single_pass(capture_file *cf,
131     epan_dissect_t *edt, gint64 offset, struct wtap_pkthdr *whdr,
132     const guchar *pd, guint tap_flags);
133 static void show_print_file_io_error(int err);
134 static gboolean write_preamble(capture_file *cf);
135 static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
136 static gboolean write_finale(void);
137 static const char *cf_open_error_message(int err, gchar *err_info,
138     gboolean for_writing, int file_type);
139
140 static void failure_warning_message(const char *msg_format, va_list ap);
141 static void open_failure_message(const char *filename, int err,
142     gboolean for_writing);
143 static void read_failure_message(const char *filename, int err);
144 static void write_failure_message(const char *filename, int err);
145 static void failure_message_cont(const char *msg_format, va_list ap);
146
147 capture_file cfile;
148
149 static GHashTable *output_only_tables = NULL;
150
151 #if 0
152 struct string_elem {
153   const char *sstr;   /* The short string */
154   const char *lstr;   /* The long string */
155 };
156
157 static gint
158 string_compare(gconstpointer a, gconstpointer b)
159 {
160   return strcmp(((const struct string_elem *)a)->sstr,
161                 ((const struct string_elem *)b)->sstr);
162 }
163
164 static void
165 string_elem_print(gpointer data, gpointer not_used _U_)
166 {
167   fprintf(stderr, "    %s - %s\n",
168           ((struct string_elem *)data)->sstr,
169           ((struct string_elem *)data)->lstr);
170 }
171 #endif
172
173 static void
174 print_usage(FILE *output)
175 {
176   fprintf(output, "\n");
177   fprintf(output, "Usage: tfshark [options] ...\n");
178   fprintf(output, "\n");
179
180   /*fprintf(output, "\n");*/
181   fprintf(output, "Input file:\n");
182   fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin)\n");
183
184   fprintf(output, "\n");
185   fprintf(output, "Processing:\n");
186   fprintf(output, "  -2                       perform a two-pass analysis\n");
187   fprintf(output, "  -R <read filter>         packet Read filter in Wireshark display filter syntax\n");
188   fprintf(output, "                           (requires -2)\n");
189   fprintf(output, "  -Y <display filter>      packet displaY filter in Wireshark display filter\n");
190   fprintf(output, "                           syntax\n");
191   fprintf(output, "  -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
192   fprintf(output, "                           \"Decode As\", see the man page for details\n");
193   fprintf(output, "                           Example: tcp.port==8888,http\n");
194
195   /*fprintf(output, "\n");*/
196   fprintf(output, "Output:\n");
197   fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
198   fprintf(output, "  -V                       add output of packet tree        (Packet Details)\n");
199   fprintf(output, "  -O <protocols>           Only show packet details of these protocols, comma\n");
200   fprintf(output, "                           separated\n");
201   fprintf(output, "  -S <separator>           the line separator to print between packets\n");
202   fprintf(output, "  -x                       add output of hex and ASCII dump (Packet Bytes)\n");
203   fprintf(output, "  -T pdml|ps|psml|text|fields\n");
204   fprintf(output, "                           format of text output (def: text)\n");
205   fprintf(output, "  -e <field>               field to print if -Tfields selected (e.g. tcp.port,\n");
206   fprintf(output, "                           _ws.col.Info)\n");
207   fprintf(output, "                           this option can be repeated to print multiple fields\n");
208   fprintf(output, "  -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
209   fprintf(output, "     header=y|n            switch headers on and off\n");
210   fprintf(output, "     separator=/t|/s|<char> select tab, space, printable character as separator\n");
211   fprintf(output, "     occurrence=f|l|a      print first, last or all occurrences of each field\n");
212   fprintf(output, "     aggregator=,|/s|<char> select comma, space, printable character as\n");
213   fprintf(output, "                           aggregator\n");
214   fprintf(output, "     quote=d|s|n           select double, single, no quotes for values\n");
215   fprintf(output, "  -t a|ad|d|dd|e|r|u|ud    output format of time stamps (def: r: rel. to first)\n");
216   fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
217   fprintf(output, "  -l                       flush standard output after each packet\n");
218   fprintf(output, "  -q                       be more quiet on stdout (e.g. when using statistics)\n");
219   fprintf(output, "  -Q                       only log true errors to stderr (quieter than -q)\n");
220   fprintf(output, "  -X <key>:<value>         eXtension options, see the man page for details\n");
221   fprintf(output, "  -z <statistics>          various statistics, see the man page for details\n");
222
223   fprintf(output, "\n");
224   fprintf(output, "Miscellaneous:\n");
225   fprintf(output, "  -h                       display this help and exit\n");
226   fprintf(output, "  -v                       display version info and exit\n");
227   fprintf(output, "  -o <name>:<value> ...    override preference setting\n");
228   fprintf(output, "  -K <keytab>              keytab file to use for kerberos decryption\n");
229   fprintf(output, "  -G [report]              dump one of several available reports and exit\n");
230   fprintf(output, "                           default report=\"fields\"\n");
231   fprintf(output, "                           use \"-G ?\" for more help\n");
232 }
233
234 static void
235 glossary_option_help(void)
236 {
237   FILE *output;
238
239   output = stdout;
240
241   fprintf(output, "TFShark (Wireshark) %s\n", get_ws_vcs_version_info());
242
243   fprintf(output, "\n");
244   fprintf(output, "Usage: tfshark -G [report]\n");
245   fprintf(output, "\n");
246   fprintf(output, "Glossary table reports:\n");
247   fprintf(output, "  -G column-formats        dump column format codes and exit\n");
248   fprintf(output, "  -G decodes               dump \"layer type\"/\"decode as\" associations and exit\n");
249   fprintf(output, "  -G dissector-tables      dump dissector table names, types, and properties\n");
250   fprintf(output, "  -G fields                dump fields glossary and exit\n");
251   fprintf(output, "  -G ftypes                dump field type basic and descriptive names\n");
252   fprintf(output, "  -G heuristic-decodes     dump heuristic dissector tables\n");
253   fprintf(output, "  -G plugins               dump installed plugins and exit\n");
254   fprintf(output, "  -G protocols             dump protocols in registration database and exit\n");
255   fprintf(output, "  -G values                dump value, range, true/false strings and exit\n");
256   fprintf(output, "\n");
257   fprintf(output, "Preference reports:\n");
258   fprintf(output, "  -G currentprefs          dump current preferences and exit\n");
259   fprintf(output, "  -G defaultprefs          dump default preferences and exit\n");
260   fprintf(output, "\n");
261 }
262
263 static void
264 tfshark_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
265     const gchar *message, gpointer user_data)
266 {
267   /* ignore log message, if log_level isn't interesting based
268      upon the console log preferences.
269      If the preferences haven't been loaded yet, display the
270      message anyway.
271
272      The default console_log_level preference value is such that only
273        ERROR, CRITICAL and WARNING level messages are processed;
274        MESSAGE, INFO and DEBUG level messages are ignored.
275
276      XXX: Aug 07, 2009: Prior tshark g_log code was hardwired to process only
277            ERROR and CRITICAL level messages so the current code is a behavioral
278            change.  The current behavior is the same as in Wireshark.
279   */
280   if (prefs_loaded && (log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0) {
281     return;
282   }
283
284   g_log_default_handler(log_domain, log_level, message, user_data);
285
286 }
287
288 static void
289 print_current_user(void) {
290   gchar *cur_user, *cur_group;
291
292   if (started_with_special_privs()) {
293     cur_user = get_cur_username();
294     cur_group = get_cur_groupname();
295     fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
296       cur_user, cur_group);
297     g_free(cur_user);
298     g_free(cur_group);
299     if (running_with_special_privs()) {
300       fprintf(stderr, " This could be dangerous.");
301     }
302     fprintf(stderr, "\n");
303   }
304 }
305
306 static void
307 get_tfshark_runtime_version_info(GString *str)
308 {
309   /* stuff used by libwireshark */
310   epan_get_runtime_version_info(str);
311 }
312
313 int
314 main(int argc, char *argv[])
315 {
316   GString             *comp_info_str;
317   GString             *runtime_info_str;
318   char                *init_progfile_dir_error;
319   int                  opt;
320   static const struct option long_options[] = {
321     {"help", no_argument, NULL, 'h'},
322     {"version", no_argument, NULL, 'v'},
323     {0, 0, 0, 0 }
324   };
325   gboolean             arg_error = FALSE;
326
327   int                  err;
328   volatile gboolean    success;
329   volatile int         exit_status = 0;
330   gboolean             quiet = FALSE;
331   gchar               *volatile cf_name = NULL;
332   gchar               *rfilter = NULL;
333   gchar               *dfilter = NULL;
334   dfilter_t           *rfcode = NULL;
335   dfilter_t           *dfcode = NULL;
336   gchar               *err_msg;
337   e_prefs             *prefs_p;
338   int                  log_flags;
339   gchar               *output_only = NULL;
340
341 /*
342  * The leading + ensures that getopt_long() does not permute the argv[]
343  * entries.
344  *
345  * We have to make sure that the first getopt_long() preserves the content
346  * of argv[] for the subsequent getopt_long() call.
347  *
348  * We use getopt_long() in both cases to ensure that we're using a routine
349  * whose permutation behavior we can control in the same fashion on all
350  * platforms, and so that, if we ever need to process a long argument before
351  * doing further initialization, we can do so.
352  *
353  * Glibc and Solaris libc document that a leading + disables permutation
354  * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
355  * and macOS don't document it, but do so anyway.
356  *
357  * We do *not* use a leading - because the behavior of a leading - is
358  * platform-dependent.
359  */
360 #define OPTSTRING "+2C:d:e:E:hK:lo:O:qQr:R:S:t:T:u:vVxX:Y:z:"
361
362   static const char    optstring[] = OPTSTRING;
363
364   /* Set the C-language locale to the native environment. */
365   setlocale(LC_ALL, "");
366
367   cmdarg_err_init(failure_warning_message, failure_message_cont);
368
369 #ifdef _WIN32
370   arg_list_utf_16to8(argc, argv);
371   create_app_running_mutex();
372 #if !GLIB_CHECK_VERSION(2,31,0)
373   g_thread_init(NULL);
374 #endif
375 #endif /* _WIN32 */
376
377   /*
378    * Get credential information for later use, and drop privileges
379    * before doing anything else.
380    * Let the user know if anything happened.
381    */
382   init_process_policies();
383   relinquish_special_privs_perm();
384   print_current_user();
385
386   /*
387    * Attempt to get the pathname of the directory containing the
388    * executable file.
389    */
390   init_progfile_dir_error = init_progfile_dir(argv[0], main);
391   if (init_progfile_dir_error != NULL) {
392     fprintf(stderr,
393             "tfshark: Can't get pathname of directory containing the tfshark program: %s.\n",
394             init_progfile_dir_error);
395     g_free(init_progfile_dir_error);
396   }
397
398   initialize_funnel_ops();
399
400   /* Get the compile-time version information string */
401   comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
402
403   /* Get the run-time version information string */
404   runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
405
406   /* Add it to the information to be reported on a crash. */
407   ws_add_crash_info("TFShark (Wireshark) %s\n"
408          "\n"
409          "%s"
410          "\n"
411          "%s",
412       get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
413   g_string_free(comp_info_str, TRUE);
414   g_string_free(runtime_info_str, TRUE);
415
416   /*
417    * In order to have the -X opts assigned before the wslua machine starts
418    * we need to call getopts before epan_init() gets called.
419    *
420    * In order to handle, for example, -o options, we also need to call it
421    * *after* epan_init() gets called, so that the dissectors have had a
422    * chance to register their preferences.
423    *
424    * XXX - can we do this all with one getopt_long() call, saving the
425    * arguments we can't handle until after initializing libwireshark,
426    * and then process them after initializing libwireshark?
427    */
428   opterr = 0;
429
430   while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
431     switch (opt) {
432     case 'C':        /* Configuration Profile */
433       if (profile_exists (optarg, FALSE)) {
434         set_profile_name (optarg);
435       } else {
436         cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
437         return 1;
438       }
439       break;
440     case 'O':        /* Only output these protocols */
441       output_only = g_strdup(optarg);
442       /* FALLTHROUGH */
443     case 'V':        /* Verbose */
444       print_details = TRUE;
445       print_packet_info = TRUE;
446       break;
447     case 'x':        /* Print packet data in hex (and ASCII) */
448       print_hex = TRUE;
449       /*  The user asked for hex output, so let's ensure they get it,
450        *  even if they're writing to a file.
451        */
452       print_packet_info = TRUE;
453       break;
454     case 'X':
455       ex_opt_add(optarg);
456       break;
457     default:
458       break;
459     }
460   }
461
462   /*
463    * Print packet summary information is the default, unless either -V or -x
464    * were specified.  Note that this is new behavior, which
465    * allows for the possibility of printing only hex/ascii output without
466    * necessarily requiring that either the summary or details be printed too.
467    */
468   if (print_summary == -1)
469     print_summary = (print_details || print_hex) ? FALSE : TRUE;
470
471 /** Send All g_log messages to our own handler **/
472
473   log_flags =
474                     G_LOG_LEVEL_ERROR|
475                     G_LOG_LEVEL_CRITICAL|
476                     G_LOG_LEVEL_WARNING|
477                     G_LOG_LEVEL_MESSAGE|
478                     G_LOG_LEVEL_INFO|
479                     G_LOG_LEVEL_DEBUG|
480                     G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
481
482   g_log_set_handler(NULL,
483                     (GLogLevelFlags)log_flags,
484                     tfshark_log_handler, NULL /* user_data */);
485   g_log_set_handler(LOG_DOMAIN_MAIN,
486                     (GLogLevelFlags)log_flags,
487                     tfshark_log_handler, NULL /* user_data */);
488
489   init_report_message(failure_warning_message, failure_warning_message,
490                       open_failure_message, read_failure_message,
491                       write_failure_message);
492
493   timestamp_set_type(TS_RELATIVE);
494   timestamp_set_precision(TS_PREC_AUTO);
495   timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
496
497   wtap_init();
498
499 #ifdef HAVE_PLUGINS
500   /* Register all the plugin types we have. */
501   epan_register_plugin_types(); /* Types known to libwireshark */
502
503   /* Scan for plugins.  This does *not* call their registration routines;
504      that's done later. */
505   scan_plugins(REPORT_LOAD_FAILURE);
506
507 #endif
508
509   /* Register all dissectors; we must do this before checking for the
510      "-G" flag, as the "-G" flag dumps information registered by the
511      dissectors, and we must do it before we read the preferences, in
512      case any dissectors register preferences. */
513   if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
514                  NULL)) {
515     exit_status = INIT_ERROR;
516     goto clean_exit;
517   }
518
519   /* Register all tap listeners; we do this before we parse the arguments,
520      as the "-z" argument can specify a registered tap. */
521
522   /* we register the plugin taps before the other taps because
523      stats_tree taps plugins will be registered as tap listeners
524      by stats_tree_stat.c and need to registered before that */
525
526   /* XXX Disable tap registration for now until we can get tfshark set up with
527    * its own set of taps and the necessary registration function etc.
528 #ifdef HAVE_PLUGINS
529   register_all_plugin_tap_listeners();
530 #endif
531   register_all_tap_listeners();
532   */
533
534   /* If invoked with the "-G" flag, we dump out information based on
535      the argument to the "-G" flag; if no argument is specified,
536      for backwards compatibility we dump out a glossary of display
537      filter symbols.
538
539      XXX - we do this here, for now, to support "-G" with no arguments.
540      If none of our build or other processes uses "-G" with no arguments,
541      we can just process it with the other arguments. */
542   if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
543     proto_initialize_all_prefixes();
544
545     if (argc == 2)
546       proto_registrar_dump_fields();
547     else {
548       if (strcmp(argv[2], "column-formats") == 0)
549         column_dump_column_formats();
550       else if (strcmp(argv[2], "currentprefs") == 0) {
551         epan_load_settings();
552         write_prefs(NULL);
553       }
554       else if (strcmp(argv[2], "decodes") == 0)
555         dissector_dump_decodes();
556       else if (strcmp(argv[2], "defaultprefs") == 0)
557         write_prefs(NULL);
558       else if (strcmp(argv[2], "dissector-tables") == 0)
559         dissector_dump_dissector_tables();
560       else if (strcmp(argv[2], "fields") == 0)
561         proto_registrar_dump_fields();
562       else if (strcmp(argv[2], "ftypes") == 0)
563         proto_registrar_dump_ftypes();
564       else if (strcmp(argv[2], "heuristic-decodes") == 0)
565         dissector_dump_heur_decodes();
566       else if (strcmp(argv[2], "plugins") == 0) {
567 #ifdef HAVE_PLUGINS
568         plugins_dump_all();
569 #endif
570 #ifdef HAVE_LUA
571         wslua_plugins_dump_all();
572 #endif
573       }
574       else if (strcmp(argv[2], "protocols") == 0)
575         proto_registrar_dump_protocols();
576       else if (strcmp(argv[2], "values") == 0)
577         proto_registrar_dump_values();
578       else if (strcmp(argv[2], "?") == 0)
579         glossary_option_help();
580       else if (strcmp(argv[2], "-?") == 0)
581         glossary_option_help();
582       else {
583         cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
584         exit_status = INVALID_OPTION;
585         goto clean_exit;
586       }
587     }
588     goto clean_exit;
589   }
590
591   /* Load libwireshark settings from the current profile. */
592   prefs_p = epan_load_settings();
593   prefs_loaded = TRUE;
594
595   cap_file_init(&cfile);
596
597   /* Print format defaults to this. */
598   print_format = PR_FMT_TEXT;
599
600   output_fields = output_fields_new();
601
602   /*
603    * To reset the options parser, set optreset to 1 on platforms that
604    * have optreset (documented in *BSD and macOS, apparently present but
605    * not documented in Solaris - the Illumos repository seems to
606    * suggest that the first Solaris getopt_long(), at least as of 2004,
607    * was based on the NetBSD one, it had optreset) and set optind to 1,
608    * and set optind to 0 otherwise (documented as working in the GNU
609    * getopt_long().  Setting optind to 0 didn't originally work in the
610    * NetBSD one, but that was added later - we don't want to depend on
611    * it if we have optreset).
612    *
613    * Also reset opterr to 1, so that error messages are printed by
614    * getopt_long().
615    */
616 #ifdef HAVE_OPTRESET
617   optreset = 1;
618   optind = 1;
619 #else
620   optind = 0;
621 #endif
622   opterr = 1;
623
624   /* Now get our args */
625   while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
626     switch (opt) {
627     case '2':        /* Perform two pass analysis */
628       perform_two_pass_analysis = TRUE;
629       break;
630     case 'C':
631       /* already processed; just ignore it now */
632       break;
633     case 'e':
634       /* Field entry */
635       output_fields_add(output_fields, optarg);
636       break;
637     case 'E':
638       /* Field option */
639       if (!output_fields_set_option(output_fields, optarg)) {
640         cmdarg_err("\"%s\" is not a valid field output option=value pair.", optarg);
641         output_fields_list_options(stderr);
642         exit_status = INVALID_OPTION;
643         goto clean_exit;
644       }
645       break;
646
647     case 'h':        /* Print help and exit */
648       printf("TFShark (Wireshark) %s\n"
649              "Dump and analyze network traffic.\n"
650              "See https://www.wireshark.org for more information.\n",
651              get_ws_vcs_version_info());
652       print_usage(stdout);
653       goto clean_exit;
654       break;
655     case 'l':        /* "Line-buffer" standard output */
656       /* The ANSI C standard does not appear to *require* that a line-buffered
657          stream be flushed to the host environment whenever a newline is
658          written, it just says that, on such a stream, characters "are
659          intended to be transmitted to or from the host environment as a
660          block when a new-line character is encountered".
661
662          The Visual C++ 6.0 C implementation doesn't do what is intended;
663          even if you set a stream to be line-buffered, it still doesn't
664          flush the buffer at the end of every line.
665
666          The whole reason for the "-l" flag in either tcpdump or TShark
667          is to allow the output of a live capture to be piped to a program
668          or script and to have that script see the information for the
669          packet as soon as it's printed, rather than having to wait until
670          a standard I/O buffer fills up.
671
672          So, if the "-l" flag is specified, we flush the standard output
673          at the end of a packet.  This will do the right thing if we're
674          printing packet summary lines, and, as we print the entire protocol
675          tree for a single packet without waiting for anything to happen,
676          it should be as good as line-buffered mode if we're printing
677          protocol trees - arguably even better, as it may do fewer
678          writes. */
679       line_buffered = TRUE;
680       break;
681     case 'o':        /* Override preference from command line */
682     {
683       char *errmsg = NULL;
684
685       switch (prefs_set_pref(optarg, &errmsg)) {
686
687       case PREFS_SET_OK:
688         break;
689
690       case PREFS_SET_SYNTAX_ERR:
691         cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg,
692             errmsg ? ": " : "", errmsg ? errmsg : "");
693         g_free(errmsg);
694         return 1;
695         break;
696
697       case PREFS_SET_NO_SUCH_PREF:
698       case PREFS_SET_OBSOLETE:
699         cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
700         exit_status = INVALID_OPTION;
701         goto clean_exit;
702         break;
703       }
704       break;
705     }
706     case 'q':        /* Quiet */
707       quiet = TRUE;
708       break;
709     case 'Q':        /* Really quiet */
710       quiet = TRUE;
711       really_quiet = TRUE;
712       break;
713     case 'r':        /* Read capture file x */
714       cf_name = g_strdup(optarg);
715       break;
716     case 'R':        /* Read file filter */
717       rfilter = optarg;
718       break;
719     case 'S':        /* Set the line Separator to be printed between packets */
720       separator = g_strdup(optarg);
721       break;
722     case 'T':        /* printing Type */
723       if (strcmp(optarg, "text") == 0) {
724         output_action = WRITE_TEXT;
725         print_format = PR_FMT_TEXT;
726       } else if (strcmp(optarg, "ps") == 0) {
727         output_action = WRITE_TEXT;
728         print_format = PR_FMT_PS;
729       } else if (strcmp(optarg, "pdml") == 0) {
730         output_action = WRITE_XML;
731         print_details = TRUE;   /* Need details */
732         print_summary = FALSE;  /* Don't allow summary */
733       } else if (strcmp(optarg, "psml") == 0) {
734         output_action = WRITE_XML;
735         print_details = FALSE;  /* Don't allow details */
736         print_summary = TRUE;   /* Need summary */
737       } else if (strcmp(optarg, "fields") == 0) {
738         output_action = WRITE_FIELDS;
739         print_details = TRUE;   /* Need full tree info */
740         print_summary = FALSE;  /* Don't allow summary */
741       } else {
742         cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg);                   /* x */
743         cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
744                         "\t         specified by the -E option.\n"
745                         "\t\"pdml\"   Packet Details Markup Language, an XML-based format for the\n"
746                         "\t         details of a decoded packet. This information is equivalent to\n"
747                         "\t         the packet details printed with the -V flag.\n"
748                         "\t\"ps\"     PostScript for a human-readable one-line summary of each of\n"
749                         "\t         the packets, or a multi-line view of the details of each of\n"
750                         "\t         the packets, depending on whether the -V flag was specified.\n"
751                         "\t\"psml\"   Packet Summary Markup Language, an XML-based format for the\n"
752                         "\t         summary information of a decoded packet. This information is\n"
753                         "\t         equivalent to the information shown in the one-line summary\n"
754                         "\t         printed by default.\n"
755                         "\t\"text\"   Text of a human-readable one-line summary of each of the\n"
756                         "\t         packets, or a multi-line view of the details of each of the\n"
757                         "\t         packets, depending on whether the -V flag was specified.\n"
758                         "\t         This is the default.");
759         exit_status = INVALID_OPTION;
760         goto clean_exit;
761       }
762       break;
763     case 'v':         /* Show version and exit */
764       comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
765       runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
766       show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
767       g_string_free(comp_info_str, TRUE);
768       g_string_free(runtime_info_str, TRUE);
769       goto clean_exit;
770     case 'O':        /* Only output these protocols */
771       /* already processed; just ignore it now */
772       break;
773     case 'V':        /* Verbose */
774       /* already processed; just ignore it now */
775       break;
776     case 'x':        /* Print packet data in hex (and ASCII) */
777       /* already processed; just ignore it now */
778       break;
779     case 'X':
780       /* already processed; just ignore it now */
781       break;
782     case 'Y':
783       dfilter = optarg;
784       break;
785     case 'z':
786       /* We won't call the init function for the stat this soon
787          as it would disallow MATE's fields (which are registered
788          by the preferences set callback) from being used as
789          part of a tap filter.  Instead, we just add the argument
790          to a list of stat arguments. */
791       if (strcmp("help", optarg) == 0) {
792         fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
793         list_stat_cmd_args();
794         goto clean_exit;
795       }
796       if (!process_stat_cmd_arg(optarg)) {
797         cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
798         list_stat_cmd_args();
799         exit_status = INVALID_OPTION;
800         goto clean_exit;
801       }
802       break;
803     case 'd':        /* Decode as rule */
804     case 'K':        /* Kerberos keytab file */
805     case 't':        /* Time stamp type */
806     case 'u':        /* Seconds type */
807     case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
808     case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
809     case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
810     case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
811       if (!dissect_opts_handle_opt(opt, optarg)) {
812         exit_status = INVALID_OPTION;
813         goto clean_exit;
814       }
815       break;
816     default:
817     case '?':        /* Bad flag - print usage message */
818       print_usage(stderr);
819       exit_status = INVALID_OPTION;
820       goto clean_exit;
821       break;
822     }
823   }
824
825   /* If we specified output fields, but not the output field type... */
826   if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
827         cmdarg_err("Output fields were specified with \"-e\", "
828             "but \"-Tfields\" was not specified.");
829         return 1;
830   } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
831         cmdarg_err("\"-Tfields\" was specified, but no fields were "
832                     "specified with \"-e\".");
833
834         exit_status = INVALID_OPTION;
835         goto clean_exit;
836   }
837
838   /* If no capture filter or display filter has been specified, and there are
839      still command-line arguments, treat them as the tokens of a capture
840      filter (if no "-r" flag was specified) or a display filter (if a "-r"
841      flag was specified. */
842   if (optind < argc) {
843     if (cf_name != NULL) {
844       if (dfilter != NULL) {
845         cmdarg_err("Display filters were specified both with \"-d\" "
846             "and with additional command-line arguments.");
847         exit_status = INVALID_OPTION;
848         goto clean_exit;
849       }
850       dfilter = get_args_as_string(argc, argv, optind);
851     }
852   }
853
854   /* if "-q" wasn't specified, we should print packet information */
855   if (!quiet)
856     print_packet_info = TRUE;
857
858   if (arg_error) {
859     print_usage(stderr);
860     exit_status = INVALID_OPTION;
861     goto clean_exit;
862   }
863
864   if (print_hex) {
865     if (output_action != WRITE_TEXT) {
866       cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
867       exit_status = INVALID_OPTION;
868       goto clean_exit;
869     }
870   }
871
872   if (output_only != NULL) {
873     char *ps;
874
875     if (!print_details) {
876       cmdarg_err("-O requires -V");
877       exit_status = INVALID_OPTION;
878       goto clean_exit;
879     }
880
881     output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
882     for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
883       g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
884     }
885   }
886
887   if (rfilter != NULL && !perform_two_pass_analysis) {
888     cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
889     exit_status = INVALID_OPTION;
890     goto clean_exit;
891   }
892
893   /* Notify all registered modules that have had any of their preferences
894      changed either from one of the preferences file or from the command
895      line that their preferences have changed. */
896   prefs_apply_all();
897
898   /* At this point MATE will have registered its field array so we can
899      have a tap filter with one of MATE's late-registered fields as part
900      of the filter.  We can now process all the "-z" arguments. */
901   start_requested_stats();
902
903   /*
904    * Enabled and disabled protocols and heuristic dissectors as per
905    * command-line options.
906    */
907   if (!setup_enabled_and_disabled_protocols()) {
908     exit_status = INVALID_OPTION;
909     goto clean_exit;
910   }
911
912   /* Build the column format array */
913   build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
914
915   if (rfilter != NULL) {
916     if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
917       cmdarg_err("%s", err_msg);
918       g_free(err_msg);
919       exit_status = INVALID_FILTER;
920       goto clean_exit;
921     }
922   }
923   cfile.rfcode = rfcode;
924
925   if (dfilter != NULL) {
926     if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
927       cmdarg_err("%s", err_msg);
928       g_free(err_msg);
929       exit_status = INVALID_FILTER;
930       goto clean_exit;
931     }
932   }
933   cfile.dfcode = dfcode;
934
935   if (print_packet_info) {
936     /* If we're printing as text or PostScript, we have
937        to create a print stream. */
938     if (output_action == WRITE_TEXT) {
939       switch (print_format) {
940
941       case PR_FMT_TEXT:
942         print_stream = print_stream_text_stdio_new(stdout);
943         break;
944
945       case PR_FMT_PS:
946         print_stream = print_stream_ps_stdio_new(stdout);
947         break;
948
949       default:
950         g_assert_not_reached();
951       }
952     }
953   }
954
955   /* We have to dissect each packet if:
956
957         we're printing information about each packet;
958
959         we're using a read filter on the packets;
960
961         we're using a display filter on the packets;
962
963         we're using any taps that need dissection. */
964   do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
965
966   if (cf_name) {
967     /*
968      * We're reading a capture file.
969      */
970
971     /* TODO: if tfshark is ever changed to give the user a choice of which
972        open_routine reader to use, then the following needs to change. */
973     if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
974       exit_status = OPEN_ERROR;
975       goto clean_exit;
976     }
977
978     /* Process the packets in the file */
979     TRY {
980       /* XXX - for now there is only 1 packet */
981       success = process_file(&cfile, 1, 0);
982     }
983     CATCH(OutOfMemoryError) {
984       fprintf(stderr,
985               "Out Of Memory.\n"
986               "\n"
987               "Sorry, but TFShark has to terminate now.\n"
988               "\n"
989               "Some infos / workarounds can be found at:\n"
990               "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
991       success = FALSE;
992     }
993     ENDTRY;
994
995     if (!success) {
996       /* We still dump out the results of taps, etc., as we might have
997          read some packets; however, we exit with an error status. */
998       exit_status = 2;
999     }
1000   }
1001
1002   g_free(cf_name);
1003
1004   if (cfile.frames != NULL) {
1005     free_frame_data_sequence(cfile.frames);
1006     cfile.frames = NULL;
1007   }
1008
1009   draw_tap_listeners(TRUE);
1010   funnel_dump_all_text_windows();
1011
1012 clean_exit:
1013   destroy_print_stream(print_stream);
1014   epan_free(cfile.epan);
1015   epan_cleanup();
1016 #ifdef HAVE_EXTCAP
1017   extcap_cleanup();
1018 #endif
1019
1020   output_fields_free(output_fields);
1021   output_fields = NULL;
1022
1023   col_cleanup(&cfile.cinfo);
1024   wtap_cleanup();
1025   return exit_status;
1026 }
1027
1028 static const nstime_t *
1029 tfshark_get_frame_ts(void *data, guint32 frame_num)
1030 {
1031   capture_file *cf = (capture_file *) data;
1032
1033   if (ref && ref->num == frame_num)
1034     return &ref->abs_ts;
1035
1036   if (prev_dis && prev_dis->num == frame_num)
1037     return &prev_dis->abs_ts;
1038
1039   if (prev_cap && prev_cap->num == frame_num)
1040     return &prev_cap->abs_ts;
1041
1042   if (cf->frames) {
1043      frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
1044
1045      return (fd) ? &fd->abs_ts : NULL;
1046   }
1047
1048   return NULL;
1049 }
1050
1051 static const char *
1052 no_interface_name(void *data _U_, guint32 interface_id _U_)
1053 {
1054     return "";
1055 }
1056
1057 static epan_t *
1058 tfshark_epan_new(capture_file *cf)
1059 {
1060   epan_t *epan = epan_new();
1061
1062   epan->data = cf;
1063   epan->get_frame_ts = tfshark_get_frame_ts;
1064   epan->get_interface_name = no_interface_name;
1065   epan->get_user_comment = NULL;
1066
1067   return epan;
1068 }
1069
1070 static gboolean
1071 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
1072                           gint64 offset, struct wtap_pkthdr *whdr,
1073                           const guchar *pd)
1074 {
1075   frame_data     fdlocal;
1076   guint32        framenum;
1077   gboolean       passed;
1078
1079   /* The frame number of this packet is one more than the count of
1080      frames in this packet. */
1081   framenum = cf->count + 1;
1082
1083   /* If we're not running a display filter and we're not printing any
1084      packet information, we don't need to do a dissection. This means
1085      that all packets can be marked as 'passed'. */
1086   passed = TRUE;
1087
1088   frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
1089
1090   /* If we're going to print packet information, or we're going to
1091      run a read filter, or display filter, or we're going to process taps, set up to
1092      do a dissection and do so. */
1093   if (edt) {
1094     /* If we're running a read filter, prime the epan_dissect_t with that
1095        filter. */
1096     if (cf->rfcode)
1097       epan_dissect_prime_with_dfilter(edt, cf->rfcode);
1098
1099     /* This is the first pass, so prime the epan_dissect_t with the
1100        hfids postdissectors want on the first pass. */
1101     prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1102
1103     frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
1104                                   &ref, prev_dis);
1105     if (ref == &fdlocal) {
1106       ref_frame = fdlocal;
1107       ref = &ref_frame;
1108     }
1109
1110     epan_dissect_file_run(edt, whdr, file_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
1111
1112     /* Run the read filter if we have one. */
1113     if (cf->rfcode)
1114       passed = dfilter_apply_edt(cf->rfcode, edt);
1115   }
1116
1117   if (passed) {
1118     frame_data_set_after_dissect(&fdlocal, &cum_bytes);
1119     prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
1120
1121     /* If we're not doing dissection then there won't be any dependent frames.
1122      * More importantly, edt.pi.dependent_frames won't be initialized because
1123      * epan hasn't been initialized.
1124      */
1125     if (edt) {
1126       g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
1127     }
1128
1129     cf->count++;
1130   } else {
1131     /* if we don't add it to the frame_data_sequence, clean it up right now
1132      * to avoid leaks */
1133     frame_data_destroy(&fdlocal);
1134   }
1135
1136   if (edt)
1137     epan_dissect_reset(edt);
1138
1139   return passed;
1140 }
1141
1142 static gboolean
1143 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
1144                            frame_data *fdata, struct wtap_pkthdr *phdr,
1145                            Buffer *buf, guint tap_flags)
1146 {
1147   column_info    *cinfo;
1148   gboolean        passed;
1149
1150   /* If we're not running a display filter and we're not printing any
1151      packet information, we don't need to do a dissection. This means
1152      that all packets can be marked as 'passed'. */
1153   passed = TRUE;
1154
1155   /* If we're going to print packet information, or we're going to
1156      run a read filter, or we're going to process taps, set up to
1157      do a dissection and do so. */
1158   if (edt) {
1159
1160     /* If we're running a display filter, prime the epan_dissect_t with that
1161        filter. */
1162     if (cf->dfcode)
1163       epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1164
1165     /* This is the first and only pass, so prime the epan_dissect_t
1166        with the hfids postdissectors want on the first pass. */
1167     prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1168
1169     col_custom_prime_edt(edt, &cf->cinfo);
1170
1171     /* We only need the columns if either
1172          1) some tap needs the columns
1173        or
1174          2) we're printing packet info but we're *not* verbose; in verbose
1175             mode, we print the protocol tree, not the protocol summary.
1176      */
1177     if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
1178       cinfo = &cf->cinfo;
1179     else
1180       cinfo = NULL;
1181
1182     frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1183                                   &ref, prev_dis);
1184     if (ref == fdata) {
1185       ref_frame = *fdata;
1186       ref = &ref_frame;
1187     }
1188
1189     epan_dissect_file_run_with_taps(edt, phdr, file_tvbuff_new_buffer(fdata, buf), fdata, cinfo);
1190
1191     /* Run the read/display filter if we have one. */
1192     if (cf->dfcode)
1193       passed = dfilter_apply_edt(cf->dfcode, edt);
1194   }
1195
1196   if (passed) {
1197     frame_data_set_after_dissect(fdata, &cum_bytes);
1198     /* Process this packet. */
1199     if (print_packet_info) {
1200       /* We're printing packet information; print the information for
1201          this packet. */
1202       print_packet(cf, edt);
1203
1204       /* If we're doing "line-buffering", flush the standard output
1205          after every packet.  See the comment above, for the "-l"
1206          option, for an explanation of why we do that. */
1207       if (line_buffered)
1208         fflush(stdout);
1209
1210       if (ferror(stdout)) {
1211         show_print_file_io_error(errno);
1212         return FALSE;
1213       }
1214     }
1215     prev_dis = fdata;
1216   }
1217   prev_cap = fdata;
1218
1219   if (edt) {
1220     epan_dissect_reset(edt);
1221   }
1222   return passed || fdata->flags.dependent_of_displayed;
1223 }
1224
1225 static gboolean
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)
1227 {
1228     /* int bytes_read; */
1229     gint64 packet_size = wtap_file_size(cf->wth, err);
1230
1231     *data_buffer = (guint8*)g_malloc((gsize)packet_size);
1232     /* bytes_read =*/ file_read(*data_buffer, (unsigned int)packet_size, cf->wth->fh);
1233
1234 #if 0 /* no more filetap */
1235     if (bytes_read < 0) {
1236         *err = file_error(cf->wth->fh, err_info);
1237         if (*err == 0)
1238             *err = FTAP_ERR_SHORT_READ;
1239         return FALSE;
1240     } else if (bytes_read == 0) {
1241         /* Done with file, no error */
1242         return FALSE;
1243     }
1244
1245
1246     /* XXX - SET FRAME SIZE EQUAL TO TOTAL FILE SIZE */
1247     file_phdr->caplen = (guint32)packet_size;
1248     file_phdr->len = (guint32)packet_size;
1249
1250     /*
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
1256      * anyway.
1257      */
1258     wth->phdr.pkt_encap = wth->file_encap;
1259
1260     if (!wth->subtype_read(wth, err, err_info, data_offset)) {
1261         /*
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.
1269          */
1270         if (*err == 0)
1271             *err = file_error(wth->fh, err_info);
1272         return FALSE;    /* failure */
1273     }
1274
1275     /*
1276      * It makes no sense for the captured data length to be bigger
1277      * than the actual data length.
1278      */
1279     if (wth->phdr.caplen > wth->phdr.len)
1280         wth->phdr.caplen = wth->phdr.len;
1281
1282     /*
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.
1287      */
1288     g_assert(wth->phdr.pkt_encap != WTAP_ENCAP_PER_PACKET);
1289 #endif
1290
1291     return TRUE; /* success */
1292 }
1293
1294 static gboolean
1295 process_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
1296 {
1297   guint32      framenum;
1298   int          err;
1299   gchar       *err_info = NULL;
1300   gint64       data_offset = 0;
1301   gboolean     filtering_tap_listeners;
1302   guint        tap_flags;
1303   Buffer       buf;
1304   epan_dissect_t *edt = NULL;
1305   struct wtap_pkthdr file_phdr;
1306   guint8* raw_data;
1307
1308   if (print_packet_info) {
1309     if (!write_preamble(cf)) {
1310       err = errno;
1311       show_print_file_io_error(err);
1312       goto out;
1313     }
1314   }
1315
1316   /* Do we have any tap listeners with filters? */
1317   filtering_tap_listeners = have_filtering_tap_listeners();
1318
1319   /* Get the union of the flags for all tap listeners. */
1320   tap_flags = union_of_tap_listener_flags();
1321
1322   wtap_phdr_init(&file_phdr);
1323
1324   /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1325   file_phdr.pkt_encap = 1234;
1326
1327   if (perform_two_pass_analysis) {
1328     frame_data *fdata;
1329
1330     /* Allocate a frame_data_sequence for all the frames. */
1331     cf->frames = new_frame_data_sequence();
1332
1333     if (do_dissection) {
1334       gboolean create_proto_tree;
1335
1336       /*
1337        * Determine whether we need to create a protocol tree.
1338        * We do if:
1339        *
1340        *    we're going to apply a read filter;
1341        *
1342        *    a postdissector wants field values or protocols
1343        *    on the first pass.
1344        */
1345       create_proto_tree =
1346         (cf->rfcode != NULL || postdissectors_want_hfids());
1347
1348       /* We're not going to display the protocol tree on this pass,
1349          so it's not going to be "visible". */
1350       edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
1351     }
1352     while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1353       if (process_packet_first_pass(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1354                                     wtap_buf_ptr(cf->wth))) {
1355
1356         /* Stop reading if we have the maximum number of packets;
1357          * When the -c option has not been used, max_packet_count
1358          * starts at 0, which practically means, never stop reading.
1359          * (unless we roll over max_packet_count ?)
1360          */
1361         if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1362           err = 0; /* This is not an error */
1363           break;
1364         }
1365       }
1366     }
1367
1368     if (edt) {
1369       epan_dissect_free(edt);
1370       edt = NULL;
1371     }
1372
1373 #if 0
1374     /* Close the sequential I/O side, to free up memory it requires. */
1375     wtap_sequential_close(cf->wth);
1376 #endif
1377
1378     /* Allow the protocol dissectors to free up memory that they
1379      * don't need after the sequential run-through of the packets. */
1380     postseq_cleanup_all_protocols();
1381
1382     prev_dis = NULL;
1383     prev_cap = NULL;
1384     ws_buffer_init(&buf, 1500);
1385
1386     if (do_dissection) {
1387       gboolean create_proto_tree;
1388
1389       /*
1390        * Determine whether we need to create a protocol tree.
1391        * We do if:
1392        *
1393        *    we're going to apply a display filter;
1394        *
1395        *    we're going to print the protocol tree;
1396        *
1397        *    one of the tap listeners requires a protocol tree;
1398        *
1399        *    we have custom columns (which require field values, which
1400        *    currently requires that we build a protocol tree).
1401        */
1402       create_proto_tree =
1403         (cf->dfcode || print_details || filtering_tap_listeners ||
1404          (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo));
1405
1406       /* The protocol tree will be "visible", i.e., printed, only if we're
1407          printing packet details, which is true if we're printing stuff
1408          ("print_packet_info" is true) and we're in verbose mode
1409          ("packet_details" is true). */
1410       edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1411     }
1412
1413     for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
1414       fdata = frame_data_sequence_find(cf->frames, framenum);
1415 #if 0
1416       if (wtap_seek_read(cf->wth, fdata->file_off,
1417           &buf, fdata->cap_len, &err, &err_info)) {
1418         process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1419       }
1420 #else
1421       if (!process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf,
1422                                        tap_flags))
1423         return FALSE;
1424 #endif
1425     }
1426
1427     if (edt) {
1428       epan_dissect_free(edt);
1429       edt = NULL;
1430     }
1431
1432     ws_buffer_free(&buf);
1433   }
1434   else {
1435     framenum = 0;
1436
1437     if (do_dissection) {
1438       gboolean create_proto_tree;
1439
1440       /*
1441        * Determine whether we need to create a protocol tree.
1442        * We do if:
1443        *
1444        *    we're going to apply a read filter;
1445        *
1446        *    we're going to apply a display filter;
1447        *
1448        *    we're going to print the protocol tree;
1449        *
1450        *    one of the tap listeners is going to apply a filter;
1451        *
1452        *    one of the tap listeners requires a protocol tree;
1453        *
1454        *    a postdissector wants field values or protocols
1455        *    on the first pass;
1456        *
1457        *    we have custom columns (which require field values, which
1458        *    currently requires that we build a protocol tree).
1459        */
1460       create_proto_tree =
1461         (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
1462           (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
1463           have_custom_cols(&cf->cinfo));
1464
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);
1470     }
1471
1472     while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1473
1474       framenum++;
1475
1476       if (!process_packet_single_pass(cf, edt, data_offset,
1477                                       &file_phdr/*wtap_phdr(cf->wth)*/,
1478                                       raw_data, tap_flags))
1479         return FALSE;
1480
1481       /* Stop reading if we have the maximum number of packets;
1482       * When the -c option has not been used, max_packet_count
1483       * starts at 0, which practically means, never stop reading.
1484       * (unless we roll over max_packet_count ?)
1485       */
1486       if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1487         err = 0; /* This is not an error */
1488         break;
1489       }
1490     }
1491
1492     if (edt) {
1493       epan_dissect_free(edt);
1494       edt = NULL;
1495     }
1496   }
1497
1498   wtap_phdr_cleanup(&file_phdr);
1499
1500   if (err != 0) {
1501     /*
1502      * Print a message noting that the read failed somewhere along the line.
1503      *
1504      * If we're printing packet data, and the standard output and error are
1505      * going to the same place, flush the standard output, so everything
1506      * buffered up is written, and then print a newline to the standard error
1507      * before printing the error message, to separate it from the packet
1508      * data.  (Alas, that only works on UN*X; st_dev is meaningless, and
1509      * the _fstat() documentation at Microsoft doesn't indicate whether
1510      * st_ino is even supported.)
1511      */
1512 #ifndef _WIN32
1513     if (print_packet_info) {
1514       ws_statb64 stat_stdout, stat_stderr;
1515
1516       if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
1517         if (stat_stdout.st_dev == stat_stderr.st_dev &&
1518             stat_stdout.st_ino == stat_stderr.st_ino) {
1519           fflush(stdout);
1520           fprintf(stderr, "\n");
1521         }
1522       }
1523     }
1524 #endif
1525 #if 0
1526     switch (err) {
1527
1528     case FTAP_ERR_UNSUPPORTED:
1529       cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
1530                  cf->filename, err_info);
1531       g_free(err_info);
1532       break;
1533
1534     case FTAP_ERR_UNSUPPORTED_ENCAP:
1535       cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
1536                  cf->filename, err_info);
1537       g_free(err_info);
1538       break;
1539
1540     case FTAP_ERR_CANT_READ:
1541       cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
1542                  cf->filename);
1543       break;
1544
1545     case FTAP_ERR_SHORT_READ:
1546       cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
1547                  cf->filename);
1548       break;
1549
1550     case FTAP_ERR_BAD_FILE:
1551       cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
1552                  cf->filename, err_info);
1553       g_free(err_info);
1554       break;
1555
1556     case FTAP_ERR_DECOMPRESS:
1557       cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
1558                  "(%s)", cf->filename, err_info);
1559       break;
1560
1561     default:
1562       cmdarg_err("An error occurred while reading the file \"%s\": %s.",
1563                  cf->filename, ftap_strerror(err));
1564       break;
1565     }
1566 #endif
1567   } else {
1568     if (print_packet_info) {
1569       if (!write_finale()) {
1570         err = errno;
1571         show_print_file_io_error(err);
1572       }
1573     }
1574   }
1575
1576 out:
1577   wtap_close(cf->wth);
1578   cf->wth = NULL;
1579
1580   return (err != 0);
1581 }
1582
1583 static gboolean
1584 process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset,
1585                            struct wtap_pkthdr *whdr, const guchar *pd,
1586                            guint tap_flags)
1587 {
1588   frame_data      fdata;
1589   column_info    *cinfo;
1590   gboolean        passed;
1591
1592   /* Count this packet. */
1593   cf->count++;
1594
1595   /* If we're not running a display filter and we're not printing any
1596      packet information, we don't need to do a dissection. This means
1597      that all packets can be marked as 'passed'. */
1598   passed = TRUE;
1599
1600   frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
1601
1602   /* If we're going to print packet information, or we're going to
1603      run a read filter, or we're going to process taps, set up to
1604      do a dissection and do so. */
1605   if (edt) {
1606     /* If we're running a filter, prime the epan_dissect_t with that
1607        filter. */
1608     if (cf->dfcode)
1609       epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1610
1611     col_custom_prime_edt(edt, &cf->cinfo);
1612
1613     /* We only need the columns if either
1614          1) some tap needs the columns
1615        or
1616          2) we're printing packet info but we're *not* verbose; in verbose
1617             mode, we print the protocol tree, not the protocol summary.
1618        or
1619          3) there is a column mapped as an individual field */
1620     if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
1621       cinfo = &cf->cinfo;
1622     else
1623       cinfo = NULL;
1624
1625     frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
1626                                   &ref, prev_dis);
1627     if (ref == &fdata) {
1628       ref_frame = fdata;
1629       ref = &ref_frame;
1630     }
1631
1632     epan_dissect_file_run_with_taps(edt, whdr, frame_tvbuff_new(&fdata, pd), &fdata, cinfo);
1633
1634     /* Run the filter if we have it. */
1635     if (cf->dfcode)
1636       passed = dfilter_apply_edt(cf->dfcode, edt);
1637   }
1638
1639   if (passed) {
1640     frame_data_set_after_dissect(&fdata, &cum_bytes);
1641
1642     /* Process this packet. */
1643     if (print_packet_info) {
1644       /* We're printing packet information; print the information for
1645          this packet. */
1646       print_packet(cf, edt);
1647
1648       /* If we're doing "line-buffering", flush the standard output
1649          after every packet.  See the comment above, for the "-l"
1650          option, for an explanation of why we do that. */
1651       if (line_buffered)
1652         fflush(stdout);
1653
1654       if (ferror(stdout)) {
1655         show_print_file_io_error(errno);
1656         return FALSE;
1657       }
1658     }
1659
1660     /* this must be set after print_packet() [bug #8160] */
1661     prev_dis_frame = fdata;
1662     prev_dis = &prev_dis_frame;
1663   }
1664
1665   prev_cap_frame = fdata;
1666   prev_cap = &prev_cap_frame;
1667
1668   if (edt) {
1669     epan_dissect_reset(edt);
1670     frame_data_destroy(&fdata);
1671   }
1672   return passed;
1673 }
1674
1675 static gboolean
1676 write_preamble(capture_file *cf)
1677 {
1678   switch (output_action) {
1679
1680   case WRITE_TEXT:
1681     return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
1682
1683   case WRITE_XML:
1684     if (print_details)
1685       write_pdml_preamble(stdout, cf->filename);
1686     else
1687       write_psml_preamble(&cf->cinfo, stdout);
1688     return !ferror(stdout);
1689
1690   case WRITE_FIELDS:
1691     write_fields_preamble(output_fields, stdout);
1692     return !ferror(stdout);
1693
1694   default:
1695     g_assert_not_reached();
1696     return FALSE;
1697   }
1698 }
1699
1700 static char *
1701 get_line_buf(size_t len)
1702 {
1703   static char   *line_bufp    = NULL;
1704   static size_t  line_buf_len = 256;
1705   size_t         new_line_buf_len;
1706
1707   for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
1708        new_line_buf_len *= 2)
1709     ;
1710   if (line_bufp == NULL) {
1711     line_buf_len = new_line_buf_len;
1712     line_bufp = (char *)g_malloc(line_buf_len + 1);
1713   } else {
1714     if (new_line_buf_len > line_buf_len) {
1715       line_buf_len = new_line_buf_len;
1716       line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
1717     }
1718   }
1719   return line_bufp;
1720 }
1721
1722 static inline void
1723 put_string(char *dest, const char *str, size_t str_len)
1724 {
1725   memcpy(dest, str, str_len);
1726   dest[str_len] = '\0';
1727 }
1728
1729 static inline void
1730 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1731 {
1732   size_t i;
1733
1734   for (i = str_len; i < str_with_spaces; i++)
1735     *dest++ = ' ';
1736
1737   put_string(dest, str, str_len);
1738 }
1739
1740 static inline void
1741 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1742 {
1743   size_t i;
1744
1745   memcpy(dest, str, str_len);
1746   for (i = str_len; i < str_with_spaces; i++)
1747     dest[i] = ' ';
1748
1749   dest[str_with_spaces] = '\0';
1750 }
1751
1752 static gboolean
1753 print_columns(capture_file *cf)
1754 {
1755   char   *line_bufp;
1756   int     i;
1757   size_t  buf_offset;
1758   size_t  column_len;
1759   size_t  col_len;
1760   col_item_t* col_item;
1761
1762   line_bufp = get_line_buf(256);
1763   buf_offset = 0;
1764   *line_bufp = '\0';
1765   for (i = 0; i < cf->cinfo.num_cols; i++) {
1766     col_item = &cf->cinfo.columns[i];
1767     /* Skip columns not marked as visible. */
1768     if (!get_column_visible(i))
1769       continue;
1770     switch (col_item->col_fmt) {
1771     case COL_NUMBER:
1772       column_len = col_len = strlen(col_item->col_data);
1773       if (column_len < 3)
1774         column_len = 3;
1775       line_bufp = get_line_buf(buf_offset + column_len);
1776       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1777       break;
1778
1779     case COL_CLS_TIME:
1780     case COL_REL_TIME:
1781     case COL_ABS_TIME:
1782     case COL_ABS_YMD_TIME:  /* XXX - wider */
1783     case COL_ABS_YDOY_TIME: /* XXX - wider */
1784     case COL_UTC_TIME:
1785     case COL_UTC_YMD_TIME:  /* XXX - wider */
1786     case COL_UTC_YDOY_TIME: /* XXX - wider */
1787       column_len = col_len = strlen(col_item->col_data);
1788       if (column_len < 10)
1789         column_len = 10;
1790       line_bufp = get_line_buf(buf_offset + column_len);
1791       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1792       break;
1793
1794     case COL_DEF_SRC:
1795     case COL_RES_SRC:
1796     case COL_UNRES_SRC:
1797     case COL_DEF_DL_SRC:
1798     case COL_RES_DL_SRC:
1799     case COL_UNRES_DL_SRC:
1800     case COL_DEF_NET_SRC:
1801     case COL_RES_NET_SRC:
1802     case COL_UNRES_NET_SRC:
1803       column_len = col_len = strlen(col_item->col_data);
1804       if (column_len < 12)
1805         column_len = 12;
1806       line_bufp = get_line_buf(buf_offset + column_len);
1807       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1808       break;
1809
1810     case COL_DEF_DST:
1811     case COL_RES_DST:
1812     case COL_UNRES_DST:
1813     case COL_DEF_DL_DST:
1814     case COL_RES_DL_DST:
1815     case COL_UNRES_DL_DST:
1816     case COL_DEF_NET_DST:
1817     case COL_RES_NET_DST:
1818     case COL_UNRES_NET_DST:
1819       column_len = col_len = strlen(col_item->col_data);
1820       if (column_len < 12)
1821         column_len = 12;
1822       line_bufp = get_line_buf(buf_offset + column_len);
1823       put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1824       break;
1825
1826     default:
1827       column_len = strlen(col_item->col_data);
1828       line_bufp = get_line_buf(buf_offset + column_len);
1829       put_string(line_bufp + buf_offset, col_item->col_data, column_len);
1830       break;
1831     }
1832     buf_offset += column_len;
1833     if (i != cf->cinfo.num_cols - 1) {
1834       /*
1835        * This isn't the last column, so we need to print a
1836        * separator between this column and the next.
1837        *
1838        * If we printed a network source and are printing a
1839        * network destination of the same type next, separate
1840        * them with " -> "; if we printed a network destination
1841        * and are printing a network source of the same type
1842        * next, separate them with " <- "; otherwise separate them
1843        * with a space.
1844        *
1845        * We add enough space to the buffer for " <- " or " -> ",
1846        * even if we're only adding " ".
1847        */
1848       line_bufp = get_line_buf(buf_offset + 4);
1849       switch (col_item->col_fmt) {
1850
1851       case COL_DEF_SRC:
1852       case COL_RES_SRC:
1853       case COL_UNRES_SRC:
1854         switch (cf->cinfo.columns[i+1].col_fmt) {
1855
1856         case COL_DEF_DST:
1857         case COL_RES_DST:
1858         case COL_UNRES_DST:
1859           put_string(line_bufp + buf_offset, " -> ", 4);
1860           buf_offset += 4;
1861           break;
1862
1863         default:
1864           put_string(line_bufp + buf_offset, " ", 1);
1865           buf_offset += 1;
1866           break;
1867         }
1868         break;
1869
1870       case COL_DEF_DL_SRC:
1871       case COL_RES_DL_SRC:
1872       case COL_UNRES_DL_SRC:
1873         switch (cf->cinfo.columns[i+1].col_fmt) {
1874
1875         case COL_DEF_DL_DST:
1876         case COL_RES_DL_DST:
1877         case COL_UNRES_DL_DST:
1878           put_string(line_bufp + buf_offset, " -> ", 4);
1879           buf_offset += 4;
1880           break;
1881
1882         default:
1883           put_string(line_bufp + buf_offset, " ", 1);
1884           buf_offset += 1;
1885           break;
1886         }
1887         break;
1888
1889       case COL_DEF_NET_SRC:
1890       case COL_RES_NET_SRC:
1891       case COL_UNRES_NET_SRC:
1892         switch (cf->cinfo.columns[i+1].col_fmt) {
1893
1894         case COL_DEF_NET_DST:
1895         case COL_RES_NET_DST:
1896         case COL_UNRES_NET_DST:
1897           put_string(line_bufp + buf_offset, " -> ", 4);
1898           buf_offset += 4;
1899           break;
1900
1901         default:
1902           put_string(line_bufp + buf_offset, " ", 1);
1903           buf_offset += 1;
1904           break;
1905         }
1906         break;
1907
1908       case COL_DEF_DST:
1909       case COL_RES_DST:
1910       case COL_UNRES_DST:
1911         switch (cf->cinfo.columns[i+1].col_fmt) {
1912
1913         case COL_DEF_SRC:
1914         case COL_RES_SRC:
1915         case COL_UNRES_SRC:
1916           put_string(line_bufp + buf_offset, " <- ", 4);
1917           buf_offset += 4;
1918           break;
1919
1920         default:
1921           put_string(line_bufp + buf_offset, " ", 1);
1922           buf_offset += 1;
1923           break;
1924         }
1925         break;
1926
1927       case COL_DEF_DL_DST:
1928       case COL_RES_DL_DST:
1929       case COL_UNRES_DL_DST:
1930         switch (cf->cinfo.columns[i+1].col_fmt) {
1931
1932         case COL_DEF_DL_SRC:
1933         case COL_RES_DL_SRC:
1934         case COL_UNRES_DL_SRC:
1935           put_string(line_bufp + buf_offset, " <- ", 4);
1936           buf_offset += 4;
1937           break;
1938
1939         default:
1940           put_string(line_bufp + buf_offset, " ", 1);
1941           buf_offset += 1;
1942           break;
1943         }
1944         break;
1945
1946       case COL_DEF_NET_DST:
1947       case COL_RES_NET_DST:
1948       case COL_UNRES_NET_DST:
1949         switch (cf->cinfo.columns[i+1].col_fmt) {
1950
1951         case COL_DEF_NET_SRC:
1952         case COL_RES_NET_SRC:
1953         case COL_UNRES_NET_SRC:
1954           put_string(line_bufp + buf_offset, " <- ", 4);
1955           buf_offset += 4;
1956           break;
1957
1958         default:
1959           put_string(line_bufp + buf_offset, " ", 1);
1960           buf_offset += 1;
1961           break;
1962         }
1963         break;
1964
1965       default:
1966         put_string(line_bufp + buf_offset, " ", 1);
1967         buf_offset += 1;
1968         break;
1969       }
1970     }
1971   }
1972   return print_line(print_stream, 0, line_bufp);
1973 }
1974
1975 static gboolean
1976 print_packet(capture_file *cf, epan_dissect_t *edt)
1977 {
1978   if (print_summary || output_fields_has_cols(output_fields)) {
1979     /* Just fill in the columns. */
1980     epan_dissect_fill_in_columns(edt, FALSE, TRUE);
1981
1982     if (print_summary) {
1983       /* Now print them. */
1984       switch (output_action) {
1985
1986       case WRITE_TEXT:
1987         if (!print_columns(cf))
1988           return FALSE;
1989         break;
1990
1991       case WRITE_XML:
1992         write_psml_columns(edt, stdout, FALSE);
1993         return !ferror(stdout);
1994       case WRITE_FIELDS: /*No non-verbose "fields" format */
1995         g_assert_not_reached();
1996         break;
1997       }
1998     }
1999   }
2000   if (print_details) {
2001     /* Print the information in the protocol tree. */
2002     switch (output_action) {
2003
2004     case WRITE_TEXT:
2005       if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
2006                             print_hex, edt, output_only_tables, print_stream))
2007         return FALSE;
2008       if (!print_hex) {
2009         if (!print_line(print_stream, 0, separator))
2010           return FALSE;
2011       }
2012       break;
2013
2014     case WRITE_XML:
2015       write_pdml_proto_tree(NULL, NULL, PF_NONE, edt, stdout, FALSE);
2016       printf("\n");
2017       return !ferror(stdout);
2018     case WRITE_FIELDS:
2019       write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
2020       printf("\n");
2021       return !ferror(stdout);
2022     }
2023   }
2024   if (print_hex) {
2025     if (print_summary || print_details) {
2026       if (!print_line(print_stream, 0, ""))
2027         return FALSE;
2028     }
2029     if (!print_hex_data(print_stream, edt))
2030       return FALSE;
2031     if (!print_line(print_stream, 0, separator))
2032       return FALSE;
2033   }
2034   return TRUE;
2035 }
2036
2037 static gboolean
2038 write_finale(void)
2039 {
2040   switch (output_action) {
2041
2042   case WRITE_TEXT:
2043     return print_finale(print_stream);
2044
2045   case WRITE_XML:
2046     if (print_details)
2047       write_pdml_finale(stdout);
2048     else
2049       write_psml_finale(stdout);
2050     return !ferror(stdout);
2051
2052   case WRITE_FIELDS:
2053     write_fields_finale(output_fields, stdout);
2054     return !ferror(stdout);
2055
2056   default:
2057     g_assert_not_reached();
2058     return FALSE;
2059   }
2060 }
2061
2062 cf_status_t
2063 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
2064 {
2065   gchar *err_info;
2066   char   err_msg[2048+1];
2067
2068   /* The open isn't implemented yet.  Fill in the information for this file. */
2069
2070   /* Create new epan session for dissection. */
2071   epan_free(cf->epan);
2072   cf->epan = tfshark_epan_new(cf);
2073
2074   cf->wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2075   cf->f_datalen = 0; /* not used, but set it anyway */
2076
2077   /* Set the file name because we need it to set the follow stream filter.
2078      XXX - is that still true?  We need it for other reasons, though,
2079      in any case. */
2080   cf->filename = g_strdup(fname);
2081
2082   /* Indicate whether it's a permanent or temporary file. */
2083   cf->is_tempfile = is_tempfile;
2084
2085   /* No user changes yet. */
2086   cf->unsaved_changes = FALSE;
2087
2088   cf->cd_t      = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2089   cf->open_type = type;
2090   cf->count     = 0;
2091   cf->drops_known = FALSE;
2092   cf->drops     = 0;
2093   cf->snap      = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2094   nstime_set_zero(&cf->elapsed_time);
2095   ref = NULL;
2096   prev_dis = NULL;
2097   prev_cap = NULL;
2098
2099   cf->state = FILE_READ_IN_PROGRESS;
2100
2101   return CF_OK;
2102
2103 /* fail: */
2104   g_snprintf(err_msg, sizeof err_msg,
2105              cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
2106   cmdarg_err("%s", err_msg);
2107   return CF_ERROR;
2108 }
2109
2110 static void
2111 show_print_file_io_error(int err)
2112 {
2113   switch (err) {
2114
2115   case ENOSPC:
2116     cmdarg_err("Not all the packets could be printed because there is "
2117 "no space left on the file system.");
2118     break;
2119
2120 #ifdef EDQUOT
2121   case EDQUOT:
2122     cmdarg_err("Not all the packets could be printed because you are "
2123 "too close to, or over your disk quota.");
2124   break;
2125 #endif
2126
2127   default:
2128     cmdarg_err("An error occurred while printing packets: %s.",
2129       g_strerror(err));
2130     break;
2131   }
2132 }
2133
2134 static const char *
2135 cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
2136                       int file_type _U_)
2137 {
2138   const char *errmsg;
2139   /* static char errmsg_errno[1024+1]; */
2140
2141 #if 0
2142   if (err < 0) {
2143     /* Wiretap error. */
2144     switch (err) {
2145
2146     case FTAP_ERR_NOT_REGULAR_FILE:
2147       errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
2148       break;
2149
2150     case FTAP_ERR_RANDOM_OPEN_PIPE:
2151       /* Seen only when opening a capture file for reading. */
2152       errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
2153       break;
2154
2155     case FTAP_ERR_FILE_UNKNOWN_FORMAT:
2156       /* Seen only when opening a capture file for reading. */
2157       errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
2158       break;
2159
2160     case FTAP_ERR_UNSUPPORTED:
2161       /* Seen only when opening a capture file for reading. */
2162       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2163                "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
2164                "(%s)", err_info);
2165       g_free(err_info);
2166       errmsg = errmsg_errno;
2167       break;
2168
2169     case FTAP_ERR_CANT_WRITE_TO_PIPE:
2170       /* Seen only when opening a capture file for writing. */
2171       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2172                  "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
2173                  "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
2174       errmsg = errmsg_errno;
2175       break;
2176
2177     case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
2178       /* Seen only when opening a capture file for writing. */
2179       errmsg = "TFShark doesn't support writing capture files in that format.";
2180       break;
2181
2182     case FTAP_ERR_UNSUPPORTED_ENCAP:
2183       if (for_writing) {
2184         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2185                    "TFShark can't save this capture as a \"%s\" file.",
2186                    ftap_file_type_subtype_short_string(file_type));
2187       } else {
2188         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2189                  "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
2190                  "(%s)", err_info);
2191         g_free(err_info);
2192       }
2193       errmsg = errmsg_errno;
2194       break;
2195
2196     case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
2197       if (for_writing) {
2198         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2199                    "TFShark can't save this capture as a \"%s\" file.",
2200                    ftap_file_type_subtype_short_string(file_type));
2201         errmsg = errmsg_errno;
2202       } else
2203         errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
2204       break;
2205
2206     case FTAP_ERR_BAD_FILE:
2207       /* Seen only when opening a capture file for reading. */
2208       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2209                "The file \"%%s\" appears to be damaged or corrupt.\n"
2210                "(%s)", err_info);
2211       g_free(err_info);
2212       errmsg = errmsg_errno;
2213       break;
2214
2215     case FTAP_ERR_CANT_OPEN:
2216       if (for_writing)
2217         errmsg = "The file \"%s\" could not be created for some unknown reason.";
2218       else
2219         errmsg = "The file \"%s\" could not be opened for some unknown reason.";
2220       break;
2221
2222     case FTAP_ERR_SHORT_READ:
2223       errmsg = "The file \"%s\" appears to have been cut short"
2224                " in the middle of a packet or other data.";
2225       break;
2226
2227     case FTAP_ERR_SHORT_WRITE:
2228       errmsg = "A full header couldn't be written to the file \"%s\".";
2229       break;
2230
2231     case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
2232       errmsg = "This file type cannot be written as a compressed file.";
2233       break;
2234
2235     case FTAP_ERR_DECOMPRESS:
2236       /* Seen only when opening a capture file for reading. */
2237       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2238                  "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
2239                  "(%s)", err_info);
2240       g_free(err_info);
2241       errmsg = errmsg_errno;
2242       break;
2243
2244     default:
2245       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2246                  "The file \"%%s\" could not be %s: %s.",
2247                  for_writing ? "created" : "opened",
2248                  ftap_strerror(err));
2249       errmsg = errmsg_errno;
2250       break;
2251     }
2252   } else
2253 #endif
2254     errmsg = file_open_error_message(err, for_writing);
2255   return errmsg;
2256 }
2257
2258 /*
2259  * General errors and warnings are reported with an console message
2260  * in TFShark.
2261  */
2262 static void
2263 failure_warning_message(const char *msg_format, va_list ap)
2264 {
2265   fprintf(stderr, "tfshark: ");
2266   vfprintf(stderr, msg_format, ap);
2267   fprintf(stderr, "\n");
2268 }
2269
2270 /*
2271  * Open/create errors are reported with an console message in TFShark.
2272  */
2273 static void
2274 open_failure_message(const char *filename, int err, gboolean for_writing)
2275 {
2276   fprintf(stderr, "tfshark: ");
2277   fprintf(stderr, file_open_error_message(err, for_writing), filename);
2278   fprintf(stderr, "\n");
2279 }
2280
2281 /*
2282  * Read errors are reported with an console message in TFShark.
2283  */
2284 static void
2285 read_failure_message(const char *filename, int err)
2286 {
2287   cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
2288           filename, g_strerror(err));
2289 }
2290
2291 /*
2292  * Write errors are reported with an console message in TFShark.
2293  */
2294 static void
2295 write_failure_message(const char *filename, int err)
2296 {
2297   cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
2298           filename, g_strerror(err));
2299 }
2300
2301 /*
2302  * Report additional information for an error in command-line arguments.
2303  */
2304 static void
2305 failure_message_cont(const char *msg_format, va_list ap)
2306 {
2307   vfprintf(stderr, msg_format, ap);
2308   fprintf(stderr, "\n");
2309 }
2310
2311 /*
2312  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2313  *
2314  * Local variables:
2315  * c-basic-offset: 2
2316  * tab-width: 8
2317  * indent-tabs-mode: nil
2318  * End:
2319  *
2320  * vi: set shiftwidth=2 tabstop=8 expandtab:
2321  * :indentSize=2:tabSize=8:noTabs=true:
2322  */