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