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