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