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