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