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