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