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