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