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