Merge with the FreeRADIUS version.
[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     {
693       char *errmsg = NULL;
694
695       switch (prefs_set_pref(optarg, &errmsg)) {
696
697       case PREFS_SET_OK:
698         break;
699
700       case PREFS_SET_SYNTAX_ERR:
701         cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg,
702             errmsg ? ": " : "", errmsg ? errmsg : "");
703         g_free(errmsg);
704         return 1;
705         break;
706
707       case PREFS_SET_NO_SUCH_PREF:
708       case PREFS_SET_OBSOLETE:
709         cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
710         exit_status = INVALID_OPTION;
711         goto clean_exit;
712         break;
713       }
714       break;
715     }
716     case 'q':        /* Quiet */
717       quiet = TRUE;
718       break;
719     case 'Q':        /* Really quiet */
720       quiet = TRUE;
721       really_quiet = TRUE;
722       break;
723     case 'r':        /* Read capture file x */
724       cf_name = g_strdup(optarg);
725       break;
726     case 'R':        /* Read file filter */
727       rfilter = optarg;
728       break;
729     case 'S':        /* Set the line Separator to be printed between packets */
730       separator = g_strdup(optarg);
731       break;
732     case 'T':        /* printing Type */
733       if (strcmp(optarg, "text") == 0) {
734         output_action = WRITE_TEXT;
735         print_format = PR_FMT_TEXT;
736       } else if (strcmp(optarg, "ps") == 0) {
737         output_action = WRITE_TEXT;
738         print_format = PR_FMT_PS;
739       } else if (strcmp(optarg, "pdml") == 0) {
740         output_action = WRITE_XML;
741         print_details = TRUE;   /* Need details */
742         print_summary = FALSE;  /* Don't allow summary */
743       } else if (strcmp(optarg, "psml") == 0) {
744         output_action = WRITE_XML;
745         print_details = FALSE;  /* Don't allow details */
746         print_summary = TRUE;   /* Need summary */
747       } else if (strcmp(optarg, "fields") == 0) {
748         output_action = WRITE_FIELDS;
749         print_details = TRUE;   /* Need full tree info */
750         print_summary = FALSE;  /* Don't allow summary */
751       } else {
752         cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg);                   /* x */
753         cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
754                         "\t         specified by the -E option.\n"
755                         "\t\"pdml\"   Packet Details Markup Language, an XML-based format for the\n"
756                         "\t         details of a decoded packet. This information is equivalent to\n"
757                         "\t         the packet details printed with the -V flag.\n"
758                         "\t\"ps\"     PostScript for a human-readable one-line summary of each of\n"
759                         "\t         the packets, or a multi-line view of the details of each of\n"
760                         "\t         the packets, depending on whether the -V flag was specified.\n"
761                         "\t\"psml\"   Packet Summary Markup Language, an XML-based format for the\n"
762                         "\t         summary information of a decoded packet. This information is\n"
763                         "\t         equivalent to the information shown in the one-line summary\n"
764                         "\t         printed by default.\n"
765                         "\t\"text\"   Text of a human-readable one-line summary of each of the\n"
766                         "\t         packets, or a multi-line view of the details of each of the\n"
767                         "\t         packets, depending on whether the -V flag was specified.\n"
768                         "\t         This is the default.");
769         exit_status = INVALID_OPTION;
770         goto clean_exit;
771       }
772       break;
773     case 'v':         /* Show version and exit */
774       comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
775       runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
776       show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
777       g_string_free(comp_info_str, TRUE);
778       g_string_free(runtime_info_str, TRUE);
779       goto clean_exit;
780     case 'O':        /* Only output these protocols */
781       /* already processed; just ignore it now */
782       break;
783     case 'V':        /* Verbose */
784       /* already processed; just ignore it now */
785       break;
786     case 'x':        /* Print packet data in hex (and ASCII) */
787       /* already processed; just ignore it now */
788       break;
789     case 'X':
790       /* already processed; just ignore it now */
791       break;
792     case 'Y':
793       dfilter = optarg;
794       break;
795     case 'z':
796       /* We won't call the init function for the stat this soon
797          as it would disallow MATE's fields (which are registered
798          by the preferences set callback) from being used as
799          part of a tap filter.  Instead, we just add the argument
800          to a list of stat arguments. */
801       if (strcmp("help", optarg) == 0) {
802         fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
803         list_stat_cmd_args();
804         goto clean_exit;
805       }
806       if (!process_stat_cmd_arg(optarg)) {
807         cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
808         list_stat_cmd_args();
809         exit_status = INVALID_OPTION;
810         goto clean_exit;
811       }
812       break;
813     case 'd':        /* Decode as rule */
814     case 'K':        /* Kerberos keytab file */
815     case 't':        /* Time stamp type */
816     case 'u':        /* Seconds type */
817     case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
818     case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
819     case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
820     case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
821       if (!dissect_opts_handle_opt(opt, optarg)) {
822         exit_status = INVALID_OPTION;
823         goto clean_exit;
824       }
825       break;
826     default:
827     case '?':        /* Bad flag - print usage message */
828       print_usage(stderr);
829       exit_status = INVALID_OPTION;
830       goto clean_exit;
831       break;
832     }
833   }
834
835   /* If we specified output fields, but not the output field type... */
836   if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
837         cmdarg_err("Output fields were specified with \"-e\", "
838             "but \"-Tfields\" was not specified.");
839         return 1;
840   } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
841         cmdarg_err("\"-Tfields\" was specified, but no fields were "
842                     "specified with \"-e\".");
843
844         exit_status = INVALID_OPTION;
845         goto clean_exit;
846   }
847
848   /* If no capture filter or display filter has been specified, and there are
849      still command-line arguments, treat them as the tokens of a capture
850      filter (if no "-r" flag was specified) or a display filter (if a "-r"
851      flag was specified. */
852   if (optind < argc) {
853     if (cf_name != NULL) {
854       if (dfilter != NULL) {
855         cmdarg_err("Display filters were specified both with \"-d\" "
856             "and with additional command-line arguments.");
857         exit_status = INVALID_OPTION;
858         goto clean_exit;
859       }
860       dfilter = get_args_as_string(argc, argv, optind);
861     }
862   }
863
864   /* if "-q" wasn't specified, we should print packet information */
865   if (!quiet)
866     print_packet_info = TRUE;
867
868   if (arg_error) {
869     print_usage(stderr);
870     exit_status = INVALID_OPTION;
871     goto clean_exit;
872   }
873
874   if (print_hex) {
875     if (output_action != WRITE_TEXT) {
876       cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
877       exit_status = INVALID_OPTION;
878       goto clean_exit;
879     }
880   }
881
882   if (output_only != NULL) {
883     char *ps;
884
885     if (!print_details) {
886       cmdarg_err("-O requires -V");
887       exit_status = INVALID_OPTION;
888       goto clean_exit;
889     }
890
891     output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
892     for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
893       g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
894     }
895   }
896
897   if (rfilter != NULL && !perform_two_pass_analysis) {
898     cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
899     exit_status = INVALID_OPTION;
900     goto clean_exit;
901   }
902
903   /* Notify all registered modules that have had any of their preferences
904      changed either from one of the preferences file or from the command
905      line that their preferences have changed. */
906   prefs_apply_all();
907
908   /* At this point MATE will have registered its field array so we can
909      have a tap filter with one of MATE's late-registered fields as part
910      of the filter.  We can now process all the "-z" arguments. */
911   start_requested_stats();
912   
913   /*
914    * Enabled and disabled protocols and heuristic dissectors as per
915    * command-line options.
916    */
917   if (!setup_enabled_and_disabled_protocols()) {
918     exit_status = INVALID_OPTION;
919     goto clean_exit;
920   }
921
922   /* Build the column format array */
923   build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
924
925   if (rfilter != NULL) {
926     if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
927       cmdarg_err("%s", err_msg);
928       g_free(err_msg);
929       exit_status = INVALID_FILTER;
930       goto clean_exit;
931     }
932   }
933   cfile.rfcode = rfcode;
934
935   if (dfilter != NULL) {
936     if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
937       cmdarg_err("%s", err_msg);
938       g_free(err_msg);
939       exit_status = INVALID_FILTER;
940       goto clean_exit;
941     }
942   }
943   cfile.dfcode = dfcode;
944
945   if (print_packet_info) {
946     /* If we're printing as text or PostScript, we have
947        to create a print stream. */
948     if (output_action == WRITE_TEXT) {
949       switch (print_format) {
950
951       case PR_FMT_TEXT:
952         print_stream = print_stream_text_stdio_new(stdout);
953         break;
954
955       case PR_FMT_PS:
956         print_stream = print_stream_ps_stdio_new(stdout);
957         break;
958
959       default:
960         g_assert_not_reached();
961       }
962     }
963   }
964
965   /* We have to dissect each packet if:
966
967         we're printing information about each packet;
968
969         we're using a read filter on the packets;
970
971         we're using a display filter on the packets;
972
973         we're using any taps that need dissection. */
974   do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
975
976   if (cf_name) {
977     /*
978      * We're reading a capture file.
979      */
980
981     /* TODO: if tfshark is ever changed to give the user a choice of which
982        open_routine reader to use, then the following needs to change. */
983     if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
984       exit_status = OPEN_ERROR;
985       goto clean_exit;
986     }
987
988     /* Process the packets in the file */
989     TRY {
990       /* XXX - for now there is only 1 packet */
991       success = process_file(&cfile, 1, 0);
992     }
993     CATCH(OutOfMemoryError) {
994       fprintf(stderr,
995               "Out Of Memory.\n"
996               "\n"
997               "Sorry, but TFShark has to terminate now.\n"
998               "\n"
999               "Some infos / workarounds can be found at:\n"
1000               "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
1001       success = FALSE;
1002     }
1003     ENDTRY;
1004
1005     if (!success) {
1006       /* We still dump out the results of taps, etc., as we might have
1007          read some packets; however, we exit with an error status. */
1008       exit_status = 2;
1009     }
1010   }
1011
1012   g_free(cf_name);
1013
1014   if (cfile.frames != NULL) {
1015     free_frame_data_sequence(cfile.frames);
1016     cfile.frames = NULL;
1017   }
1018
1019   draw_tap_listeners(TRUE);
1020   funnel_dump_all_text_windows();
1021
1022 clean_exit:
1023   destroy_print_stream(print_stream);
1024   epan_free(cfile.epan);
1025   epan_cleanup();
1026 #ifdef HAVE_EXTCAP
1027   extcap_cleanup();
1028 #endif
1029
1030   output_fields_free(output_fields);
1031   output_fields = NULL;
1032
1033   col_cleanup(&cfile.cinfo);
1034   wtap_cleanup();
1035   return exit_status;
1036 }
1037
1038 static const nstime_t *
1039 tfshark_get_frame_ts(void *data, guint32 frame_num)
1040 {
1041   capture_file *cf = (capture_file *) data;
1042
1043   if (ref && ref->num == frame_num)
1044     return &ref->abs_ts;
1045
1046   if (prev_dis && prev_dis->num == frame_num)
1047     return &prev_dis->abs_ts;
1048
1049   if (prev_cap && prev_cap->num == frame_num)
1050     return &prev_cap->abs_ts;
1051
1052   if (cf->frames) {
1053      frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
1054
1055      return (fd) ? &fd->abs_ts : NULL;
1056   }
1057
1058   return NULL;
1059 }
1060
1061 static const char *
1062 no_interface_name(void *data _U_, guint32 interface_id _U_)
1063 {
1064     return "";
1065 }
1066
1067 static epan_t *
1068 tfshark_epan_new(capture_file *cf)
1069 {
1070   epan_t *epan = epan_new();
1071
1072   epan->data = cf;
1073   epan->get_frame_ts = tfshark_get_frame_ts;
1074   epan->get_interface_name = no_interface_name;
1075   epan->get_user_comment = NULL;
1076
1077   return epan;
1078 }
1079
1080 static gboolean
1081 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
1082                           gint64 offset, struct wtap_pkthdr *whdr,
1083                           const guchar *pd)
1084 {
1085   frame_data     fdlocal;
1086   guint32        framenum;
1087   gboolean       passed;
1088
1089   /* The frame number of this packet is one more than the count of
1090      frames in this packet. */
1091   framenum = cf->count + 1;
1092
1093   /* If we're not running a display filter and we're not printing any
1094      packet information, we don't need to do a dissection. This means
1095      that all packets can be marked as 'passed'. */
1096   passed = TRUE;
1097
1098   frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
1099
1100   /* If we're going to print packet information, or we're going to
1101      run a read filter, or display filter, or we're going to process taps, set up to
1102      do a dissection and do so. */
1103   if (edt) {
1104     /* If we're running a read filter, prime the epan_dissect_t with that
1105        filter. */
1106     if (cf->rfcode)
1107       epan_dissect_prime_with_dfilter(edt, cf->rfcode);
1108
1109     /* This is the first pass, so prime the epan_dissect_t with the
1110        hfids postdissectors want on the first pass. */
1111     prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1112
1113     frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
1114                                   &ref, prev_dis);
1115     if (ref == &fdlocal) {
1116       ref_frame = fdlocal;
1117       ref = &ref_frame;
1118     }
1119
1120     epan_dissect_file_run(edt, whdr, file_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
1121
1122     /* Run the read filter if we have one. */
1123     if (cf->rfcode)
1124       passed = dfilter_apply_edt(cf->rfcode, edt);
1125   }
1126
1127   if (passed) {
1128     frame_data_set_after_dissect(&fdlocal, &cum_bytes);
1129     prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
1130
1131     /* If we're not doing dissection then there won't be any dependent frames.
1132      * More importantly, edt.pi.dependent_frames won't be initialized because
1133      * epan hasn't been initialized.
1134      */
1135     if (edt) {
1136       g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
1137     }
1138
1139     cf->count++;
1140   } else {
1141     /* if we don't add it to the frame_data_sequence, clean it up right now
1142      * to avoid leaks */
1143     frame_data_destroy(&fdlocal);
1144   }
1145
1146   if (edt)
1147     epan_dissect_reset(edt);
1148
1149   return passed;
1150 }
1151
1152 static gboolean
1153 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
1154                            frame_data *fdata, struct wtap_pkthdr *phdr,
1155                            Buffer *buf, guint tap_flags)
1156 {
1157   column_info    *cinfo;
1158   gboolean        passed;
1159
1160   /* If we're not running a display filter and we're not printing any
1161      packet information, we don't need to do a dissection. This means
1162      that all packets can be marked as 'passed'. */
1163   passed = TRUE;
1164
1165   /* If we're going to print packet information, or we're going to
1166      run a read filter, or we're going to process taps, set up to
1167      do a dissection and do so. */
1168   if (edt) {
1169
1170     /* If we're running a display filter, prime the epan_dissect_t with that
1171        filter. */
1172     if (cf->dfcode)
1173       epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1174
1175     /* This is the first and only pass, so prime the epan_dissect_t
1176        with the hfids postdissectors want on the first pass. */
1177     prime_epan_dissect_with_postdissector_wanted_hfids(edt);
1178
1179     col_custom_prime_edt(edt, &cf->cinfo);
1180
1181     /* We only need the columns if either
1182          1) some tap needs the columns
1183        or
1184          2) we're printing packet info but we're *not* verbose; in verbose
1185             mode, we print the protocol tree, not the protocol summary.
1186      */
1187     if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
1188       cinfo = &cf->cinfo;
1189     else
1190       cinfo = NULL;
1191
1192     frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1193                                   &ref, prev_dis);
1194     if (ref == fdata) {
1195       ref_frame = *fdata;
1196       ref = &ref_frame;
1197     }
1198
1199     epan_dissect_file_run_with_taps(edt, phdr, file_tvbuff_new_buffer(fdata, buf), fdata, cinfo);
1200
1201     /* Run the read/display filter if we have one. */
1202     if (cf->dfcode)
1203       passed = dfilter_apply_edt(cf->dfcode, edt);
1204   }
1205
1206   if (passed) {
1207     frame_data_set_after_dissect(fdata, &cum_bytes);
1208     /* Process this packet. */
1209     if (print_packet_info) {
1210       /* We're printing packet information; print the information for
1211          this packet. */
1212       print_packet(cf, edt);
1213
1214       /* If we're doing "line-buffering", flush the standard output
1215          after every packet.  See the comment above, for the "-l"
1216          option, for an explanation of why we do that. */
1217       if (line_buffered)
1218         fflush(stdout);
1219
1220       if (ferror(stdout)) {
1221         show_print_file_io_error(errno);
1222         return FALSE;
1223       }
1224     }
1225     prev_dis = fdata;
1226   }
1227   prev_cap = fdata;
1228
1229   if (edt) {
1230     epan_dissect_reset(edt);
1231   }
1232   return passed || fdata->flags.dependent_of_displayed;
1233 }
1234
1235 static gboolean
1236 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)
1237 {
1238     /* int bytes_read; */
1239     gint64 packet_size = wtap_file_size(cf->wth, err);
1240
1241     *data_buffer = (guint8*)g_malloc((gsize)packet_size);
1242     /* bytes_read =*/ file_read(*data_buffer, (unsigned int)packet_size, cf->wth->fh);
1243
1244 #if 0 /* no more filetap */
1245     if (bytes_read < 0) {
1246         *err = file_error(cf->wth->fh, err_info);
1247         if (*err == 0)
1248             *err = FTAP_ERR_SHORT_READ;
1249         return FALSE;
1250     } else if (bytes_read == 0) {
1251         /* Done with file, no error */
1252         return FALSE;
1253     }
1254
1255
1256     /* XXX - SET FRAME SIZE EQUAL TO TOTAL FILE SIZE */
1257     file_phdr->caplen = (guint32)packet_size;
1258     file_phdr->len = (guint32)packet_size;
1259
1260     /*
1261      * Set the packet encapsulation to the file's encapsulation
1262      * value; if that's not WTAP_ENCAP_PER_PACKET, it's the
1263      * right answer (and means that the read routine for this
1264      * capture file type doesn't have to set it), and if it
1265      * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it
1266      * anyway.
1267      */
1268     wth->phdr.pkt_encap = wth->file_encap;
1269
1270     if (!wth->subtype_read(wth, err, err_info, data_offset)) {
1271         /*
1272          * If we didn't get an error indication, we read
1273          * the last packet.  See if there's any deferred
1274          * error, as might, for example, occur if we're
1275          * reading a compressed file, and we got an error
1276          * reading compressed data from the file, but
1277          * got enough compressed data to decompress the
1278          * last packet of the file.
1279          */
1280         if (*err == 0)
1281             *err = file_error(wth->fh, err_info);
1282         return FALSE;    /* failure */
1283     }
1284
1285     /*
1286      * It makes no sense for the captured data length to be bigger
1287      * than the actual data length.
1288      */
1289     if (wth->phdr.caplen > wth->phdr.len)
1290         wth->phdr.caplen = wth->phdr.len;
1291
1292     /*
1293      * Make sure that it's not WTAP_ENCAP_PER_PACKET, as that
1294      * probably means the file has that encapsulation type
1295      * but the read routine didn't set this packet's
1296      * encapsulation type.
1297      */
1298     g_assert(wth->phdr.pkt_encap != WTAP_ENCAP_PER_PACKET);
1299 #endif
1300
1301     return TRUE; /* success */
1302 }
1303
1304 static gboolean
1305 process_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
1306 {
1307   guint32      framenum;
1308   int          err;
1309   gchar       *err_info = NULL;
1310   gint64       data_offset = 0;
1311   gboolean     filtering_tap_listeners;
1312   guint        tap_flags;
1313   Buffer       buf;
1314   epan_dissect_t *edt = NULL;
1315   struct wtap_pkthdr file_phdr;
1316   guint8* raw_data;
1317
1318   if (print_packet_info) {
1319     if (!write_preamble(cf)) {
1320       err = errno;
1321       show_print_file_io_error(err);
1322       goto out;
1323     }
1324   }
1325
1326   /* Do we have any tap listeners with filters? */
1327   filtering_tap_listeners = have_filtering_tap_listeners();
1328
1329   /* Get the union of the flags for all tap listeners. */
1330   tap_flags = union_of_tap_listener_flags();
1331
1332   wtap_phdr_init(&file_phdr);
1333
1334   /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1335   file_phdr.pkt_encap = 1234;
1336
1337   if (perform_two_pass_analysis) {
1338     frame_data *fdata;
1339
1340     /* Allocate a frame_data_sequence for all the frames. */
1341     cf->frames = new_frame_data_sequence();
1342
1343     if (do_dissection) {
1344       gboolean create_proto_tree;
1345
1346       /*
1347        * Determine whether we need to create a protocol tree.
1348        * We do if:
1349        *
1350        *    we're going to apply a read filter;
1351        *
1352        *    a postdissector wants field values or protocols
1353        *    on the first pass.
1354        */
1355       create_proto_tree =
1356         (cf->rfcode != NULL || postdissectors_want_hfids());
1357
1358       /* We're not going to display the protocol tree on this pass,
1359          so it's not going to be "visible". */
1360       edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
1361     }
1362     while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1363       if (process_packet_first_pass(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1364                                     wtap_buf_ptr(cf->wth))) {
1365
1366         /* Stop reading if we have the maximum number of packets;
1367          * When the -c option has not been used, max_packet_count
1368          * starts at 0, which practically means, never stop reading.
1369          * (unless we roll over max_packet_count ?)
1370          */
1371         if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1372           err = 0; /* This is not an error */
1373           break;
1374         }
1375       }
1376     }
1377
1378     if (edt) {
1379       epan_dissect_free(edt);
1380       edt = NULL;
1381     }
1382
1383 #if 0
1384     /* Close the sequential I/O side, to free up memory it requires. */
1385     wtap_sequential_close(cf->wth);
1386 #endif
1387
1388     /* Allow the protocol dissectors to free up memory that they
1389      * don't need after the sequential run-through of the packets. */
1390     postseq_cleanup_all_protocols();
1391
1392     prev_dis = NULL;
1393     prev_cap = NULL;
1394     ws_buffer_init(&buf, 1500);
1395
1396     if (do_dissection) {
1397       gboolean create_proto_tree;
1398
1399       /*
1400        * Determine whether we need to create a protocol tree.
1401        * We do if:
1402        *
1403        *    we're going to apply a display filter;
1404        *
1405        *    we're going to print the protocol tree;
1406        *
1407        *    one of the tap listeners requires a protocol tree;
1408        *
1409        *    we have custom columns (which require field values, which
1410        *    currently requires that we build a protocol tree).
1411        */
1412       create_proto_tree =
1413         (cf->dfcode || print_details || filtering_tap_listeners ||
1414          (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo));
1415
1416       /* The protocol tree will be "visible", i.e., printed, only if we're
1417          printing packet details, which is true if we're printing stuff
1418          ("print_packet_info" is true) and we're in verbose mode
1419          ("packet_details" is true). */
1420       edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1421     }
1422
1423     for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
1424       fdata = frame_data_sequence_find(cf->frames, framenum);
1425 #if 0
1426       if (wtap_seek_read(cf->wth, fdata->file_off,
1427           &buf, fdata->cap_len, &err, &err_info)) {
1428         process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1429       }
1430 #else
1431       if (!process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf,
1432                                        tap_flags))
1433         return FALSE;
1434 #endif
1435     }
1436
1437     if (edt) {
1438       epan_dissect_free(edt);
1439       edt = NULL;
1440     }
1441
1442     ws_buffer_free(&buf);
1443   }
1444   else {
1445     framenum = 0;
1446
1447     if (do_dissection) {
1448       gboolean create_proto_tree;
1449
1450       /*
1451        * Determine whether we need to create a protocol tree.
1452        * We do if:
1453        *
1454        *    we're going to apply a read filter;
1455        *
1456        *    we're going to apply a display filter;
1457        *
1458        *    we're going to print the protocol tree;
1459        *
1460        *    one of the tap listeners is going to apply a filter;
1461        *
1462        *    one of the tap listeners requires a protocol tree;
1463        *
1464        *    a postdissector wants field values or protocols
1465        *    on the first pass;
1466        *
1467        *    we have custom columns (which require field values, which
1468        *    currently requires that we build a protocol tree).
1469        */
1470       create_proto_tree =
1471         (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
1472           (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
1473           have_custom_cols(&cf->cinfo));
1474
1475       /* The protocol tree will be "visible", i.e., printed, only if we're
1476          printing packet details, which is true if we're printing stuff
1477          ("print_packet_info" is true) and we're in verbose mode
1478          ("packet_details" is true). */
1479       edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1480     }
1481
1482     while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1483
1484       framenum++;
1485
1486       if (!process_packet_single_pass(cf, edt, data_offset,
1487                                       &file_phdr/*wtap_phdr(cf->wth)*/,
1488                                       raw_data, tap_flags))
1489         return FALSE;
1490
1491       /* Stop reading if we have the maximum number of packets;
1492       * When the -c option has not been used, max_packet_count
1493       * starts at 0, which practically means, never stop reading.
1494       * (unless we roll over max_packet_count ?)
1495       */
1496       if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1497         err = 0; /* This is not an error */
1498         break;
1499       }
1500     }
1501
1502     if (edt) {
1503       epan_dissect_free(edt);
1504       edt = NULL;
1505     }
1506   }
1507
1508   wtap_phdr_cleanup(&file_phdr);
1509
1510   if (err != 0) {
1511     /*
1512      * Print a message noting that the read failed somewhere along the line.
1513      *
1514      * If we're printing packet data, and the standard output and error are
1515      * going to the same place, flush the standard output, so everything
1516      * buffered up is written, and then print a newline to the standard error
1517      * before printing the error message, to separate it from the packet
1518      * data.  (Alas, that only works on UN*X; st_dev is meaningless, and
1519      * the _fstat() documentation at Microsoft doesn't indicate whether
1520      * st_ino is even supported.)
1521      */
1522 #ifndef _WIN32
1523     if (print_packet_info) {
1524       ws_statb64 stat_stdout, stat_stderr;
1525
1526       if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
1527         if (stat_stdout.st_dev == stat_stderr.st_dev &&
1528             stat_stdout.st_ino == stat_stderr.st_ino) {
1529           fflush(stdout);
1530           fprintf(stderr, "\n");
1531         }
1532       }
1533     }
1534 #endif
1535 #if 0
1536     switch (err) {
1537
1538     case FTAP_ERR_UNSUPPORTED:
1539       cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
1540                  cf->filename, err_info);
1541       g_free(err_info);
1542       break;
1543
1544     case FTAP_ERR_UNSUPPORTED_ENCAP:
1545       cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
1546                  cf->filename, err_info);
1547       g_free(err_info);
1548       break;
1549
1550     case FTAP_ERR_CANT_READ:
1551       cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
1552                  cf->filename);
1553       break;
1554
1555     case FTAP_ERR_SHORT_READ:
1556       cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
1557                  cf->filename);
1558       break;
1559
1560     case FTAP_ERR_BAD_FILE:
1561       cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
1562                  cf->filename, err_info);
1563       g_free(err_info);
1564       break;
1565
1566     case FTAP_ERR_DECOMPRESS:
1567       cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
1568                  "(%s)", cf->filename, err_info);
1569       break;
1570
1571     default:
1572       cmdarg_err("An error occurred while reading the file \"%s\": %s.",
1573                  cf->filename, ftap_strerror(err));
1574       break;
1575     }
1576 #endif
1577   } else {
1578     if (print_packet_info) {
1579       if (!write_finale()) {
1580         err = errno;
1581         show_print_file_io_error(err);
1582       }
1583     }
1584   }
1585
1586 out:
1587   wtap_close(cf->wth);
1588   cf->wth = NULL;
1589
1590   return (err != 0);
1591 }
1592
1593 static gboolean
1594 process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset,
1595                            struct wtap_pkthdr *whdr, const guchar *pd,
1596                            guint tap_flags)
1597 {
1598   frame_data      fdata;
1599   column_info    *cinfo;
1600   gboolean        passed;
1601
1602   /* Count this packet. */
1603   cf->count++;
1604
1605   /* If we're not running a display filter and we're not printing any
1606      packet information, we don't need to do a dissection. This means
1607      that all packets can be marked as 'passed'. */
1608   passed = TRUE;
1609
1610   frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
1611
1612   /* If we're going to print packet information, or we're going to
1613      run a read filter, or we're going to process taps, set up to
1614      do a dissection and do so. */
1615   if (edt) {
1616     /* If we're running a filter, prime the epan_dissect_t with that
1617        filter. */
1618     if (cf->dfcode)
1619       epan_dissect_prime_with_dfilter(edt, cf->dfcode);
1620
1621     col_custom_prime_edt(edt, &cf->cinfo);
1622
1623     /* We only need the columns if either
1624          1) some tap needs the columns
1625        or
1626          2) we're printing packet info but we're *not* verbose; in verbose
1627             mode, we print the protocol tree, not the protocol summary.
1628        or
1629          3) there is a column mapped as an individual field */
1630     if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
1631       cinfo = &cf->cinfo;
1632     else
1633       cinfo = NULL;
1634
1635     frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
1636                                   &ref, prev_dis);
1637     if (ref == &fdata) {
1638       ref_frame = fdata;
1639       ref = &ref_frame;
1640     }
1641
1642     epan_dissect_file_run_with_taps(edt, whdr, frame_tvbuff_new(&fdata, pd), &fdata, cinfo);
1643
1644     /* Run the filter if we have it. */
1645     if (cf->dfcode)
1646       passed = dfilter_apply_edt(cf->dfcode, edt);
1647   }
1648
1649   if (passed) {
1650     frame_data_set_after_dissect(&fdata, &cum_bytes);
1651
1652     /* Process this packet. */
1653     if (print_packet_info) {
1654       /* We're printing packet information; print the information for
1655          this packet. */
1656       print_packet(cf, edt);
1657
1658       /* If we're doing "line-buffering", flush the standard output
1659          after every packet.  See the comment above, for the "-l"
1660          option, for an explanation of why we do that. */
1661       if (line_buffered)
1662         fflush(stdout);
1663
1664       if (ferror(stdout)) {
1665         show_print_file_io_error(errno);
1666         return FALSE;
1667       }
1668     }
1669
1670     /* this must be set after print_packet() [bug #8160] */
1671     prev_dis_frame = fdata;
1672     prev_dis = &prev_dis_frame;
1673   }
1674
1675   prev_cap_frame = fdata;
1676   prev_cap = &prev_cap_frame;
1677
1678   if (edt) {
1679     epan_dissect_reset(edt);
1680     frame_data_destroy(&fdata);
1681   }
1682   return passed;
1683 }
1684
1685 static gboolean
1686 write_preamble(capture_file *cf)
1687 {
1688   switch (output_action) {
1689
1690   case WRITE_TEXT:
1691     return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
1692
1693   case WRITE_XML:
1694     if (print_details)
1695       write_pdml_preamble(stdout, cf->filename);
1696     else
1697       write_psml_preamble(&cf->cinfo, stdout);
1698     return !ferror(stdout);
1699
1700   case WRITE_FIELDS:
1701     write_fields_preamble(output_fields, stdout);
1702     return !ferror(stdout);
1703
1704   default:
1705     g_assert_not_reached();
1706     return FALSE;
1707   }
1708 }
1709
1710 static char *
1711 get_line_buf(size_t len)
1712 {
1713   static char   *line_bufp    = NULL;
1714   static size_t  line_buf_len = 256;
1715   size_t         new_line_buf_len;
1716
1717   for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
1718        new_line_buf_len *= 2)
1719     ;
1720   if (line_bufp == NULL) {
1721     line_buf_len = new_line_buf_len;
1722     line_bufp = (char *)g_malloc(line_buf_len + 1);
1723   } else {
1724     if (new_line_buf_len > line_buf_len) {
1725       line_buf_len = new_line_buf_len;
1726       line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
1727     }
1728   }
1729   return line_bufp;
1730 }
1731
1732 static inline void
1733 put_string(char *dest, const char *str, size_t str_len)
1734 {
1735   memcpy(dest, str, str_len);
1736   dest[str_len] = '\0';
1737 }
1738
1739 static inline void
1740 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1741 {
1742   size_t i;
1743
1744   for (i = str_len; i < str_with_spaces; i++)
1745     *dest++ = ' ';
1746
1747   put_string(dest, str, str_len);
1748 }
1749
1750 static inline void
1751 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1752 {
1753   size_t i;
1754
1755   memcpy(dest, str, str_len);
1756   for (i = str_len; i < str_with_spaces; i++)
1757     dest[i] = ' ';
1758
1759   dest[str_with_spaces] = '\0';
1760 }
1761
1762 static gboolean
1763 print_columns(capture_file *cf)
1764 {
1765   char   *line_bufp;
1766   int     i;
1767   size_t  buf_offset;
1768   size_t  column_len;
1769   size_t  col_len;
1770   col_item_t* col_item;
1771
1772   line_bufp = get_line_buf(256);
1773   buf_offset = 0;
1774   *line_bufp = '\0';
1775   for (i = 0; i < cf->cinfo.num_cols; i++) {
1776     col_item = &cf->cinfo.columns[i];
1777     /* Skip columns not marked as visible. */
1778     if (!get_column_visible(i))
1779       continue;
1780     switch (col_item->col_fmt) {
1781     case COL_NUMBER:
1782       column_len = col_len = strlen(col_item->col_data);
1783       if (column_len < 3)
1784         column_len = 3;
1785       line_bufp = get_line_buf(buf_offset + column_len);
1786       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1787       break;
1788
1789     case COL_CLS_TIME:
1790     case COL_REL_TIME:
1791     case COL_ABS_TIME:
1792     case COL_ABS_YMD_TIME:  /* XXX - wider */
1793     case COL_ABS_YDOY_TIME: /* XXX - wider */
1794     case COL_UTC_TIME:
1795     case COL_UTC_YMD_TIME:  /* XXX - wider */
1796     case COL_UTC_YDOY_TIME: /* XXX - wider */
1797       column_len = col_len = strlen(col_item->col_data);
1798       if (column_len < 10)
1799         column_len = 10;
1800       line_bufp = get_line_buf(buf_offset + column_len);
1801       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1802       break;
1803
1804     case COL_DEF_SRC:
1805     case COL_RES_SRC:
1806     case COL_UNRES_SRC:
1807     case COL_DEF_DL_SRC:
1808     case COL_RES_DL_SRC:
1809     case COL_UNRES_DL_SRC:
1810     case COL_DEF_NET_SRC:
1811     case COL_RES_NET_SRC:
1812     case COL_UNRES_NET_SRC:
1813       column_len = col_len = strlen(col_item->col_data);
1814       if (column_len < 12)
1815         column_len = 12;
1816       line_bufp = get_line_buf(buf_offset + column_len);
1817       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1818       break;
1819
1820     case COL_DEF_DST:
1821     case COL_RES_DST:
1822     case COL_UNRES_DST:
1823     case COL_DEF_DL_DST:
1824     case COL_RES_DL_DST:
1825     case COL_UNRES_DL_DST:
1826     case COL_DEF_NET_DST:
1827     case COL_RES_NET_DST:
1828     case COL_UNRES_NET_DST:
1829       column_len = col_len = strlen(col_item->col_data);
1830       if (column_len < 12)
1831         column_len = 12;
1832       line_bufp = get_line_buf(buf_offset + column_len);
1833       put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1834       break;
1835
1836     default:
1837       column_len = strlen(col_item->col_data);
1838       line_bufp = get_line_buf(buf_offset + column_len);
1839       put_string(line_bufp + buf_offset, col_item->col_data, column_len);
1840       break;
1841     }
1842     buf_offset += column_len;
1843     if (i != cf->cinfo.num_cols - 1) {
1844       /*
1845        * This isn't the last column, so we need to print a
1846        * separator between this column and the next.
1847        *
1848        * If we printed a network source and are printing a
1849        * network destination of the same type next, separate
1850        * them with " -> "; if we printed a network destination
1851        * and are printing a network source of the same type
1852        * next, separate them with " <- "; otherwise separate them
1853        * with a space.
1854        *
1855        * We add enough space to the buffer for " <- " or " -> ",
1856        * even if we're only adding " ".
1857        */
1858       line_bufp = get_line_buf(buf_offset + 4);
1859       switch (col_item->col_fmt) {
1860
1861       case COL_DEF_SRC:
1862       case COL_RES_SRC:
1863       case COL_UNRES_SRC:
1864         switch (cf->cinfo.columns[i+1].col_fmt) {
1865
1866         case COL_DEF_DST:
1867         case COL_RES_DST:
1868         case COL_UNRES_DST:
1869           put_string(line_bufp + buf_offset, " -> ", 4);
1870           buf_offset += 4;
1871           break;
1872
1873         default:
1874           put_string(line_bufp + buf_offset, " ", 1);
1875           buf_offset += 1;
1876           break;
1877         }
1878         break;
1879
1880       case COL_DEF_DL_SRC:
1881       case COL_RES_DL_SRC:
1882       case COL_UNRES_DL_SRC:
1883         switch (cf->cinfo.columns[i+1].col_fmt) {
1884
1885         case COL_DEF_DL_DST:
1886         case COL_RES_DL_DST:
1887         case COL_UNRES_DL_DST:
1888           put_string(line_bufp + buf_offset, " -> ", 4);
1889           buf_offset += 4;
1890           break;
1891
1892         default:
1893           put_string(line_bufp + buf_offset, " ", 1);
1894           buf_offset += 1;
1895           break;
1896         }
1897         break;
1898
1899       case COL_DEF_NET_SRC:
1900       case COL_RES_NET_SRC:
1901       case COL_UNRES_NET_SRC:
1902         switch (cf->cinfo.columns[i+1].col_fmt) {
1903
1904         case COL_DEF_NET_DST:
1905         case COL_RES_NET_DST:
1906         case COL_UNRES_NET_DST:
1907           put_string(line_bufp + buf_offset, " -> ", 4);
1908           buf_offset += 4;
1909           break;
1910
1911         default:
1912           put_string(line_bufp + buf_offset, " ", 1);
1913           buf_offset += 1;
1914           break;
1915         }
1916         break;
1917
1918       case COL_DEF_DST:
1919       case COL_RES_DST:
1920       case COL_UNRES_DST:
1921         switch (cf->cinfo.columns[i+1].col_fmt) {
1922
1923         case COL_DEF_SRC:
1924         case COL_RES_SRC:
1925         case COL_UNRES_SRC:
1926           put_string(line_bufp + buf_offset, " <- ", 4);
1927           buf_offset += 4;
1928           break;
1929
1930         default:
1931           put_string(line_bufp + buf_offset, " ", 1);
1932           buf_offset += 1;
1933           break;
1934         }
1935         break;
1936
1937       case COL_DEF_DL_DST:
1938       case COL_RES_DL_DST:
1939       case COL_UNRES_DL_DST:
1940         switch (cf->cinfo.columns[i+1].col_fmt) {
1941
1942         case COL_DEF_DL_SRC:
1943         case COL_RES_DL_SRC:
1944         case COL_UNRES_DL_SRC:
1945           put_string(line_bufp + buf_offset, " <- ", 4);
1946           buf_offset += 4;
1947           break;
1948
1949         default:
1950           put_string(line_bufp + buf_offset, " ", 1);
1951           buf_offset += 1;
1952           break;
1953         }
1954         break;
1955
1956       case COL_DEF_NET_DST:
1957       case COL_RES_NET_DST:
1958       case COL_UNRES_NET_DST:
1959         switch (cf->cinfo.columns[i+1].col_fmt) {
1960
1961         case COL_DEF_NET_SRC:
1962         case COL_RES_NET_SRC:
1963         case COL_UNRES_NET_SRC:
1964           put_string(line_bufp + buf_offset, " <- ", 4);
1965           buf_offset += 4;
1966           break;
1967
1968         default:
1969           put_string(line_bufp + buf_offset, " ", 1);
1970           buf_offset += 1;
1971           break;
1972         }
1973         break;
1974
1975       default:
1976         put_string(line_bufp + buf_offset, " ", 1);
1977         buf_offset += 1;
1978         break;
1979       }
1980     }
1981   }
1982   return print_line(print_stream, 0, line_bufp);
1983 }
1984
1985 static gboolean
1986 print_packet(capture_file *cf, epan_dissect_t *edt)
1987 {
1988   if (print_summary || output_fields_has_cols(output_fields)) {
1989     /* Just fill in the columns. */
1990     epan_dissect_fill_in_columns(edt, FALSE, TRUE);
1991
1992     if (print_summary) {
1993       /* Now print them. */
1994       switch (output_action) {
1995
1996       case WRITE_TEXT:
1997         if (!print_columns(cf))
1998           return FALSE;
1999         break;
2000
2001       case WRITE_XML:
2002         write_psml_columns(edt, stdout);
2003         return !ferror(stdout);
2004       case WRITE_FIELDS: /*No non-verbose "fields" format */
2005         g_assert_not_reached();
2006         break;
2007       }
2008     }
2009   }
2010   if (print_details) {
2011     /* Print the information in the protocol tree. */
2012     switch (output_action) {
2013
2014     case WRITE_TEXT:
2015       if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
2016                             print_hex, edt, output_only_tables, print_stream))
2017         return FALSE;
2018       if (!print_hex) {
2019         if (!print_line(print_stream, 0, separator))
2020           return FALSE;
2021       }
2022       break;
2023
2024     case WRITE_XML:
2025       write_pdml_proto_tree(NULL, NULL, PF_NONE, edt, stdout);
2026       printf("\n");
2027       return !ferror(stdout);
2028     case WRITE_FIELDS:
2029       write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
2030       printf("\n");
2031       return !ferror(stdout);
2032     }
2033   }
2034   if (print_hex) {
2035     if (print_summary || print_details) {
2036       if (!print_line(print_stream, 0, ""))
2037         return FALSE;
2038     }
2039     if (!print_hex_data(print_stream, edt))
2040       return FALSE;
2041     if (!print_line(print_stream, 0, separator))
2042       return FALSE;
2043   }
2044   return TRUE;
2045 }
2046
2047 static gboolean
2048 write_finale(void)
2049 {
2050   switch (output_action) {
2051
2052   case WRITE_TEXT:
2053     return print_finale(print_stream);
2054
2055   case WRITE_XML:
2056     if (print_details)
2057       write_pdml_finale(stdout);
2058     else
2059       write_psml_finale(stdout);
2060     return !ferror(stdout);
2061
2062   case WRITE_FIELDS:
2063     write_fields_finale(output_fields, stdout);
2064     return !ferror(stdout);
2065
2066   default:
2067     g_assert_not_reached();
2068     return FALSE;
2069   }
2070 }
2071
2072 cf_status_t
2073 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
2074 {
2075   gchar *err_info;
2076   char   err_msg[2048+1];
2077
2078   /* The open isn't implemented yet.  Fill in the information for this file. */
2079
2080   /* Create new epan session for dissection. */
2081   epan_free(cf->epan);
2082   cf->epan = tfshark_epan_new(cf);
2083
2084   cf->wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2085   cf->f_datalen = 0; /* not used, but set it anyway */
2086
2087   /* Set the file name because we need it to set the follow stream filter.
2088      XXX - is that still true?  We need it for other reasons, though,
2089      in any case. */
2090   cf->filename = g_strdup(fname);
2091
2092   /* Indicate whether it's a permanent or temporary file. */
2093   cf->is_tempfile = is_tempfile;
2094
2095   /* No user changes yet. */
2096   cf->unsaved_changes = FALSE;
2097
2098   cf->cd_t      = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2099   cf->open_type = type;
2100   cf->count     = 0;
2101   cf->drops_known = FALSE;
2102   cf->drops     = 0;
2103   cf->snap      = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2104   if (cf->snap == 0) {
2105     /* Snapshot length not known. */
2106     cf->has_snap = FALSE;
2107     cf->snap = 0;
2108   } else
2109     cf->has_snap = TRUE;
2110   nstime_set_zero(&cf->elapsed_time);
2111   ref = NULL;
2112   prev_dis = NULL;
2113   prev_cap = NULL;
2114
2115   cf->state = FILE_READ_IN_PROGRESS;
2116
2117   return CF_OK;
2118
2119 /* fail: */
2120   g_snprintf(err_msg, sizeof err_msg,
2121              cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
2122   cmdarg_err("%s", err_msg);
2123   return CF_ERROR;
2124 }
2125
2126 static void
2127 show_print_file_io_error(int err)
2128 {
2129   switch (err) {
2130
2131   case ENOSPC:
2132     cmdarg_err("Not all the packets could be printed because there is "
2133 "no space left on the file system.");
2134     break;
2135
2136 #ifdef EDQUOT
2137   case EDQUOT:
2138     cmdarg_err("Not all the packets could be printed because you are "
2139 "too close to, or over your disk quota.");
2140   break;
2141 #endif
2142
2143   default:
2144     cmdarg_err("An error occurred while printing packets: %s.",
2145       g_strerror(err));
2146     break;
2147   }
2148 }
2149
2150 static const char *
2151 cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
2152                       int file_type _U_)
2153 {
2154   const char *errmsg;
2155   /* static char errmsg_errno[1024+1]; */
2156
2157 #if 0
2158   if (err < 0) {
2159     /* Wiretap error. */
2160     switch (err) {
2161
2162     case FTAP_ERR_NOT_REGULAR_FILE:
2163       errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
2164       break;
2165
2166     case FTAP_ERR_RANDOM_OPEN_PIPE:
2167       /* Seen only when opening a capture file for reading. */
2168       errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
2169       break;
2170
2171     case FTAP_ERR_FILE_UNKNOWN_FORMAT:
2172       /* Seen only when opening a capture file for reading. */
2173       errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
2174       break;
2175
2176     case FTAP_ERR_UNSUPPORTED:
2177       /* Seen only when opening a capture file for reading. */
2178       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2179                "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
2180                "(%s)", err_info);
2181       g_free(err_info);
2182       errmsg = errmsg_errno;
2183       break;
2184
2185     case FTAP_ERR_CANT_WRITE_TO_PIPE:
2186       /* Seen only when opening a capture file for writing. */
2187       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2188                  "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
2189                  "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
2190       errmsg = errmsg_errno;
2191       break;
2192
2193     case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
2194       /* Seen only when opening a capture file for writing. */
2195       errmsg = "TFShark doesn't support writing capture files in that format.";
2196       break;
2197
2198     case FTAP_ERR_UNSUPPORTED_ENCAP:
2199       if (for_writing) {
2200         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2201                    "TFShark can't save this capture as a \"%s\" file.",
2202                    ftap_file_type_subtype_short_string(file_type));
2203       } else {
2204         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2205                  "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
2206                  "(%s)", err_info);
2207         g_free(err_info);
2208       }
2209       errmsg = errmsg_errno;
2210       break;
2211
2212     case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
2213       if (for_writing) {
2214         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2215                    "TFShark can't save this capture as a \"%s\" file.",
2216                    ftap_file_type_subtype_short_string(file_type));
2217         errmsg = errmsg_errno;
2218       } else
2219         errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
2220       break;
2221
2222     case FTAP_ERR_BAD_FILE:
2223       /* Seen only when opening a capture file for reading. */
2224       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2225                "The file \"%%s\" appears to be damaged or corrupt.\n"
2226                "(%s)", err_info);
2227       g_free(err_info);
2228       errmsg = errmsg_errno;
2229       break;
2230
2231     case FTAP_ERR_CANT_OPEN:
2232       if (for_writing)
2233         errmsg = "The file \"%s\" could not be created for some unknown reason.";
2234       else
2235         errmsg = "The file \"%s\" could not be opened for some unknown reason.";
2236       break;
2237
2238     case FTAP_ERR_SHORT_READ:
2239       errmsg = "The file \"%s\" appears to have been cut short"
2240                " in the middle of a packet or other data.";
2241       break;
2242
2243     case FTAP_ERR_SHORT_WRITE:
2244       errmsg = "A full header couldn't be written to the file \"%s\".";
2245       break;
2246
2247     case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
2248       errmsg = "This file type cannot be written as a compressed file.";
2249       break;
2250
2251     case FTAP_ERR_DECOMPRESS:
2252       /* Seen only when opening a capture file for reading. */
2253       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2254                  "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
2255                  "(%s)", err_info);
2256       g_free(err_info);
2257       errmsg = errmsg_errno;
2258       break;
2259
2260     default:
2261       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2262                  "The file \"%%s\" could not be %s: %s.",
2263                  for_writing ? "created" : "opened",
2264                  ftap_strerror(err));
2265       errmsg = errmsg_errno;
2266       break;
2267     }
2268   } else
2269 #endif
2270     errmsg = file_open_error_message(err, for_writing);
2271   return errmsg;
2272 }
2273
2274 /*
2275  * General errors and warnings are reported with an console message
2276  * in TFShark.
2277  */
2278 static void
2279 failure_warning_message(const char *msg_format, va_list ap)
2280 {
2281   fprintf(stderr, "tfshark: ");
2282   vfprintf(stderr, msg_format, ap);
2283   fprintf(stderr, "\n");
2284 }
2285
2286 /*
2287  * Open/create errors are reported with an console message in TFShark.
2288  */
2289 static void
2290 open_failure_message(const char *filename, int err, gboolean for_writing)
2291 {
2292   fprintf(stderr, "tfshark: ");
2293   fprintf(stderr, file_open_error_message(err, for_writing), filename);
2294   fprintf(stderr, "\n");
2295 }
2296
2297 /*
2298  * Read errors are reported with an console message in TFShark.
2299  */
2300 static void
2301 read_failure_message(const char *filename, int err)
2302 {
2303   cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
2304           filename, g_strerror(err));
2305 }
2306
2307 /*
2308  * Write errors are reported with an console message in TFShark.
2309  */
2310 static void
2311 write_failure_message(const char *filename, int err)
2312 {
2313   cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
2314           filename, g_strerror(err));
2315 }
2316
2317 /*
2318  * Report additional information for an error in command-line arguments.
2319  */
2320 static void
2321 failure_message_cont(const char *msg_format, va_list ap)
2322 {
2323   vfprintf(stderr, msg_format, ap);
2324   fprintf(stderr, "\n");
2325 }
2326
2327 /*
2328  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2329  *
2330  * Local variables:
2331  * c-basic-offset: 2
2332  * tab-width: 8
2333  * indent-tabs-mode: nil
2334  * End:
2335  *
2336  * vi: set shiftwidth=2 tabstop=8 expandtab:
2337  * :indentSize=2:tabSize=8:noTabs=true:
2338  */