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