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