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