tools/checkAPIs.pl: improve the hf_ error messages
[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   if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
972                  NULL))
973     return 2;
974
975   /* Register all tap listeners; we do this before we parse the arguments,
976      as the "-z" argument can specify a registered tap. */
977
978   /* we register the plugin taps before the other taps because
979      stats_tree taps plugins will be registered as tap listeners
980      by stats_tree_stat.c and need to registered before that */
981
982   /* XXX Disable tap registration for now until we can get tfshark set up with
983    * its own set of taps and the necessary registration function etc.
984 #ifdef HAVE_PLUGINS
985   register_all_plugin_tap_listeners();
986 #endif
987   register_all_tap_listeners();
988   */
989
990   /* If invoked with the "-G" flag, we dump out information based on
991      the argument to the "-G" flag; if no argument is specified,
992      for backwards compatibility we dump out a glossary of display
993      filter symbols.
994
995      XXX - we do this here, for now, to support "-G" with no arguments.
996      If none of our build or other processes uses "-G" with no arguments,
997      we can just process it with the other arguments. */
998   if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
999     proto_initialize_all_prefixes();
1000
1001     if (argc == 2)
1002       proto_registrar_dump_fields();
1003     else {
1004       if (strcmp(argv[2], "column-formats") == 0)
1005         column_dump_column_formats();
1006       else if (strcmp(argv[2], "currentprefs") == 0) {
1007         read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1008             &pf_open_errno, &pf_read_errno, &pf_path);
1009         write_prefs(NULL);
1010       }
1011       else if (strcmp(argv[2], "decodes") == 0)
1012         dissector_dump_decodes();
1013       else if (strcmp(argv[2], "defaultprefs") == 0)
1014         write_prefs(NULL);
1015       else if (strcmp(argv[2], "dissector-tables") == 0)
1016         dissector_dump_dissector_tables();
1017       else if (strcmp(argv[2], "fields") == 0)
1018         proto_registrar_dump_fields();
1019       else if (strcmp(argv[2], "ftypes") == 0)
1020         proto_registrar_dump_ftypes();
1021       else if (strcmp(argv[2], "heuristic-decodes") == 0)
1022         dissector_dump_heur_decodes();
1023       else if (strcmp(argv[2], "plugins") == 0) {
1024 #ifdef HAVE_PLUGINS
1025         plugins_dump_all();
1026 #endif
1027 #ifdef HAVE_LUA
1028         wslua_plugins_dump_all();
1029 #endif
1030       }
1031       else if (strcmp(argv[2], "protocols") == 0)
1032         proto_registrar_dump_protocols();
1033       else if (strcmp(argv[2], "values") == 0)
1034         proto_registrar_dump_values();
1035       else if (strcmp(argv[2], "?") == 0)
1036         glossary_option_help();
1037       else if (strcmp(argv[2], "-?") == 0)
1038         glossary_option_help();
1039       else {
1040         cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
1041         return 1;
1042       }
1043     }
1044     return 0;
1045   }
1046
1047   prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1048                      &pf_open_errno, &pf_read_errno, &pf_path);
1049   if (gpf_path != NULL) {
1050     if (gpf_open_errno != 0) {
1051       cmdarg_err("Can't open global preferences file \"%s\": %s.",
1052               pf_path, g_strerror(gpf_open_errno));
1053     }
1054     if (gpf_read_errno != 0) {
1055       cmdarg_err("I/O error reading global preferences file \"%s\": %s.",
1056               pf_path, g_strerror(gpf_read_errno));
1057     }
1058   }
1059   if (pf_path != NULL) {
1060     if (pf_open_errno != 0) {
1061       cmdarg_err("Can't open your preferences file \"%s\": %s.", pf_path,
1062               g_strerror(pf_open_errno));
1063     }
1064     if (pf_read_errno != 0) {
1065       cmdarg_err("I/O error reading your preferences file \"%s\": %s.",
1066               pf_path, g_strerror(pf_read_errno));
1067     }
1068     g_free(pf_path);
1069     pf_path = NULL;
1070   }
1071
1072   /* Read the disabled protocols file. */
1073   read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
1074                             &dp_path, &dp_open_errno, &dp_read_errno);
1075   read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
1076                             &dp_path, &dp_open_errno, &dp_read_errno);
1077   if (gdp_path != NULL) {
1078     if (gdp_open_errno != 0) {
1079       cmdarg_err("Could not open global disabled protocols file\n\"%s\": %s.",
1080                  gdp_path, g_strerror(gdp_open_errno));
1081     }
1082     if (gdp_read_errno != 0) {
1083       cmdarg_err("I/O error reading global disabled protocols file\n\"%s\": %s.",
1084                  gdp_path, g_strerror(gdp_read_errno));
1085     }
1086     g_free(gdp_path);
1087   }
1088   if (dp_path != NULL) {
1089     if (dp_open_errno != 0) {
1090       cmdarg_err(
1091         "Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
1092         g_strerror(dp_open_errno));
1093     }
1094     if (dp_read_errno != 0) {
1095       cmdarg_err(
1096         "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
1097         g_strerror(dp_read_errno));
1098     }
1099     g_free(dp_path);
1100   }
1101
1102   cap_file_init(&cfile);
1103
1104   /* Print format defaults to this. */
1105   print_format = PR_FMT_TEXT;
1106
1107   output_fields = output_fields_new();
1108
1109   /*
1110    * To reset the options parser, set optreset to 1 on platforms that
1111    * have optreset (documented in *BSD and OS X, apparently present but
1112    * not documented in Solaris - the Illumos repository seems to
1113    * suggest that the first Solaris getopt_long(), at least as of 2004,
1114    * was based on the NetBSD one, it had optreset) and set optind to 1,
1115    * and set optind to 0 otherwise (documented as working in the GNU
1116    * getopt_long().  Setting optind to 0 didn't originally work in the
1117    * NetBSD one, but that was added later - we don't want to depend on
1118    * it if we have optreset).
1119    *
1120    * Also reset opterr to 1, so that error messages are printed by
1121    * getopt_long().
1122    */
1123 #ifdef HAVE_OPTRESET
1124   optreset = 1;
1125   optind = 1;
1126 #else
1127   optind = 0;
1128 #endif
1129   opterr = 1;
1130
1131   /* Now get our args */
1132   while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
1133     switch (opt) {
1134     case '2':        /* Perform two pass analysis */
1135       perform_two_pass_analysis = TRUE;
1136       break;
1137     case 'C':
1138       /* already processed; just ignore it now */
1139       break;
1140     case 'd':        /* Decode as rule */
1141       if (!add_decode_as(optarg))
1142         return 1;
1143       break;
1144 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
1145     case 'K':        /* Kerberos keytab file */
1146       read_keytab_file(optarg);
1147       break;
1148 #endif
1149     case 'e':
1150       /* Field entry */
1151       output_fields_add(output_fields, optarg);
1152       break;
1153     case 'E':
1154       /* Field option */
1155       if (!output_fields_set_option(output_fields, optarg)) {
1156         cmdarg_err("\"%s\" is not a valid field output option=value pair.", optarg);
1157         output_fields_list_options(stderr);
1158         return 1;
1159       }
1160       break;
1161
1162     case 'h':        /* Print help and exit */
1163       printf("TFShark (Wireshark) %s\n"
1164              "Dump and analyze network traffic.\n"
1165              "See https://www.wireshark.org for more information.\n",
1166              get_ws_vcs_version_info());
1167       print_usage(stdout);
1168       return 0;
1169       break;
1170     case 'l':        /* "Line-buffer" standard output */
1171       /* This isn't line-buffering, strictly speaking, it's just
1172          flushing the standard output after the information for
1173          each packet is printed; however, that should be good
1174          enough for all the purposes to which "-l" is put (and
1175          is probably actually better for "-V", as it does fewer
1176          writes).
1177
1178          See the comment in "process_packet()" for an explanation of
1179          why we do that, and why we don't just use "setvbuf()" to
1180          make the standard output line-buffered (short version: in
1181          Windows, "line-buffered" is the same as "fully-buffered",
1182          and the output buffer is only flushed when it fills up). */
1183       line_buffered = TRUE;
1184       break;
1185     case 'o':        /* Override preference from command line */
1186       switch (prefs_set_pref(optarg)) {
1187
1188       case PREFS_SET_OK:
1189         break;
1190
1191       case PREFS_SET_SYNTAX_ERR:
1192         cmdarg_err("Invalid -o flag \"%s\"", optarg);
1193         return 1;
1194         break;
1195
1196       case PREFS_SET_NO_SUCH_PREF:
1197       case PREFS_SET_OBSOLETE:
1198         cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
1199         return 1;
1200         break;
1201       }
1202       break;
1203     case 'q':        /* Quiet */
1204       quiet = TRUE;
1205       break;
1206     case 'Q':        /* Really quiet */
1207       quiet = TRUE;
1208       really_quiet = TRUE;
1209       break;
1210     case 'r':        /* Read capture file x */
1211       cf_name = g_strdup(optarg);
1212       break;
1213     case 'R':        /* Read file filter */
1214       rfilter = optarg;
1215       break;
1216     case 'S':        /* Set the line Separator to be printed between packets */
1217       separator = g_strdup(optarg);
1218       break;
1219     case 't':        /* Time stamp type */
1220       if (strcmp(optarg, "r") == 0)
1221         timestamp_set_type(TS_RELATIVE);
1222       else if (strcmp(optarg, "a") == 0)
1223         timestamp_set_type(TS_ABSOLUTE);
1224       else if (strcmp(optarg, "ad") == 0)
1225         timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
1226       else if (strcmp(optarg, "adoy") == 0)
1227         timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
1228       else if (strcmp(optarg, "d") == 0)
1229         timestamp_set_type(TS_DELTA);
1230       else if (strcmp(optarg, "dd") == 0)
1231         timestamp_set_type(TS_DELTA_DIS);
1232       else if (strcmp(optarg, "e") == 0)
1233         timestamp_set_type(TS_EPOCH);
1234       else if (strcmp(optarg, "u") == 0)
1235         timestamp_set_type(TS_UTC);
1236       else if (strcmp(optarg, "ud") == 0)
1237         timestamp_set_type(TS_UTC_WITH_YMD);
1238       else if (strcmp(optarg, "udoy") == 0)
1239         timestamp_set_type(TS_UTC_WITH_YDOY);
1240       else {
1241         cmdarg_err("Invalid time stamp type \"%s\"; it must be one of:", optarg);
1242         cmdarg_err_cont("\t\"a\"    for absolute\n"
1243                         "\t\"ad\"   for absolute with YYYY-MM-DD date\n"
1244                         "\t\"adoy\" for absolute with YYYY/DOY date\n"
1245                         "\t\"d\"    for delta\n"
1246                         "\t\"dd\"   for delta displayed\n"
1247                         "\t\"e\"    for epoch\n"
1248                         "\t\"r\"    for relative\n"
1249                         "\t\"u\"    for absolute UTC\n"
1250                         "\t\"ud\"   for absolute UTC with YYYY-MM-DD date\n"
1251                         "\t\"udoy\" for absolute UTC with YYYY/DOY date");
1252         return 1;
1253       }
1254       break;
1255     case 'T':        /* printing Type */
1256       if (strcmp(optarg, "text") == 0) {
1257         output_action = WRITE_TEXT;
1258         print_format = PR_FMT_TEXT;
1259       } else if (strcmp(optarg, "ps") == 0) {
1260         output_action = WRITE_TEXT;
1261         print_format = PR_FMT_PS;
1262       } else if (strcmp(optarg, "pdml") == 0) {
1263         output_action = WRITE_XML;
1264         print_details = TRUE;   /* Need details */
1265         print_summary = FALSE;  /* Don't allow summary */
1266       } else if (strcmp(optarg, "psml") == 0) {
1267         output_action = WRITE_XML;
1268         print_details = FALSE;  /* Don't allow details */
1269         print_summary = TRUE;   /* Need summary */
1270       } else if (strcmp(optarg, "fields") == 0) {
1271         output_action = WRITE_FIELDS;
1272         print_details = TRUE;   /* Need full tree info */
1273         print_summary = FALSE;  /* Don't allow summary */
1274       } else {
1275         cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg);                   /* x */
1276         cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
1277                         "\t         specified by the -E option.\n"
1278                         "\t\"pdml\"   Packet Details Markup Language, an XML-based format for the\n"
1279                         "\t         details of a decoded packet. This information is equivalent to\n"
1280                         "\t         the packet details printed with the -V flag.\n"
1281                         "\t\"ps\"     PostScript for a human-readable one-line summary of each of\n"
1282                         "\t         the packets, or a multi-line view of the details of each of\n"
1283                         "\t         the packets, depending on whether the -V flag was specified.\n"
1284                         "\t\"psml\"   Packet Summary Markup Language, an XML-based format for the\n"
1285                         "\t         summary information of a decoded packet. This information is\n"
1286                         "\t         equivalent to the information shown in the one-line summary\n"
1287                         "\t         printed by default.\n"
1288                         "\t\"text\"   Text of a human-readable one-line summary of each of the\n"
1289                         "\t         packets, or a multi-line view of the details of each of the\n"
1290                         "\t         packets, depending on whether the -V flag was specified.\n"
1291                         "\t         This is the default.");
1292         return 1;
1293       }
1294       break;
1295     case 'u':        /* Seconds type */
1296       if (strcmp(optarg, "s") == 0)
1297         timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
1298       else if (strcmp(optarg, "hms") == 0)
1299         timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
1300       else {
1301         cmdarg_err("Invalid seconds type \"%s\"; it must be one of:", optarg);
1302         cmdarg_err_cont("\t\"s\"   for seconds\n"
1303                         "\t\"hms\" for hours, minutes and seconds");
1304         return 1;
1305       }
1306       break;
1307     case 'v':         /* Show version and exit */
1308     {
1309       show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
1310       g_string_free(comp_info_str, TRUE);
1311       g_string_free(runtime_info_str, TRUE);
1312       /* We don't really have to cleanup here, but it's a convenient way to test
1313        * start-up and shut-down of the epan library without any UI-specific
1314        * cruft getting in the way. Makes the results of running
1315        * $ ./tools/valgrind-wireshark -n
1316        * much more useful. */
1317       epan_cleanup();
1318       return 0;
1319     }
1320     case 'O':        /* Only output these protocols */
1321       /* already processed; just ignore it now */
1322       break;
1323     case 'V':        /* Verbose */
1324       /* already processed; just ignore it now */
1325       break;
1326     case 'x':        /* Print packet data in hex (and ASCII) */
1327       /* already processed; just ignore it now */
1328       break;
1329     case 'X':
1330       /* already processed; just ignore it now */
1331       break;
1332     case 'Y':
1333       dfilter = optarg;
1334       break;
1335     case 'z':
1336       /* We won't call the init function for the stat this soon
1337          as it would disallow MATE's fields (which are registered
1338          by the preferences set callback) from being used as
1339          part of a tap filter.  Instead, we just add the argument
1340          to a list of stat arguments. */
1341       if (strcmp("help", optarg) == 0) {
1342         fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
1343         list_stat_cmd_args();
1344         return 0;
1345       }
1346       if (!process_stat_cmd_arg(optarg)) {
1347         cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
1348         list_stat_cmd_args();
1349         return 1;
1350       }
1351       break;
1352     default:
1353     case '?':        /* Bad flag - print usage message */
1354       print_usage(stderr);
1355       return 1;
1356       break;
1357     }
1358   }
1359
1360   /* If we specified output fields, but not the output field type... */
1361   if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
1362         cmdarg_err("Output fields were specified with \"-e\", "
1363             "but \"-Tfields\" was not specified.");
1364         return 1;
1365   } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
1366         cmdarg_err("\"-Tfields\" was specified, but no fields were "
1367                     "specified with \"-e\".");
1368
1369         return 1;
1370   }
1371
1372   /* If no capture filter or display filter has been specified, and there are
1373      still command-line arguments, treat them as the tokens of a capture
1374      filter (if no "-r" flag was specified) or a display filter (if a "-r"
1375      flag was specified. */
1376   if (optind < argc) {
1377     if (cf_name != NULL) {
1378       if (dfilter != NULL) {
1379         cmdarg_err("Display filters were specified both with \"-d\" "
1380             "and with additional command-line arguments.");
1381         return 1;
1382       }
1383       dfilter = get_args_as_string(argc, argv, optind);
1384     }
1385   }
1386
1387   /* if "-q" wasn't specified, we should print packet information */
1388   if (!quiet)
1389     print_packet_info = TRUE;
1390
1391   if (arg_error) {
1392     print_usage(stderr);
1393     return 1;
1394   }
1395
1396   if (print_hex) {
1397     if (output_action != WRITE_TEXT) {
1398       cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
1399       return 1;
1400     }
1401   }
1402
1403   if (output_only != NULL) {
1404     char *ps;
1405
1406     if (!print_details) {
1407       cmdarg_err("-O requires -V");
1408       return 1;
1409     }
1410
1411     output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
1412     for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
1413       g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
1414     }
1415   }
1416
1417   if (rfilter != NULL && !perform_two_pass_analysis) {
1418     cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
1419     return 1;
1420   }
1421
1422   /* Notify all registered modules that have had any of their preferences
1423      changed either from one of the preferences file or from the command
1424      line that their preferences have changed. */
1425   prefs_apply_all();
1426
1427   /* At this point MATE will have registered its field array so we can
1428      have a tap filter with one of MATE's late-registered fields as part
1429      of the filter.  We can now process all the "-z" arguments. */
1430   start_requested_stats();
1431
1432   /* disabled protocols as per configuration file */
1433   if (gdp_path == NULL && dp_path == NULL) {
1434     set_disabled_protos_list();
1435     set_disabled_heur_dissector_list();
1436   }
1437
1438   /* Build the column format array */
1439   build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
1440
1441   if (rfilter != NULL) {
1442     if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
1443       cmdarg_err("%s", err_msg);
1444       g_free(err_msg);
1445       epan_cleanup();
1446       return 2;
1447     }
1448   }
1449   cfile.rfcode = rfcode;
1450
1451   if (dfilter != NULL) {
1452     if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
1453       cmdarg_err("%s", err_msg);
1454       g_free(err_msg);
1455       epan_cleanup();
1456       return 2;
1457     }
1458   }
1459   cfile.dfcode = dfcode;
1460
1461   if (print_packet_info) {
1462     /* If we're printing as text or PostScript, we have
1463        to create a print stream. */
1464     if (output_action == WRITE_TEXT) {
1465       switch (print_format) {
1466
1467       case PR_FMT_TEXT:
1468         print_stream = print_stream_text_stdio_new(stdout);
1469         break;
1470
1471       case PR_FMT_PS:
1472         print_stream = print_stream_ps_stdio_new(stdout);
1473         break;
1474
1475       default:
1476         g_assert_not_reached();
1477       }
1478     }
1479   }
1480
1481   /* We have to dissect each packet if:
1482
1483         we're printing information about each packet;
1484
1485         we're using a read filter on the packets;
1486
1487         we're using a display filter on the packets;
1488
1489         we're using any taps that need dissection. */
1490   do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
1491
1492   if (cf_name) {
1493     /*
1494      * We're reading a capture file.
1495      */
1496
1497     /* TODO: if tfshark is ever changed to give the user a choice of which
1498        open_routine reader to use, then the following needs to change. */
1499     if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
1500       epan_cleanup();
1501       return 2;
1502     }
1503
1504     /* Process the packets in the file */
1505     TRY {
1506       /* XXX - for now there is only 1 packet */
1507       err = load_cap_file(&cfile, 1, 0);
1508     }
1509     CATCH(OutOfMemoryError) {
1510       fprintf(stderr,
1511               "Out Of Memory!\n"
1512               "\n"
1513               "Sorry, but TFShark has to terminate now!\n"
1514               "\n"
1515               "Some infos / workarounds can be found at:\n"
1516               "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
1517       err = ENOMEM;
1518     }
1519     ENDTRY;
1520
1521     if (err != 0) {
1522       /* We still dump out the results of taps, etc., as we might have
1523          read some packets; however, we exit with an error status. */
1524       exit_status = 2;
1525     }
1526   }
1527
1528   g_free(cf_name);
1529
1530   if (cfile.frames != NULL) {
1531     free_frame_data_sequence(cfile.frames);
1532     cfile.frames = NULL;
1533   }
1534
1535   draw_tap_listeners(TRUE);
1536   funnel_dump_all_text_windows();
1537   epan_free(cfile.epan);
1538   epan_cleanup();
1539
1540   output_fields_free(output_fields);
1541   output_fields = NULL;
1542
1543   return exit_status;
1544 }
1545
1546 static const nstime_t *
1547 tfshark_get_frame_ts(void *data, guint32 frame_num)
1548 {
1549   capture_file *cf = (capture_file *) data;
1550
1551   if (ref && ref->num == frame_num)
1552     return &ref->abs_ts;
1553
1554   if (prev_dis && prev_dis->num == frame_num)
1555     return &prev_dis->abs_ts;
1556
1557   if (prev_cap && prev_cap->num == frame_num)
1558     return &prev_cap->abs_ts;
1559
1560   if (cf->frames) {
1561      frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
1562
1563      return (fd) ? &fd->abs_ts : NULL;
1564   }
1565
1566   return NULL;
1567 }
1568
1569 static const char *
1570 no_interface_name(void *data _U_, guint32 interface_id _U_)
1571 {
1572     return "";
1573 }
1574
1575 static epan_t *
1576 tfshark_epan_new(capture_file *cf)
1577 {
1578   epan_t *epan = epan_new();
1579
1580   epan->data = cf;
1581   epan->get_frame_ts = tfshark_get_frame_ts;
1582   epan->get_interface_name = no_interface_name;
1583   epan->get_user_comment = NULL;
1584
1585   return epan;
1586 }
1587
1588 static gboolean
1589 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
1590                gint64 offset, struct wtap_pkthdr *whdr,
1591                const guchar *pd)
1592 {
1593   frame_data     fdlocal;
1594   guint32        framenum;
1595   gboolean       passed;
1596
1597   /* The frame number of this packet is one more than the count of
1598      frames in this packet. */
1599   framenum = cf->count + 1;
1600
1601   /* If we're not running a display filter and we're not printing any
1602      packet information, we don't need to do a dissection. This means
1603      that all packets can be marked as 'passed'. */
1604   passed = TRUE;
1605
1606   frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
1607
1608   /* If we're going to print packet information, or we're going to
1609      run a read filter, or display filter, or we're going to process taps, set up to
1610      do a dissection and do so. */
1611   if (edt) {
1612     /* If we're running a read filter, prime the epan_dissect_t with that
1613        filter. */
1614     if (cf->rfcode)
1615       epan_dissect_prime_dfilter(edt, cf->rfcode);
1616
1617     frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
1618                                   &ref, prev_dis);
1619     if (ref == &fdlocal) {
1620       ref_frame = fdlocal;
1621       ref = &ref_frame;
1622     }
1623
1624     epan_dissect_file_run(edt, whdr, file_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
1625
1626     /* Run the read filter if we have one. */
1627     if (cf->rfcode)
1628       passed = dfilter_apply_edt(cf->rfcode, edt);
1629   }
1630
1631   if (passed) {
1632     frame_data_set_after_dissect(&fdlocal, &cum_bytes);
1633     prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
1634
1635     /* If we're not doing dissection then there won't be any dependent frames.
1636      * More importantly, edt.pi.dependent_frames won't be initialized because
1637      * epan hasn't been initialized.
1638      */
1639     if (edt) {
1640       g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
1641     }
1642
1643     cf->count++;
1644   } else {
1645     /* if we don't add it to the frame_data_sequence, clean it up right now
1646      * to avoid leaks */
1647     frame_data_destroy(&fdlocal);
1648   }
1649
1650   if (edt)
1651     epan_dissect_reset(edt);
1652
1653   return passed;
1654 }
1655
1656 static gboolean
1657 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt, frame_data *fdata,
1658                struct wtap_pkthdr *phdr, Buffer *buf,
1659                guint tap_flags)
1660 {
1661   column_info    *cinfo;
1662   gboolean        passed;
1663
1664   /* If we're not running a display filter and we're not printing any
1665      packet information, we don't need to do a dissection. This means
1666      that all packets can be marked as 'passed'. */
1667   passed = TRUE;
1668
1669   /* If we're going to print packet information, or we're going to
1670      run a read filter, or we're going to process taps, set up to
1671      do a dissection and do so. */
1672   if (edt) {
1673
1674     /* If we're running a display filter, prime the epan_dissect_t with that
1675        filter. */
1676     if (cf->dfcode)
1677       epan_dissect_prime_dfilter(edt, cf->dfcode);
1678
1679     col_custom_prime_edt(edt, &cf->cinfo);
1680
1681     /* We only need the columns if either
1682          1) some tap needs the columns
1683        or
1684          2) we're printing packet info but we're *not* verbose; in verbose
1685             mode, we print the protocol tree, not the protocol summary.
1686      */
1687     if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
1688       cinfo = &cf->cinfo;
1689     else
1690       cinfo = NULL;
1691
1692     frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1693                                   &ref, prev_dis);
1694     if (ref == fdata) {
1695       ref_frame = *fdata;
1696       ref = &ref_frame;
1697     }
1698
1699     epan_dissect_file_run_with_taps(edt, phdr, file_tvbuff_new_buffer(fdata, buf), fdata, cinfo);
1700
1701     /* Run the read/display filter if we have one. */
1702     if (cf->dfcode)
1703       passed = dfilter_apply_edt(cf->dfcode, edt);
1704   }
1705
1706   if (passed) {
1707     frame_data_set_after_dissect(fdata, &cum_bytes);
1708     /* Process this packet. */
1709     if (print_packet_info) {
1710       /* We're printing packet information; print the information for
1711          this packet. */
1712       print_packet(cf, edt);
1713
1714       /* The ANSI C standard does not appear to *require* that a line-buffered
1715          stream be flushed to the host environment whenever a newline is
1716          written, it just says that, on such a stream, characters "are
1717          intended to be transmitted to or from the host environment as a
1718          block when a new-line character is encountered".
1719
1720          The Visual C++ 6.0 C implementation doesn't do what is intended;
1721          even if you set a stream to be line-buffered, it still doesn't
1722          flush the buffer at the end of every line.
1723
1724          So, if the "-l" flag was specified, we flush the standard output
1725          at the end of a packet.  This will do the right thing if we're
1726          printing packet summary lines, and, as we print the entire protocol
1727          tree for a single packet without waiting for anything to happen,
1728          it should be as good as line-buffered mode if we're printing
1729          protocol trees.  (The whole reason for the "-l" flag in either
1730          tcpdump or TShark is to allow the output of a live capture to
1731          be piped to a program or script and to have that script see the
1732          information for the packet as soon as it's printed, rather than
1733          having to wait until a standard I/O buffer fills up. */
1734       if (line_buffered)
1735         fflush(stdout);
1736
1737       if (ferror(stdout)) {
1738         show_print_file_io_error(errno);
1739         exit(2);
1740       }
1741     }
1742     prev_dis = fdata;
1743   }
1744   prev_cap = fdata;
1745
1746   if (edt) {
1747     epan_dissect_reset(edt);
1748   }
1749   return passed || fdata->flags.dependent_of_displayed;
1750 }
1751
1752 gboolean
1753 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)
1754 {
1755     /* int bytes_read; */
1756     gint64 packet_size = wtap_file_size(cf->wth, err);
1757
1758     *data_buffer = (guint8*)g_malloc((gsize)packet_size);
1759     /* bytes_read =*/ file_read(*data_buffer, (unsigned int)packet_size, cf->wth->fh);
1760
1761 #if 0 /* no more filetap */
1762     if (bytes_read < 0) {
1763         *err = file_error(cf->wth->fh, err_info);
1764         if (*err == 0)
1765             *err = FTAP_ERR_SHORT_READ;
1766         return FALSE;
1767     } else if (bytes_read == 0) {
1768         /* Done with file, no error */
1769         return FALSE;
1770     }
1771
1772
1773     /* XXX - SET FRAME SIZE EQUAL TO TOTAL FILE SIZE */
1774     file_phdr->caplen = (guint32)packet_size;
1775     file_phdr->len = (guint32)packet_size;
1776
1777     /*
1778      * Set the packet encapsulation to the file's encapsulation
1779      * value; if that's not WTAP_ENCAP_PER_PACKET, it's the
1780      * right answer (and means that the read routine for this
1781      * capture file type doesn't have to set it), and if it
1782      * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it
1783      * anyway.
1784      */
1785     wth->phdr.pkt_encap = wth->file_encap;
1786
1787     if (!wth->subtype_read(wth, err, err_info, data_offset)) {
1788         /*
1789          * If we didn't get an error indication, we read
1790          * the last packet.  See if there's any deferred
1791          * error, as might, for example, occur if we're
1792          * reading a compressed file, and we got an error
1793          * reading compressed data from the file, but
1794          * got enough compressed data to decompress the
1795          * last packet of the file.
1796          */
1797         if (*err == 0)
1798             *err = file_error(wth->fh, err_info);
1799         return FALSE;    /* failure */
1800     }
1801
1802     /*
1803      * It makes no sense for the captured data length to be bigger
1804      * than the actual data length.
1805      */
1806     if (wth->phdr.caplen > wth->phdr.len)
1807         wth->phdr.caplen = wth->phdr.len;
1808
1809     /*
1810      * Make sure that it's not WTAP_ENCAP_PER_PACKET, as that
1811      * probably means the file has that encapsulation type
1812      * but the read routine didn't set this packet's
1813      * encapsulation type.
1814      */
1815     g_assert(wth->phdr.pkt_encap != WTAP_ENCAP_PER_PACKET);
1816 #endif
1817
1818     return TRUE; /* success */
1819 }
1820
1821 static int
1822 load_cap_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
1823 {
1824   guint32      framenum;
1825   int          err;
1826   gchar       *err_info = NULL;
1827   gint64       data_offset = 0;
1828   gboolean     filtering_tap_listeners;
1829   guint        tap_flags;
1830   Buffer       buf;
1831   epan_dissect_t *edt = NULL;
1832   struct wtap_pkthdr file_phdr;
1833   guint8* raw_data;
1834
1835   if (print_packet_info) {
1836     if (!write_preamble(cf)) {
1837       err = errno;
1838       show_print_file_io_error(err);
1839       goto out;
1840     }
1841   }
1842
1843   /* Do we have any tap listeners with filters? */
1844   filtering_tap_listeners = have_filtering_tap_listeners();
1845
1846   /* Get the union of the flags for all tap listeners. */
1847   tap_flags = union_of_tap_listener_flags();
1848
1849   wtap_phdr_init(&file_phdr);
1850
1851   /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1852   file_phdr.pkt_encap = 1234;
1853
1854   if (perform_two_pass_analysis) {
1855     frame_data *fdata;
1856
1857     /* Allocate a frame_data_sequence for all the frames. */
1858     cf->frames = new_frame_data_sequence();
1859
1860     if (do_dissection) {
1861        gboolean create_proto_tree = FALSE;
1862
1863       /* If we're going to be applying a filter, we'll need to
1864          create a protocol tree against which to apply the filter. */
1865       if (cf->rfcode)
1866         create_proto_tree = TRUE;
1867
1868       /* We're not going to display the protocol tree on this pass,
1869          so it's not going to be "visible". */
1870       edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
1871     }
1872     while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1873       if (process_packet_first_pass(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1874                          wtap_buf_ptr(cf->wth))) {
1875
1876         /* Stop reading if we have the maximum number of packets;
1877          * When the -c option has not been used, max_packet_count
1878          * starts at 0, which practically means, never stop reading.
1879          * (unless we roll over max_packet_count ?)
1880          */
1881         if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1882           err = 0; /* This is not an error */
1883           break;
1884         }
1885       }
1886     }
1887
1888     if (edt) {
1889       epan_dissect_free(edt);
1890       edt = NULL;
1891     }
1892
1893 #if 0
1894     /* Close the sequential I/O side, to free up memory it requires. */
1895     wtap_sequential_close(cf->wth);
1896 #endif
1897
1898     /* Allow the protocol dissectors to free up memory that they
1899      * don't need after the sequential run-through of the packets. */
1900     postseq_cleanup_all_protocols();
1901
1902     prev_dis = NULL;
1903     prev_cap = NULL;
1904     ws_buffer_init(&buf, 1500);
1905
1906     if (do_dissection) {
1907       gboolean create_proto_tree;
1908
1909       if (cf->dfcode || print_details || filtering_tap_listeners ||
1910          (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo))
1911            create_proto_tree = TRUE;
1912       else
1913            create_proto_tree = FALSE;
1914
1915       /* The protocol tree will be "visible", i.e., printed, only if we're
1916          printing packet details, which is true if we're printing stuff
1917          ("print_packet_info" is true) and we're in verbose mode
1918          ("packet_details" is true). */
1919       edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1920     }
1921
1922     for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
1923       fdata = frame_data_sequence_find(cf->frames, framenum);
1924 #if 0
1925       if (wtap_seek_read(cf->wth, fdata->file_off,
1926           &buf, fdata->cap_len, &err, &err_info)) {
1927         process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1928       }
1929 #else
1930         process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1931 #endif
1932     }
1933
1934     if (edt) {
1935       epan_dissect_free(edt);
1936       edt = NULL;
1937     }
1938
1939     ws_buffer_free(&buf);
1940   }
1941   else {
1942     framenum = 0;
1943
1944     if (do_dissection) {
1945       gboolean create_proto_tree;
1946
1947       if (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
1948           (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo))
1949         create_proto_tree = TRUE;
1950       else
1951         create_proto_tree = FALSE;
1952
1953       /* The protocol tree will be "visible", i.e., printed, only if we're
1954          printing packet details, which is true if we're printing stuff
1955          ("print_packet_info" is true) and we're in verbose mode
1956          ("packet_details" is true). */
1957       edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1958     }
1959
1960     while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1961
1962       framenum++;
1963
1964       process_packet(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1965                              raw_data, tap_flags);
1966
1967         /* Stop reading if we have the maximum number of packets;
1968         * When the -c option has not been used, max_packet_count
1969         * starts at 0, which practically means, never stop reading.
1970         * (unless we roll over max_packet_count ?)
1971         */
1972         if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1973             err = 0; /* This is not an error */
1974             break;
1975         }
1976     }
1977
1978     if (edt) {
1979       epan_dissect_free(edt);
1980       edt = NULL;
1981     }
1982   }
1983
1984   wtap_phdr_cleanup(&file_phdr);
1985
1986   if (err != 0) {
1987     /*
1988      * Print a message noting that the read failed somewhere along the line.
1989      *
1990      * If we're printing packet data, and the standard output and error are
1991      * going to the same place, flush the standard output, so everything
1992      * buffered up is written, and then print a newline to the standard error
1993      * before printing the error message, to separate it from the packet
1994      * data.  (Alas, that only works on UN*X; st_dev is meaningless, and
1995      * the _fstat() documentation at Microsoft doesn't indicate whether
1996      * st_ino is even supported.)
1997      */
1998 #ifndef _WIN32
1999     if (print_packet_info) {
2000       ws_statb64 stat_stdout, stat_stderr;
2001
2002       if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
2003         if (stat_stdout.st_dev == stat_stderr.st_dev &&
2004             stat_stdout.st_ino == stat_stderr.st_ino) {
2005           fflush(stdout);
2006           fprintf(stderr, "\n");
2007         }
2008       }
2009     }
2010 #endif
2011 #if 0
2012     switch (err) {
2013
2014     case FTAP_ERR_UNSUPPORTED:
2015       cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
2016                  cf->filename, err_info);
2017       g_free(err_info);
2018       break;
2019
2020     case FTAP_ERR_UNSUPPORTED_ENCAP:
2021       cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
2022                  cf->filename, err_info);
2023       g_free(err_info);
2024       break;
2025
2026     case FTAP_ERR_CANT_READ:
2027       cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
2028                  cf->filename);
2029       break;
2030
2031     case FTAP_ERR_SHORT_READ:
2032       cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
2033                  cf->filename);
2034       break;
2035
2036     case FTAP_ERR_BAD_FILE:
2037       cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
2038                  cf->filename, err_info);
2039       g_free(err_info);
2040       break;
2041
2042     case FTAP_ERR_DECOMPRESS:
2043       cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
2044                  "(%s)", cf->filename, err_info);
2045       break;
2046
2047     default:
2048       cmdarg_err("An error occurred while reading the file \"%s\": %s.",
2049                  cf->filename, ftap_strerror(err));
2050       break;
2051     }
2052 #endif
2053   } else {
2054     if (print_packet_info) {
2055       if (!write_finale()) {
2056         err = errno;
2057         show_print_file_io_error(err);
2058       }
2059     }
2060   }
2061
2062 out:
2063   wtap_close(cf->wth);
2064   cf->wth = NULL;
2065
2066   return err;
2067 }
2068
2069 static gboolean
2070 process_packet(capture_file *cf, epan_dissect_t *edt, gint64 offset,
2071                struct wtap_pkthdr *whdr, const guchar *pd, guint tap_flags)
2072 {
2073   frame_data      fdata;
2074   column_info    *cinfo;
2075   gboolean        passed;
2076
2077   /* Count this packet. */
2078   cf->count++;
2079
2080   /* If we're not running a display filter and we're not printing any
2081      packet information, we don't need to do a dissection. This means
2082      that all packets can be marked as 'passed'. */
2083   passed = TRUE;
2084
2085   frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
2086
2087   /* If we're going to print packet information, or we're going to
2088      run a read filter, or we're going to process taps, set up to
2089      do a dissection and do so. */
2090   if (edt) {
2091     /* If we're running a filter, prime the epan_dissect_t with that
2092        filter. */
2093     if (cf->dfcode)
2094       epan_dissect_prime_dfilter(edt, cf->dfcode);
2095
2096     col_custom_prime_edt(edt, &cf->cinfo);
2097
2098     /* We only need the columns if either
2099          1) some tap needs the columns
2100        or
2101          2) we're printing packet info but we're *not* verbose; in verbose
2102             mode, we print the protocol tree, not the protocol summary.
2103        or
2104          3) there is a column mapped as an individual field */
2105     if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
2106       cinfo = &cf->cinfo;
2107     else
2108       cinfo = NULL;
2109
2110     frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
2111                                   &ref, prev_dis);
2112     if (ref == &fdata) {
2113       ref_frame = fdata;
2114       ref = &ref_frame;
2115     }
2116
2117     epan_dissect_file_run_with_taps(edt, whdr, frame_tvbuff_new(&fdata, pd), &fdata, cinfo);
2118
2119     /* Run the filter if we have it. */
2120     if (cf->dfcode)
2121       passed = dfilter_apply_edt(cf->dfcode, edt);
2122   }
2123
2124   if (passed) {
2125     frame_data_set_after_dissect(&fdata, &cum_bytes);
2126
2127     /* Process this packet. */
2128     if (print_packet_info) {
2129       /* We're printing packet information; print the information for
2130          this packet. */
2131       print_packet(cf, edt);
2132
2133       /* The ANSI C standard does not appear to *require* that a line-buffered
2134          stream be flushed to the host environment whenever a newline is
2135          written, it just says that, on such a stream, characters "are
2136          intended to be transmitted to or from the host environment as a
2137          block when a new-line character is encountered".
2138
2139          The Visual C++ 6.0 C implementation doesn't do what is intended;
2140          even if you set a stream to be line-buffered, it still doesn't
2141          flush the buffer at the end of every line.
2142
2143          So, if the "-l" flag was specified, we flush the standard output
2144          at the end of a packet.  This will do the right thing if we're
2145          printing packet summary lines, and, as we print the entire protocol
2146          tree for a single packet without waiting for anything to happen,
2147          it should be as good as line-buffered mode if we're printing
2148          protocol trees.  (The whole reason for the "-l" flag in either
2149          tcpdump or TShark is to allow the output of a live capture to
2150          be piped to a program or script and to have that script see the
2151          information for the packet as soon as it's printed, rather than
2152          having to wait until a standard I/O buffer fills up. */
2153       if (line_buffered)
2154         fflush(stdout);
2155
2156       if (ferror(stdout)) {
2157         show_print_file_io_error(errno);
2158         exit(2);
2159       }
2160     }
2161
2162     /* this must be set after print_packet() [bug #8160] */
2163     prev_dis_frame = fdata;
2164     prev_dis = &prev_dis_frame;
2165   }
2166
2167   prev_cap_frame = fdata;
2168   prev_cap = &prev_cap_frame;
2169
2170   if (edt) {
2171     epan_dissect_reset(edt);
2172     frame_data_destroy(&fdata);
2173   }
2174   return passed;
2175 }
2176
2177 static gboolean
2178 write_preamble(capture_file *cf)
2179 {
2180   switch (output_action) {
2181
2182   case WRITE_TEXT:
2183     return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
2184
2185   case WRITE_XML:
2186     if (print_details)
2187       write_pdml_preamble(stdout, cf->filename);
2188     else
2189       write_psml_preamble(&cf->cinfo, stdout);
2190     return !ferror(stdout);
2191
2192   case WRITE_FIELDS:
2193     write_fields_preamble(output_fields, stdout);
2194     return !ferror(stdout);
2195
2196   default:
2197     g_assert_not_reached();
2198     return FALSE;
2199   }
2200 }
2201
2202 static char *
2203 get_line_buf(size_t len)
2204 {
2205   static char   *line_bufp    = NULL;
2206   static size_t  line_buf_len = 256;
2207   size_t         new_line_buf_len;
2208
2209   for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
2210        new_line_buf_len *= 2)
2211     ;
2212   if (line_bufp == NULL) {
2213     line_buf_len = new_line_buf_len;
2214     line_bufp = (char *)g_malloc(line_buf_len + 1);
2215   } else {
2216     if (new_line_buf_len > line_buf_len) {
2217       line_buf_len = new_line_buf_len;
2218       line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
2219     }
2220   }
2221   return line_bufp;
2222 }
2223
2224 static inline void
2225 put_string(char *dest, const char *str, size_t str_len)
2226 {
2227   memcpy(dest, str, str_len);
2228   dest[str_len] = '\0';
2229 }
2230
2231 static inline void
2232 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
2233 {
2234   size_t i;
2235
2236   for (i = str_len; i < str_with_spaces; i++)
2237     *dest++ = ' ';
2238
2239   put_string(dest, str, str_len);
2240 }
2241
2242 static inline void
2243 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
2244 {
2245   size_t i;
2246
2247   memcpy(dest, str, str_len);
2248   for (i = str_len; i < str_with_spaces; i++)
2249     dest[i] = ' ';
2250
2251   dest[str_with_spaces] = '\0';
2252 }
2253
2254 static gboolean
2255 print_columns(capture_file *cf)
2256 {
2257   char   *line_bufp;
2258   int     i;
2259   size_t  buf_offset;
2260   size_t  column_len;
2261   size_t  col_len;
2262   col_item_t* col_item;
2263
2264   line_bufp = get_line_buf(256);
2265   buf_offset = 0;
2266   *line_bufp = '\0';
2267   for (i = 0; i < cf->cinfo.num_cols; i++) {
2268     col_item = &cf->cinfo.columns[i];
2269     /* Skip columns not marked as visible. */
2270     if (!get_column_visible(i))
2271       continue;
2272     switch (col_item->col_fmt) {
2273     case COL_NUMBER:
2274       column_len = col_len = strlen(col_item->col_data);
2275       if (column_len < 3)
2276         column_len = 3;
2277       line_bufp = get_line_buf(buf_offset + column_len);
2278       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
2279       break;
2280
2281     case COL_CLS_TIME:
2282     case COL_REL_TIME:
2283     case COL_ABS_TIME:
2284     case COL_ABS_YMD_TIME:  /* XXX - wider */
2285     case COL_ABS_YDOY_TIME: /* XXX - wider */
2286     case COL_UTC_TIME:
2287     case COL_UTC_YMD_TIME:  /* XXX - wider */
2288     case COL_UTC_YDOY_TIME: /* XXX - wider */
2289       column_len = col_len = strlen(col_item->col_data);
2290       if (column_len < 10)
2291         column_len = 10;
2292       line_bufp = get_line_buf(buf_offset + column_len);
2293       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
2294       break;
2295
2296     case COL_DEF_SRC:
2297     case COL_RES_SRC:
2298     case COL_UNRES_SRC:
2299     case COL_DEF_DL_SRC:
2300     case COL_RES_DL_SRC:
2301     case COL_UNRES_DL_SRC:
2302     case COL_DEF_NET_SRC:
2303     case COL_RES_NET_SRC:
2304     case COL_UNRES_NET_SRC:
2305       column_len = col_len = strlen(col_item->col_data);
2306       if (column_len < 12)
2307         column_len = 12;
2308       line_bufp = get_line_buf(buf_offset + column_len);
2309       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
2310       break;
2311
2312     case COL_DEF_DST:
2313     case COL_RES_DST:
2314     case COL_UNRES_DST:
2315     case COL_DEF_DL_DST:
2316     case COL_RES_DL_DST:
2317     case COL_UNRES_DL_DST:
2318     case COL_DEF_NET_DST:
2319     case COL_RES_NET_DST:
2320     case COL_UNRES_NET_DST:
2321       column_len = col_len = strlen(col_item->col_data);
2322       if (column_len < 12)
2323         column_len = 12;
2324       line_bufp = get_line_buf(buf_offset + column_len);
2325       put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
2326       break;
2327
2328     default:
2329       column_len = strlen(col_item->col_data);
2330       line_bufp = get_line_buf(buf_offset + column_len);
2331       put_string(line_bufp + buf_offset, col_item->col_data, column_len);
2332       break;
2333     }
2334     buf_offset += column_len;
2335     if (i != cf->cinfo.num_cols - 1) {
2336       /*
2337        * This isn't the last column, so we need to print a
2338        * separator between this column and the next.
2339        *
2340        * If we printed a network source and are printing a
2341        * network destination of the same type next, separate
2342        * them with " -> "; if we printed a network destination
2343        * and are printing a network source of the same type
2344        * next, separate them with " <- "; otherwise separate them
2345        * with a space.
2346        *
2347        * We add enough space to the buffer for " <- " or " -> ",
2348        * even if we're only adding " ".
2349        */
2350       line_bufp = get_line_buf(buf_offset + 4);
2351       switch (col_item->col_fmt) {
2352
2353       case COL_DEF_SRC:
2354       case COL_RES_SRC:
2355       case COL_UNRES_SRC:
2356         switch (cf->cinfo.columns[i+1].col_fmt) {
2357
2358         case COL_DEF_DST:
2359         case COL_RES_DST:
2360         case COL_UNRES_DST:
2361           put_string(line_bufp + buf_offset, " -> ", 4);
2362           buf_offset += 4;
2363           break;
2364
2365         default:
2366           put_string(line_bufp + buf_offset, " ", 1);
2367           buf_offset += 1;
2368           break;
2369         }
2370         break;
2371
2372       case COL_DEF_DL_SRC:
2373       case COL_RES_DL_SRC:
2374       case COL_UNRES_DL_SRC:
2375         switch (cf->cinfo.columns[i+1].col_fmt) {
2376
2377         case COL_DEF_DL_DST:
2378         case COL_RES_DL_DST:
2379         case COL_UNRES_DL_DST:
2380           put_string(line_bufp + buf_offset, " -> ", 4);
2381           buf_offset += 4;
2382           break;
2383
2384         default:
2385           put_string(line_bufp + buf_offset, " ", 1);
2386           buf_offset += 1;
2387           break;
2388         }
2389         break;
2390
2391       case COL_DEF_NET_SRC:
2392       case COL_RES_NET_SRC:
2393       case COL_UNRES_NET_SRC:
2394         switch (cf->cinfo.columns[i+1].col_fmt) {
2395
2396         case COL_DEF_NET_DST:
2397         case COL_RES_NET_DST:
2398         case COL_UNRES_NET_DST:
2399           put_string(line_bufp + buf_offset, " -> ", 4);
2400           buf_offset += 4;
2401           break;
2402
2403         default:
2404           put_string(line_bufp + buf_offset, " ", 1);
2405           buf_offset += 1;
2406           break;
2407         }
2408         break;
2409
2410       case COL_DEF_DST:
2411       case COL_RES_DST:
2412       case COL_UNRES_DST:
2413         switch (cf->cinfo.columns[i+1].col_fmt) {
2414
2415         case COL_DEF_SRC:
2416         case COL_RES_SRC:
2417         case COL_UNRES_SRC:
2418           put_string(line_bufp + buf_offset, " <- ", 4);
2419           buf_offset += 4;
2420           break;
2421
2422         default:
2423           put_string(line_bufp + buf_offset, " ", 1);
2424           buf_offset += 1;
2425           break;
2426         }
2427         break;
2428
2429       case COL_DEF_DL_DST:
2430       case COL_RES_DL_DST:
2431       case COL_UNRES_DL_DST:
2432         switch (cf->cinfo.columns[i+1].col_fmt) {
2433
2434         case COL_DEF_DL_SRC:
2435         case COL_RES_DL_SRC:
2436         case COL_UNRES_DL_SRC:
2437           put_string(line_bufp + buf_offset, " <- ", 4);
2438           buf_offset += 4;
2439           break;
2440
2441         default:
2442           put_string(line_bufp + buf_offset, " ", 1);
2443           buf_offset += 1;
2444           break;
2445         }
2446         break;
2447
2448       case COL_DEF_NET_DST:
2449       case COL_RES_NET_DST:
2450       case COL_UNRES_NET_DST:
2451         switch (cf->cinfo.columns[i+1].col_fmt) {
2452
2453         case COL_DEF_NET_SRC:
2454         case COL_RES_NET_SRC:
2455         case COL_UNRES_NET_SRC:
2456           put_string(line_bufp + buf_offset, " <- ", 4);
2457           buf_offset += 4;
2458           break;
2459
2460         default:
2461           put_string(line_bufp + buf_offset, " ", 1);
2462           buf_offset += 1;
2463           break;
2464         }
2465         break;
2466
2467       default:
2468         put_string(line_bufp + buf_offset, " ", 1);
2469         buf_offset += 1;
2470         break;
2471       }
2472     }
2473   }
2474   return print_line(print_stream, 0, line_bufp);
2475 }
2476
2477 static gboolean
2478 print_packet(capture_file *cf, epan_dissect_t *edt)
2479 {
2480   print_args_t print_args;
2481
2482   if (print_summary || output_fields_has_cols(output_fields)) {
2483     /* Just fill in the columns. */
2484     epan_dissect_fill_in_columns(edt, FALSE, TRUE);
2485
2486     if (print_summary) {
2487       /* Now print them. */
2488       switch (output_action) {
2489
2490       case WRITE_TEXT:
2491         if (!print_columns(cf))
2492           return FALSE;
2493         break;
2494
2495       case WRITE_XML:
2496         write_psml_columns(edt, stdout);
2497         return !ferror(stdout);
2498       case WRITE_FIELDS: /*No non-verbose "fields" format */
2499         g_assert_not_reached();
2500         break;
2501       }
2502     }
2503   }
2504   if (print_details) {
2505     /* Print the information in the protocol tree. */
2506     switch (output_action) {
2507
2508     case WRITE_TEXT:
2509       /* Only initialize the fields that are actually used in proto_tree_print.
2510        * This is particularly important for .range, as that's heap memory which
2511        * we would otherwise have to g_free().
2512       print_args.to_file = TRUE;
2513       print_args.format = print_format;
2514       print_args.print_summary = print_summary;
2515       print_args.print_formfeed = FALSE;
2516       packet_range_init(&print_args.range, &cfile);
2517       */
2518       print_args.print_hex = print_hex;
2519       print_args.print_dissections = print_details ? print_dissections_expanded : print_dissections_none;
2520
2521       if (!proto_tree_print(&print_args, edt, output_only_tables, print_stream))
2522         return FALSE;
2523       if (!print_hex) {
2524         if (!print_line(print_stream, 0, separator))
2525           return FALSE;
2526       }
2527       break;
2528
2529     case WRITE_XML:
2530       write_pdml_proto_tree(edt, stdout);
2531       printf("\n");
2532       return !ferror(stdout);
2533     case WRITE_FIELDS:
2534       write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
2535       printf("\n");
2536       return !ferror(stdout);
2537     }
2538   }
2539   if (print_hex) {
2540     if (print_summary || print_details) {
2541       if (!print_line(print_stream, 0, ""))
2542         return FALSE;
2543     }
2544     if (!print_hex_data(print_stream, edt))
2545       return FALSE;
2546     if (!print_line(print_stream, 0, separator))
2547       return FALSE;
2548   }
2549   return TRUE;
2550 }
2551
2552 static gboolean
2553 write_finale(void)
2554 {
2555   switch (output_action) {
2556
2557   case WRITE_TEXT:
2558     return print_finale(print_stream);
2559
2560   case WRITE_XML:
2561     if (print_details)
2562       write_pdml_finale(stdout);
2563     else
2564       write_psml_finale(stdout);
2565     return !ferror(stdout);
2566
2567   case WRITE_FIELDS:
2568     write_fields_finale(output_fields, stdout);
2569     return !ferror(stdout);
2570
2571   default:
2572     g_assert_not_reached();
2573     return FALSE;
2574   }
2575 }
2576
2577 cf_status_t
2578 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
2579 {
2580   gchar *err_info;
2581   char   err_msg[2048+1];
2582
2583   /* The open isn't implemented yet.  Fill in the information for this file. */
2584
2585   /* Create new epan session for dissection. */
2586   epan_free(cf->epan);
2587   cf->epan = tfshark_epan_new(cf);
2588
2589   cf->wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2590   cf->f_datalen = 0; /* not used, but set it anyway */
2591
2592   /* Set the file name because we need it to set the follow stream filter.
2593      XXX - is that still true?  We need it for other reasons, though,
2594      in any case. */
2595   cf->filename = g_strdup(fname);
2596
2597   /* Indicate whether it's a permanent or temporary file. */
2598   cf->is_tempfile = is_tempfile;
2599
2600   /* No user changes yet. */
2601   cf->unsaved_changes = FALSE;
2602
2603   cf->cd_t      = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2604   cf->open_type = type;
2605   cf->count     = 0;
2606   cf->drops_known = FALSE;
2607   cf->drops     = 0;
2608   cf->snap      = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2609   if (cf->snap == 0) {
2610     /* Snapshot length not known. */
2611     cf->has_snap = FALSE;
2612     cf->snap = 0;
2613   } else
2614     cf->has_snap = TRUE;
2615   nstime_set_zero(&cf->elapsed_time);
2616   ref = NULL;
2617   prev_dis = NULL;
2618   prev_cap = NULL;
2619
2620   cf->state = FILE_READ_IN_PROGRESS;
2621
2622   return CF_OK;
2623
2624 /* fail: */
2625   g_snprintf(err_msg, sizeof err_msg,
2626              cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
2627   cmdarg_err("%s", err_msg);
2628   return CF_ERROR;
2629 }
2630
2631 static void
2632 show_print_file_io_error(int err)
2633 {
2634   switch (err) {
2635
2636   case ENOSPC:
2637     cmdarg_err("Not all the packets could be printed because there is "
2638 "no space left on the file system.");
2639     break;
2640
2641 #ifdef EDQUOT
2642   case EDQUOT:
2643     cmdarg_err("Not all the packets could be printed because you are "
2644 "too close to, or over your disk quota.");
2645   break;
2646 #endif
2647
2648   default:
2649     cmdarg_err("An error occurred while printing packets: %s.",
2650       g_strerror(err));
2651     break;
2652   }
2653 }
2654
2655 static const char *
2656 cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
2657                       int file_type _U_)
2658 {
2659   const char *errmsg;
2660   /* static char errmsg_errno[1024+1]; */
2661
2662 #if 0
2663   if (err < 0) {
2664     /* Wiretap error. */
2665     switch (err) {
2666
2667     case FTAP_ERR_NOT_REGULAR_FILE:
2668       errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
2669       break;
2670
2671     case FTAP_ERR_RANDOM_OPEN_PIPE:
2672       /* Seen only when opening a capture file for reading. */
2673       errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
2674       break;
2675
2676     case FTAP_ERR_FILE_UNKNOWN_FORMAT:
2677       /* Seen only when opening a capture file for reading. */
2678       errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
2679       break;
2680
2681     case FTAP_ERR_UNSUPPORTED:
2682       /* Seen only when opening a capture file for reading. */
2683       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2684                "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
2685                "(%s)", err_info);
2686       g_free(err_info);
2687       errmsg = errmsg_errno;
2688       break;
2689
2690     case FTAP_ERR_CANT_WRITE_TO_PIPE:
2691       /* Seen only when opening a capture file for writing. */
2692       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2693                  "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
2694                  "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
2695       errmsg = errmsg_errno;
2696       break;
2697
2698     case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
2699       /* Seen only when opening a capture file for writing. */
2700       errmsg = "TFShark doesn't support writing capture files in that format.";
2701       break;
2702
2703     case FTAP_ERR_UNSUPPORTED_ENCAP:
2704       if (for_writing) {
2705         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2706                    "TFShark can't save this capture as a \"%s\" file.",
2707                    ftap_file_type_subtype_short_string(file_type));
2708       } else {
2709         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2710                  "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
2711                  "(%s)", err_info);
2712         g_free(err_info);
2713       }
2714       errmsg = errmsg_errno;
2715       break;
2716
2717     case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
2718       if (for_writing) {
2719         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2720                    "TFShark can't save this capture as a \"%s\" file.",
2721                    ftap_file_type_subtype_short_string(file_type));
2722         errmsg = errmsg_errno;
2723       } else
2724         errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
2725       break;
2726
2727     case FTAP_ERR_BAD_FILE:
2728       /* Seen only when opening a capture file for reading. */
2729       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2730                "The file \"%%s\" appears to be damaged or corrupt.\n"
2731                "(%s)", err_info);
2732       g_free(err_info);
2733       errmsg = errmsg_errno;
2734       break;
2735
2736     case FTAP_ERR_CANT_OPEN:
2737       if (for_writing)
2738         errmsg = "The file \"%s\" could not be created for some unknown reason.";
2739       else
2740         errmsg = "The file \"%s\" could not be opened for some unknown reason.";
2741       break;
2742
2743     case FTAP_ERR_SHORT_READ:
2744       errmsg = "The file \"%s\" appears to have been cut short"
2745                " in the middle of a packet or other data.";
2746       break;
2747
2748     case FTAP_ERR_SHORT_WRITE:
2749       errmsg = "A full header couldn't be written to the file \"%s\".";
2750       break;
2751
2752     case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
2753       errmsg = "This file type cannot be written as a compressed file.";
2754       break;
2755
2756     case FTAP_ERR_DECOMPRESS:
2757       /* Seen only when opening a capture file for reading. */
2758       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2759                  "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
2760                  "(%s)", err_info);
2761       g_free(err_info);
2762       errmsg = errmsg_errno;
2763       break;
2764
2765     default:
2766       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2767                  "The file \"%%s\" could not be %s: %s.",
2768                  for_writing ? "created" : "opened",
2769                  ftap_strerror(err));
2770       errmsg = errmsg_errno;
2771       break;
2772     }
2773   } else
2774 #endif
2775     errmsg = file_open_error_message(err, for_writing);
2776   return errmsg;
2777 }
2778
2779 /*
2780  * Open/create errors are reported with an console message in TFShark.
2781  */
2782 static void
2783 open_failure_message(const char *filename, int err, gboolean for_writing)
2784 {
2785   fprintf(stderr, "tfshark: ");
2786   fprintf(stderr, file_open_error_message(err, for_writing), filename);
2787   fprintf(stderr, "\n");
2788 }
2789
2790
2791 /*
2792  * General errors are reported with an console message in TFShark.
2793  */
2794 static void
2795 failure_message(const char *msg_format, va_list ap)
2796 {
2797   fprintf(stderr, "tfshark: ");
2798   vfprintf(stderr, msg_format, ap);
2799   fprintf(stderr, "\n");
2800 }
2801
2802 /*
2803  * Read errors are reported with an console message in TFShark.
2804  */
2805 static void
2806 read_failure_message(const char *filename, int err)
2807 {
2808   cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
2809           filename, g_strerror(err));
2810 }
2811
2812 /*
2813  * Write errors are reported with an console message in TFShark.
2814  */
2815 static void
2816 write_failure_message(const char *filename, int err)
2817 {
2818   cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
2819           filename, g_strerror(err));
2820 }
2821
2822 /*
2823  * Report additional information for an error in command-line arguments.
2824  */
2825 static void
2826 failure_message_cont(const char *msg_format, va_list ap)
2827 {
2828   vfprintf(stderr, msg_format, ap);
2829   fprintf(stderr, "\n");
2830 }
2831
2832 /*
2833  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2834  *
2835  * Local variables:
2836  * c-basic-offset: 2
2837  * tab-width: 8
2838  * indent-tabs-mode: nil
2839  * End:
2840  *
2841  * vi: set shiftwidth=2 tabstop=8 expandtab:
2842  * :indentSize=2:tabSize=8:noTabs=true:
2843  */