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