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