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