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