pkinit: pass kerberos_is_win2k_pkinit() over actx boundaries
[wireshark-sm.git] / tshark.c
blob2c77edfee8b4c2dfe33047fb2e41baad15ebaf30
1 /* tshark.c
3 * Text-mode variant of Wireshark, along the lines of tcpdump and snoop,
4 * by Gilbert Ramirez <gram@alumni.rice.edu> and Guy Harris <guy@alum.mit.edu>.
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include <config.h>
15 #define WS_LOG_DOMAIN LOG_DOMAIN_MAIN
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <locale.h>
21 #include <limits.h>
23 #include <wsutil/ws_getopt.h>
25 #include <errno.h>
27 #ifdef _WIN32
28 # include <winsock2.h>
29 #endif
31 #ifndef _WIN32
32 #include <signal.h>
33 #endif
35 #include <glib.h>
37 #include <epan/exceptions.h>
38 #include <epan/epan.h>
40 #include <ws_exit_codes.h>
41 #include <wsutil/clopts_common.h>
42 #include <wsutil/cmdarg_err.h>
43 #include <ui/urls.h>
44 #include <wsutil/filesystem.h>
45 #include <wsutil/file_util.h>
46 #include <wsutil/time_util.h>
47 #include <wsutil/socket.h>
48 #include <wsutil/privileges.h>
49 #include <wsutil/report_message.h>
50 #include <wsutil/please_report_bug.h>
51 #include <wsutil/wslog.h>
52 #include <wsutil/ws_assert.h>
53 #include <wsutil/strtoi.h>
54 #include <cli_main.h>
55 #include <wsutil/version_info.h>
56 #include <wiretap/wtap_opttypes.h>
58 #include "globals.h"
59 #include <epan/timestamp.h>
60 #include <epan/packet.h>
61 #ifdef HAVE_LUA
62 #include <epan/wslua/init_wslua.h>
63 #endif
64 #include "frame_tvbuff.h"
65 #include <epan/disabled_protos.h>
66 #include <epan/prefs.h>
67 #include <epan/column.h>
68 #include <epan/decode_as.h>
69 #include <epan/print.h>
70 #include <epan/addr_resolv.h>
71 #include <epan/enterprises.h>
72 #include <epan/manuf.h>
73 #include <epan/services.h>
74 #ifdef HAVE_LIBPCAP
75 #include "ui/capture_ui_utils.h"
76 #endif
77 #include "ui/taps.h"
78 #include "ui/util.h"
79 #include "ui/ws_ui_util.h"
80 #include "ui/decode_as_utils.h"
81 #include "wsutil/filter_files.h"
82 #include "ui/cli/tshark-tap.h"
83 #include "ui/cli/tap-exportobject.h"
84 #include "ui/tap_export_pdu.h"
85 #include "ui/dissect_opts.h"
86 #include "ui/ssl_key_export.h"
87 #include "ui/failure_message.h"
88 #if defined(HAVE_LIBSMI)
89 #include "epan/oids.h"
90 #endif
91 #include "epan/maxmind_db.h"
92 #include <epan/epan_dissect.h>
93 #include <epan/tap.h>
94 #include <epan/stat_tap_ui.h>
95 #include <epan/conversation_table.h>
96 #include <epan/srt_table.h>
97 #include <epan/rtd_table.h>
98 #include <epan/ex-opt.h>
99 #include <epan/exported_pdu.h>
100 #include <epan/secrets.h>
102 #include "capture_opts.h"
104 #include "capture/capture-pcap-util.h"
106 #ifdef HAVE_LIBPCAP
107 #include "capture/capture_ifinfo.h"
108 #ifdef _WIN32
109 #include "capture/capture-wpcap.h"
110 #endif /* _WIN32 */
111 #include <capture/capture_session.h>
112 #include <capture/capture_sync.h>
113 #include <ui/capture_info.h>
114 #endif /* HAVE_LIBPCAP */
115 #include <epan/funnel.h>
117 #include <wsutil/str_util.h>
118 #include <wsutil/utf8_entities.h>
119 #include <wsutil/json_dumper.h>
120 #include <wsutil/wslog.h>
121 #ifdef _WIN32
122 #include <wsutil/win32-utils.h>
123 #endif
125 #include "extcap.h"
127 #ifdef HAVE_PLUGINS
128 #include <wsutil/codecs_priv.h>
129 #include <wsutil/plugins.h>
130 #endif
132 /* Additional exit codes */
133 #define INVALID_EXPORT 2
134 #define INVALID_TAP 2
135 #define INVALID_CAPTURE 2
137 #define LONGOPT_EXPORT_OBJECTS LONGOPT_BASE_APPLICATION+1
138 #define LONGOPT_COLOR LONGOPT_BASE_APPLICATION+2
139 #define LONGOPT_NO_DUPLICATE_KEYS LONGOPT_BASE_APPLICATION+3
140 #define LONGOPT_ELASTIC_MAPPING_FILTER LONGOPT_BASE_APPLICATION+4
141 #define LONGOPT_EXPORT_TLS_SESSION_KEYS LONGOPT_BASE_APPLICATION+5
142 #define LONGOPT_CAPTURE_COMMENT LONGOPT_BASE_APPLICATION+6
143 #define LONGOPT_HEXDUMP LONGOPT_BASE_APPLICATION+7
144 #define LONGOPT_SELECTED_FRAME LONGOPT_BASE_APPLICATION+8
145 #define LONGOPT_PRINT_TIMERS LONGOPT_BASE_APPLICATION+9
147 capture_file cfile;
149 static guint32 cum_bytes;
150 static frame_data ref_frame;
151 static frame_data prev_dis_frame;
152 static frame_data prev_cap_frame;
154 static gboolean perform_two_pass_analysis;
155 static guint32 epan_auto_reset_count = 0;
156 static gboolean epan_auto_reset = FALSE;
158 static guint32 selected_frame_number = 0;
161 * The way the packet decode is to be written.
163 typedef enum {
164 WRITE_NONE, /* dummy initial state */
165 WRITE_TEXT, /* summary or detail text */
166 WRITE_XML, /* PDML or PSML */
167 WRITE_FIELDS, /* User defined list of fields */
168 WRITE_JSON, /* JSON */
169 WRITE_JSON_RAW, /* JSON only raw hex */
170 WRITE_EK /* JSON bulk insert to Elasticsearch */
171 /* Add CSV and the like here */
172 } output_action_e;
174 static output_action_e output_action;
175 static gboolean do_dissection; /* TRUE if we have to dissect each packet */
176 static gboolean print_packet_info; /* TRUE if we're to print packet information */
177 static gboolean print_summary; /* TRUE if we're to print packet summary information */
178 static gboolean print_details; /* TRUE if we're to print packet details information */
179 static gboolean print_hex; /* TRUE if we're to print hex/ascii information */
180 static gboolean line_buffered;
181 static gboolean quiet = FALSE;
182 static gboolean really_quiet = FALSE;
183 static gchar* delimiter_char = " ";
184 static gboolean dissect_color = FALSE;
185 static guint hexdump_source_option = HEXDUMP_SOURCE_MULTI; /* Default - Enable legacy multi-source mode */
186 static guint hexdump_ascii_option = HEXDUMP_ASCII_INCLUDE; /* Default - Enable legacy undelimited ASCII dump */
188 static print_format_e print_format = PR_FMT_TEXT;
189 static print_stream_t *print_stream = NULL;
191 static char *output_file_name;
193 static output_fields_t* output_fields = NULL;
195 static gboolean no_duplicate_keys = FALSE;
196 static proto_node_children_grouper_func node_children_grouper = proto_node_group_children_by_unique;
198 static json_dumper jdumper;
200 /* The line separator used between packets, changeable via the -S option */
201 static const char *separator = "";
203 /* Per-file comments to be added to the output file. */
204 static GPtrArray *capture_comments = NULL;
206 static gboolean prefs_loaded = FALSE;
208 #ifdef HAVE_LIBPCAP
210 * TRUE if we're to print packet counts to keep track of captured packets.
212 static gboolean print_packet_counts;
214 static capture_options global_capture_opts;
215 static capture_session global_capture_session;
216 static info_data_t global_info_data;
218 #ifdef SIGINFO
219 static gboolean infodelay; /* if TRUE, don't print capture info in SIGINFO handler */
220 static gboolean infoprint; /* if TRUE, print capture info after clearing infodelay */
221 #endif /* SIGINFO */
223 static gboolean capture(void);
224 static bool capture_input_new_file(capture_session *cap_session,
225 gchar *new_file);
226 static void capture_input_new_packets(capture_session *cap_session,
227 int to_read);
228 static void capture_input_drops(capture_session *cap_session, guint32 dropped,
229 const char* interface_name);
230 static void capture_input_error(capture_session *cap_session,
231 char *error_msg, char *secondary_error_msg);
232 static void capture_input_cfilter_error(capture_session *cap_session,
233 guint i, const char *error_message);
234 static void capture_input_closed(capture_session *cap_session, gchar *msg);
236 static void report_counts(void);
237 #ifdef _WIN32
238 static BOOL WINAPI capture_cleanup(DWORD);
239 #else /* _WIN32 */
240 static void capture_cleanup(int);
241 #ifdef SIGINFO
242 static void report_counts_siginfo(int);
243 #endif /* SIGINFO */
244 #endif /* _WIN32 */
245 #endif /* HAVE_LIBPCAP */
247 static void reset_epan_mem(capture_file *cf, epan_dissect_t *edt, gboolean tree, gboolean visual);
249 typedef enum {
250 PROCESS_FILE_SUCCEEDED,
251 PROCESS_FILE_NO_FILE_PROCESSED,
252 PROCESS_FILE_ERROR,
253 PROCESS_FILE_INTERRUPTED
254 } process_file_status_t;
255 static process_file_status_t process_cap_file(capture_file *, char *, int, gboolean, int, gint64, int);
257 static gboolean process_packet_single_pass(capture_file *cf,
258 epan_dissect_t *edt, gint64 offset, wtap_rec *rec, Buffer *buf,
259 guint tap_flags);
260 static void show_print_file_io_error(void);
261 static gboolean write_preamble(capture_file *cf);
262 static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
263 static gboolean write_finale(void);
265 static void tshark_cmdarg_err(const char *msg_format, va_list ap);
266 static void tshark_cmdarg_err_cont(const char *msg_format, va_list ap);
268 static GHashTable *output_only_tables = NULL;
270 static gboolean opt_print_timers = FALSE;
271 struct elapsed_pass_s {
272 gint64 dissect;
273 gint64 dfilter_read;
274 gint64 dfilter_filter;
276 static struct {
277 gint64 dfilter_expand;
278 gint64 dfilter_compile;
279 struct elapsed_pass_s first_pass;
280 gint64 elapsed_first_pass;
281 struct elapsed_pass_s second_pass;
282 gint64 elapsed_second_pass;
284 tshark_elapsed;
286 static void
287 print_elapsed_json(const char *cf_name, const char *dfilter)
289 json_dumper dumper = {
290 .output_file = stderr,
291 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT,
294 if (tshark_elapsed.elapsed_first_pass == 0) {
295 // Should not happen
296 ws_warning("Print timers requested but no timing info provided");
297 return;
300 #define DUMP(name, val) \
301 json_dumper_set_member_name(&dumper, name); \
302 json_dumper_value_anyf(&dumper, "%"PRId64, val)
304 json_dumper_begin_object(&dumper);
305 json_dumper_set_member_name(&dumper, "version");
306 json_dumper_value_string(&dumper, get_ws_vcs_version_info_short());
307 if (cf_name) {
308 json_dumper_set_member_name(&dumper, "path");
309 json_dumper_value_string(&dumper, cf_name);
311 if (dfilter) {
312 json_dumper_set_member_name(&dumper, "filter");
313 json_dumper_value_string(&dumper, dfilter);
315 json_dumper_set_member_name(&dumper, "time_unit");
316 json_dumper_value_string(&dumper, "microseconds");
317 DUMP("elapsed", tshark_elapsed.elapsed_first_pass +
318 tshark_elapsed.elapsed_second_pass);
319 DUMP("dfilter_expand", tshark_elapsed.dfilter_expand);
320 DUMP("dfilter_compile", tshark_elapsed.dfilter_compile);
321 json_dumper_begin_array(&dumper);
322 json_dumper_begin_object(&dumper);
323 DUMP("elapsed", tshark_elapsed.elapsed_first_pass);
324 DUMP("dissect", tshark_elapsed.first_pass.dissect);
325 DUMP("display_filter", tshark_elapsed.first_pass.dfilter_filter);
326 DUMP("read_filter", tshark_elapsed.first_pass.dfilter_read);
327 json_dumper_end_object(&dumper);
328 if (tshark_elapsed.elapsed_second_pass) {
329 json_dumper_begin_object(&dumper);
330 DUMP("elapsed", tshark_elapsed.elapsed_second_pass);
331 DUMP("dissect", tshark_elapsed.second_pass.dissect);
332 DUMP("display_filter", tshark_elapsed.second_pass.dfilter_filter);
333 DUMP("read_filter", tshark_elapsed.second_pass.dfilter_read);
334 json_dumper_end_object(&dumper);
336 json_dumper_end_array(&dumper);
337 json_dumper_end_object(&dumper);
338 json_dumper_finish(&dumper);
341 static void
342 list_capture_types(void)
344 GArray *writable_type_subtypes;
346 fprintf(stderr, "tshark: The available capture file types for the \"-F\" flag are:\n");
347 writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME);
348 for (guint i = 0; i < writable_type_subtypes->len; i++) {
349 int ft = g_array_index(writable_type_subtypes, int, i);
350 fprintf(stderr, " %s - %s\n", wtap_file_type_subtype_name(ft),
351 wtap_file_type_subtype_description(ft));
353 g_array_free(writable_type_subtypes, TRUE);
356 struct string_elem {
357 const char *sstr; /* The short string */
358 const char *lstr; /* The long string */
361 static gint
362 string_compare(gconstpointer a, gconstpointer b)
364 return strcmp(((const struct string_elem *)a)->sstr,
365 ((const struct string_elem *)b)->sstr);
368 static void
369 string_elem_print(gpointer data)
371 fprintf(stderr, " %s - %s\n",
372 ((struct string_elem *)data)->sstr,
373 ((struct string_elem *)data)->lstr);
376 static void
377 list_read_capture_types(void)
379 guint i;
380 size_t num_file_types;
381 struct string_elem *captypes;
382 GSList *list = NULL;
383 const char *magic = "Magic-value-based";
384 const char *heuristic = "Heuristics-based";
386 /* How many readable file types are there? */
387 num_file_types = 0;
388 for (i = 0; open_routines[i].name != NULL; i++)
389 num_file_types++;
390 captypes = g_new(struct string_elem, num_file_types);
392 fprintf(stderr, "tshark: The available read file types for the \"-X read_format:\" option are:\n");
393 for (i = 0; i < num_file_types && open_routines[i].name != NULL; i++) {
394 captypes[i].sstr = open_routines[i].name;
395 captypes[i].lstr = (open_routines[i].type == OPEN_INFO_MAGIC) ? magic : heuristic;
396 list = g_slist_insert_sorted(list, &captypes[i], string_compare);
398 g_slist_free_full(list, string_elem_print);
399 g_free(captypes);
402 static void
403 list_export_pdu_taps(void)
405 fprintf(stderr, "tshark: The available export tap names and the encapsulation types they produce for the \"-U tap_name\" option are:\n");
406 for (GSList *export_pdu_tap_name_list = get_export_pdu_tap_list();
407 export_pdu_tap_name_list != NULL;
408 export_pdu_tap_name_list = g_slist_next(export_pdu_tap_name_list)) {
409 fprintf(stderr, " %s - %s\n", (const char*)(export_pdu_tap_name_list->data), wtap_encap_description(export_pdu_tap_get_encap((const char*)export_pdu_tap_name_list->data)));
413 static void
414 print_usage(FILE *output)
416 fprintf(output, "\n");
417 fprintf(output, "Usage: tshark [options] ...\n");
418 fprintf(output, "\n");
420 #ifdef HAVE_LIBPCAP
421 fprintf(output, "Capture interface:\n");
422 fprintf(output, " -i <interface>, --interface <interface>\n");
423 fprintf(output, " name or idx of interface (def: first non-loopback)\n");
424 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
425 fprintf(output, " -s <snaplen>, --snapshot-length <snaplen>\n");
426 #ifdef HAVE_PCAP_CREATE
427 fprintf(output, " packet snapshot length (def: appropriate maximum)\n");
428 #else
429 fprintf(output, " packet snapshot length (def: %u)\n", WTAP_MAX_PACKET_SIZE_STANDARD);
430 #endif
431 fprintf(output, " -p, --no-promiscuous-mode\n");
432 fprintf(output, " don't capture in promiscuous mode\n");
433 #ifdef HAVE_PCAP_CREATE
434 fprintf(output, " -I, --monitor-mode capture in monitor mode, if available\n");
435 #endif
436 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
437 fprintf(output, " -B <buffer size>, --buffer-size <buffer size>\n");
438 fprintf(output, " size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
439 #endif
440 fprintf(output, " -y <link type>, --linktype <link type>\n");
441 fprintf(output, " link layer type (def: first appropriate)\n");
442 fprintf(output, " --time-stamp-type <type> timestamp method for interface\n");
443 fprintf(output, " -D, --list-interfaces print list of interfaces and exit\n");
444 fprintf(output, " -L, --list-data-link-types\n");
445 fprintf(output, " print list of link-layer types of iface and exit\n");
446 fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n");
447 fprintf(output, " --update-interval interval between updates with new packets (def: %dms)\n", DEFAULT_UPDATE_INTERVAL);
448 fprintf(output, "\n");
449 fprintf(output, "Capture stop conditions:\n");
450 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
451 fprintf(output, " -a <autostop cond.> ..., --autostop <autostop cond.> ...\n");
452 fprintf(output, " duration:NUM - stop after NUM seconds\n");
453 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
454 fprintf(output, " files:NUM - stop after NUM files\n");
455 fprintf(output, " packets:NUM - stop after NUM packets\n");
456 /*fprintf(output, "\n");*/
457 fprintf(output, "Capture output:\n");
458 fprintf(output, " -b <ringbuffer opt.> ..., --ring-buffer <ringbuffer opt.>\n");
459 fprintf(output, " duration:NUM - switch to next file after NUM secs\n");
460 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
461 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
462 fprintf(output, " packets:NUM - switch to next file after NUM packets\n");
463 fprintf(output, " interval:NUM - switch to next file when the time is\n");
464 fprintf(output, " an exact multiple of NUM secs\n");
465 fprintf(output, " printname:FILE - print filename to FILE when written\n");
466 fprintf(output, " (can use 'stdout' or 'stderr')\n");
467 #endif /* HAVE_LIBPCAP */
468 #ifdef HAVE_PCAP_REMOTE
469 fprintf(output, "RPCAP options:\n");
470 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
471 #endif
472 /*fprintf(output, "\n");*/
473 fprintf(output, "Input file:\n");
474 fprintf(output, " -r <infile>, --read-file <infile>\n");
475 fprintf(output, " set the filename to read from (or '-' for stdin)\n");
477 fprintf(output, "\n");
478 fprintf(output, "Processing:\n");
479 fprintf(output, " -2 perform a two-pass analysis\n");
480 fprintf(output, " -M <packet count> perform session auto reset\n");
481 fprintf(output, " -R <read filter>, --read-filter <read filter>\n");
482 fprintf(output, " packet Read filter in Wireshark display filter syntax\n");
483 fprintf(output, " (requires -2)\n");
484 fprintf(output, " -Y <display filter>, --display-filter <display filter>\n");
485 fprintf(output, " packet displaY filter in Wireshark display filter\n");
486 fprintf(output, " syntax\n");
487 fprintf(output, " -n disable all name resolutions (def: \"mNd\" enabled, or\n");
488 fprintf(output, " as set in preferences)\n");
489 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtdv\"\n");
490 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
491 fprintf(output, " \"Decode As\", see the man page for details\n");
492 fprintf(output, " Example: tcp.port==8888,http\n");
493 fprintf(output, " -H <hosts file> read a list of entries from a hosts file, which will\n");
494 fprintf(output, " then be written to a capture file. (Implies -W n)\n");
495 fprintf(output, " --enable-protocol <proto_name>\n");
496 fprintf(output, " enable dissection of proto_name\n");
497 fprintf(output, " --disable-protocol <proto_name>\n");
498 fprintf(output, " disable dissection of proto_name\n");
499 fprintf(output, " --only-protocols <protocols>\n");
500 fprintf(output, " Only enable dissection of these protocols, comma\n");
501 fprintf(output, " separated. Disable everything else\n");
502 fprintf(output, " --disable-all-protocols\n");
503 fprintf(output, " Disable dissection of all protocols\n");
504 fprintf(output, " --enable-heuristic <short_name>\n");
505 fprintf(output, " enable dissection of heuristic protocol\n");
506 fprintf(output, " --disable-heuristic <short_name>\n");
507 fprintf(output, " disable dissection of heuristic protocol\n");
509 /*fprintf(output, "\n");*/
510 fprintf(output, "Output:\n");
511 fprintf(output, " -w <outfile|-> write packets to a pcapng-format file named \"outfile\"\n");
512 fprintf(output, " (or '-' for stdout)\n");
513 fprintf(output, " --capture-comment <comment>\n");
514 fprintf(output, " add a capture file comment, if supported\n");
515 fprintf(output, " -C <config profile> start with specified configuration profile\n");
516 fprintf(output, " -F <output file type> set the output file type, default is pcapng\n");
517 fprintf(output, " an empty \"-F\" option will list the file types\n");
518 fprintf(output, " -V add output of packet tree (Packet Details)\n");
519 fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
520 fprintf(output, " separated\n");
521 fprintf(output, " -P, --print print packet summary even when writing to a file\n");
522 fprintf(output, " -S <separator> the line separator to print between packets\n");
523 fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
524 fprintf(output, " --hexdump <hexoption> add hexdump, set options for data source and ASCII dump\n");
525 fprintf(output, " all dump all data sources (-x default)\n");
526 fprintf(output, " frames dump only frame data source\n");
527 fprintf(output, " ascii include ASCII dump text (-x default)\n");
528 fprintf(output, " delimit delimit ASCII dump text with '|' characters\n");
529 fprintf(output, " noascii exclude ASCII dump text\n");
530 fprintf(output, " help display help for --hexdump and exit\n");
531 fprintf(output, " -T pdml|ps|psml|json|jsonraw|ek|tabs|text|fields|?\n");
532 fprintf(output, " format of text output (def: text)\n");
533 fprintf(output, " -j <protocolfilter> protocols layers filter if -T ek|pdml|json selected\n");
534 fprintf(output, " (e.g. \"ip ip.flags text\", filter does not expand child\n");
535 fprintf(output, " nodes, unless child is specified also in the filter)\n");
536 fprintf(output, " -J <protocolfilter> top level protocol filter if -T ek|pdml|json selected\n");
537 fprintf(output, " (e.g. \"http tcp\", filter which expands all child nodes)\n");
538 fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
539 fprintf(output, " _ws.col.info)\n");
540 fprintf(output, " this option can be repeated to print multiple fields\n");
541 fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
542 fprintf(output, " bom=y|n print a UTF-8 BOM\n");
543 fprintf(output, " header=y|n switch headers on and off\n");
544 fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
545 fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
546 fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
547 fprintf(output, " aggregator\n");
548 fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
549 fprintf(output, " -t (a|ad|adoy|d|dd|e|r|u|ud|udoy)[.[N]]|.[N]\n");
550 fprintf(output, " output format of time stamps (def: r: rel. to first)\n");
551 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
552 fprintf(output, " -l flush standard output after each packet\n");
553 fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
554 fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
555 fprintf(output, " -g enable group read access on the output file(s)\n");
556 fprintf(output, " -W n Save extra information in the file, if supported.\n");
557 fprintf(output, " n = write network address resolution information\n");
558 fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
559 fprintf(output, " -U tap_name PDUs export mode, see the man page for details\n");
560 fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
561 fprintf(output, " --export-objects <protocol>,<destdir>\n");
562 fprintf(output, " save exported objects for a protocol to a directory\n");
563 fprintf(output, " named \"destdir\"\n");
564 fprintf(output, " --export-tls-session-keys <keyfile>\n");
565 fprintf(output, " export TLS Session Keys to a file named \"keyfile\"\n");
566 fprintf(output, " --color color output text similarly to the Wireshark GUI,\n");
567 fprintf(output, " requires a terminal with 24-bit color support\n");
568 fprintf(output, " Also supplies color attributes to pdml and psml formats\n");
569 fprintf(output, " (Note that attributes are nonstandard)\n");
570 fprintf(output, " --no-duplicate-keys If -T json is specified, merge duplicate keys in an object\n");
571 fprintf(output, " into a single key with as value a json array containing all\n");
572 fprintf(output, " values\n");
573 fprintf(output, " --elastic-mapping-filter <protocols> If -G elastic-mapping is specified, put only the\n");
574 fprintf(output, " specified protocols within the mapping file\n");
575 fprintf(output, " --temp-dir <directory> write temporary files to this directory\n");
576 fprintf(output, " (default: %s)\n", g_get_tmp_dir());
577 fprintf(output, "\n");
579 ws_log_print_usage(output);
580 fprintf(output, "\n");
582 fprintf(output, "Miscellaneous:\n");
583 fprintf(output, " -h, --help display this help and exit\n");
584 fprintf(output, " -v, --version display version info and exit\n");
585 fprintf(output, " -o <name>:<value> ... override preference setting\n");
586 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
587 fprintf(output, " -G [report] dump one of several available reports and exit\n");
588 fprintf(output, " default report=\"fields\"\n");
589 fprintf(output, " use \"-G help\" for more help\n");
590 #ifdef __linux__
591 fprintf(output, "\n");
592 fprintf(output, "Dumpcap can benefit from an enabled BPF JIT compiler if available.\n");
593 fprintf(output, "You might want to enable it by executing:\n");
594 fprintf(output, " \"echo 1 > /proc/sys/net/core/bpf_jit_enable\"\n");
595 fprintf(output, "Note that this can make your system less secure!\n");
596 #endif
600 static void
601 glossary_option_help(void)
603 FILE *output;
605 output = stdout;
607 fprintf(output, "%s\n", get_appname_and_version());
609 fprintf(output, "\n");
610 fprintf(output, "Usage: tshark -G [report]\n");
611 fprintf(output, "\n");
612 fprintf(output, "Glossary table reports:\n");
613 fprintf(output, " -G column-formats dump column format codes and exit\n");
614 fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
615 fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
616 fprintf(output, " -G dissectors dump registered dissector names\n");
617 fprintf(output, " -G elastic-mapping dump ElasticSearch mapping file\n");
618 fprintf(output, " -G enterprises dump IANA Private Enterprise Number (PEN) table\n");
619 fprintf(output, " -G fieldcount dump count of header fields and exit\n");
620 fprintf(output, " -G fields [prefix] dump fields glossary and exit\n");
621 fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
622 fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
623 fprintf(output, " -G manuf dump ethernet manufacturer tables\n");
624 fprintf(output, " -G plugins dump installed plugins and exit\n");
625 fprintf(output, " -G protocols dump protocols in registration database and exit\n");
626 fprintf(output, " -G services dump transport service (port) names\n");
627 fprintf(output, " -G values dump value, range, true/false strings and exit\n");
628 fprintf(output, "\n");
629 fprintf(output, "Preference reports:\n");
630 fprintf(output, " -G currentprefs dump current preferences and exit\n");
631 fprintf(output, " -G defaultprefs dump default preferences and exit\n");
632 fprintf(output, " -G folders dump about:folders\n");
633 fprintf(output, "\n");
636 static void
637 hexdump_option_help(FILE *output)
639 fprintf(output, "%s\n", get_appname_and_version());
640 fprintf(output, "\n");
641 fprintf(output, "tshark: Valid --hexdump <hexoption> values include:\n");
642 fprintf(output, "\n");
643 fprintf(output, "Data source options:\n");
644 fprintf(output, " all add hexdump, dump all data sources (-x default)\n");
645 fprintf(output, " frames add hexdump, dump only frame data source\n");
646 fprintf(output, "\n");
647 fprintf(output, "ASCII options:\n");
648 fprintf(output, " ascii add hexdump, include ASCII dump text (-x default)\n");
649 fprintf(output, " delimit add hexdump, delimit ASCII dump text with '|' characters\n");
650 fprintf(output, " noascii add hexdump, exclude ASCII dump text\n");
651 fprintf(output, "\n");
652 fprintf(output, "Miscellaneous:\n");
653 fprintf(output, " help display this help and exit\n");
654 fprintf(output, "\n");
655 fprintf(output, "Example:\n");
656 fprintf(output, "\n");
657 fprintf(output, " $ tshark ... --hexdump frames --hexdump delimit ...\n");
658 fprintf(output, "\n");
661 static void
662 print_current_user(void)
664 gchar *cur_user, *cur_group;
666 if (started_with_special_privs()) {
667 cur_user = get_cur_username();
668 cur_group = get_cur_groupname();
669 fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
670 cur_user, cur_group);
671 g_free(cur_user);
672 g_free(cur_group);
673 if (running_with_special_privs()) {
674 fprintf(stderr, " This could be dangerous.");
676 fprintf(stderr, "\n");
680 static void
681 gather_tshark_compile_info(feature_list l)
683 /* Capture libraries */
684 gather_caplibs_compile_info(l);
685 epan_gather_compile_info(l);
688 static void
689 gather_tshark_runtime_info(feature_list l)
691 #ifdef HAVE_LIBPCAP
692 gather_caplibs_runtime_info(l);
693 #endif
695 /* stuff used by libwireshark */
696 epan_gather_runtime_info(l);
699 static gboolean
700 _compile_dfilter(const char *text, dfilter_t **dfp, const char *caller)
702 gboolean ok;
703 df_error_t *df_err;
704 char *err_off;
705 char *expanded;
706 gint64 elapsed_start;
708 elapsed_start = g_get_monotonic_time();
709 expanded = dfilter_expand(text, &df_err);
710 if (expanded == NULL) {
711 cmdarg_err("%s", df_err->msg);
712 df_error_free(&df_err);
713 return FALSE;
715 tshark_elapsed.dfilter_expand = g_get_monotonic_time() - elapsed_start;
717 elapsed_start = g_get_monotonic_time();
718 ok = dfilter_compile_full(expanded, dfp, &df_err, DF_OPTIMIZE, caller);
719 if (!ok ) {
720 cmdarg_err("%s", df_err->msg);
722 if (df_err->loc.col_start >= 0) {
723 err_off = ws_strdup_underline(NULL, df_err->loc.col_start, df_err->loc.col_len);
724 cmdarg_err_cont(" %s", expanded);
725 cmdarg_err_cont(" %s", err_off);
726 g_free(err_off);
728 df_error_free(&df_err);
730 tshark_elapsed.dfilter_compile = g_get_monotonic_time() - elapsed_start;
732 g_free(expanded);
733 return ok;
736 #define compile_dfilter(text, dfp) _compile_dfilter(text, dfp, __func__)
738 static gboolean
739 protocolfilter_add_opt(const char* arg, pf_flags filter_flags)
741 gchar **newfilter = NULL;
742 for (newfilter = wmem_strsplit(wmem_epan_scope(), arg, " ", -1); *newfilter; newfilter++) {
743 if (strcmp(*newfilter, "") == 0) {
744 /* Don't treat the empty string as an intended field abbreviation
745 * to output, consecutive spaces on the command line probably
746 * aren't intentional.
748 continue;
750 if (!output_fields_add_protocolfilter(output_fields, *newfilter, filter_flags)) {
751 cmdarg_err("%s was already specified with different filter flags. Overwriting previous protocol filter.", *newfilter);
754 return TRUE;
757 static void
758 about_folders(void)
760 const char *constpath;
761 char *path;
762 gint i;
763 gchar **resultArray;
765 /* "file open" */
768 * Fetching the "File" dialogs folder not implemented.
769 * This is arguably just a pwd for a ui/cli .
772 /* temp */
773 constpath = g_get_tmp_dir();
774 #ifdef HAVE_LIBPCAP
775 /* global_capture_opts only exists in this case */
776 if (global_capture_opts.temp_dir)
777 constpath = global_capture_opts.temp_dir;
778 #endif
779 printf("%-21s\t%s\n", "Temp:", constpath);
781 /* pers conf */
782 path = get_persconffile_path("", FALSE);
783 printf("%-21s\t%s\n", "Personal configuration:", path);
784 g_free(path);
786 /* global conf */
787 constpath = get_datafile_dir();
788 if (constpath != NULL) {
789 printf("%-21s\t%s\n", "Global configuration:", constpath);
792 /* system */
793 constpath = get_systemfile_dir();
794 printf("%-21s\t%s\n", "System:", constpath);
796 /* program */
797 constpath = get_progfile_dir();
798 printf("%-21s\t%s\n", "Program:", constpath);
800 if (plugins_supported()) {
801 /* pers plugins */
802 printf("%-21s\t%s\n", "Personal Plugins:", get_plugins_pers_dir());
804 /* global plugins */
805 printf("%-21s\t%s\n", "Global Plugins:", get_plugins_dir());
808 #ifdef HAVE_LUA
809 /* pers lua plugins */
810 printf("%-21s\t%s\n", "Personal Lua Plugins:", get_plugins_pers_dir());
812 /* global lua plugins */
813 printf("%-21s\t%s\n", "Global Lua Plugins:", get_plugins_dir());
814 #endif
816 /* Personal Extcap */
817 constpath = get_extcap_pers_dir();
819 resultArray = g_strsplit(constpath, G_SEARCHPATH_SEPARATOR_S, 10);
820 for(i = 0; resultArray[i]; i++)
821 printf("%-21s\t%s\n", "Personal Extcap path:", g_strstrip(resultArray[i]));
823 g_strfreev(resultArray);
825 /* Global Extcap */
826 constpath = get_extcap_dir();
828 resultArray = g_strsplit(constpath, G_SEARCHPATH_SEPARATOR_S, 10);
829 for(i = 0; resultArray[i]; i++)
830 printf("%-21s\t%s\n", "Global Extcap path:", g_strstrip(resultArray[i]));
832 g_strfreev(resultArray);
834 /* MaxMindDB */
835 path = maxmind_db_get_paths();
837 resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 10);
839 for(i = 0; resultArray[i]; i++)
840 printf("%-21s\t%s\n", "MaxMind database path:", g_strstrip(resultArray[i]));
842 g_strfreev(resultArray);
843 g_free(path);
845 #ifdef HAVE_LIBSMI
846 /* SMI MIBs/PIBs */
847 path = oid_get_default_mib_path();
849 resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 20);
851 for(i = 0; resultArray[i]; i++)
852 printf("%-21s\t%s\n", "MIB/PIB path:", g_strstrip(resultArray[i]));
854 g_strfreev(resultArray);
855 g_free(path);
856 #endif
860 static gboolean
861 must_do_dissection(dfilter_t *rfcode, dfilter_t *dfcode,
862 gchar *volatile pdu_export_arg)
864 /* We have to dissect each packet if:
866 we're printing information about each packet;
868 we're using a read filter on the packets;
870 we're using a display filter on the packets;
872 we're exporting PDUs;
874 we're using any taps that need dissection. */
875 return print_packet_info || rfcode || dfcode || pdu_export_arg ||
876 tap_listeners_require_dissection();
879 #ifdef HAVE_LIBPCAP
881 * Check whether a purported *shark packet-matching expression (display
882 * or read filter) looks like a capture filter and, if so, print a
883 * warning.
885 * Used, for example, if the string in question isn't a valid packet-
886 * matching expression.
888 static void
889 warn_about_capture_filter(const char *rfilter)
891 struct bpf_program fcode;
892 pcap_t *pc;
894 pc = pcap_open_dead(DLT_EN10MB, MIN_PACKET_SIZE);
895 if (pc != NULL) {
896 if (pcap_compile(pc, &fcode, rfilter, 0, 0) != -1) {
897 pcap_freecode(&fcode);
898 cmdarg_err_cont(
899 " Note: That read filter code looks like a valid capture filter;\n"
900 " maybe you mixed them up?");
902 pcap_close(pc);
905 #endif
907 #ifdef HAVE_LIBPCAP
908 static GList *cached_if_list = NULL;
910 static GList *
911 capture_opts_get_interface_list(int *err, char **err_str)
913 if (cached_if_list == NULL) {
915 * This isn't a GUI tool, so no need for a callback.
917 cached_if_list = capture_interface_list(err, err_str, NULL);
920 * Routines expect to free the returned interface list, so return
921 * a deep copy.
923 return interface_list_copy(cached_if_list);
925 #endif
928 main(int argc, char *argv[])
930 char *err_msg;
931 static const struct report_message_routines tshark_report_routines = {
932 failure_message,
933 failure_message,
934 open_failure_message,
935 read_failure_message,
936 write_failure_message,
937 cfile_open_failure_message,
938 cfile_dump_open_failure_message,
939 cfile_read_failure_message,
940 cfile_write_failure_message,
941 cfile_close_failure_message
943 int opt;
944 static const struct ws_option long_options[] = {
945 {"help", ws_no_argument, NULL, 'h'},
946 {"version", ws_no_argument, NULL, 'v'},
947 LONGOPT_CAPTURE_COMMON
948 LONGOPT_DISSECT_COMMON
949 LONGOPT_READ_CAPTURE_COMMON
950 {"print", ws_no_argument, NULL, 'P'},
951 {"export-objects", ws_required_argument, NULL, LONGOPT_EXPORT_OBJECTS},
952 {"export-tls-session-keys", ws_required_argument, NULL, LONGOPT_EXPORT_TLS_SESSION_KEYS},
953 {"color", ws_no_argument, NULL, LONGOPT_COLOR},
954 {"no-duplicate-keys", ws_no_argument, NULL, LONGOPT_NO_DUPLICATE_KEYS},
955 {"elastic-mapping-filter", ws_required_argument, NULL, LONGOPT_ELASTIC_MAPPING_FILTER},
956 {"capture-comment", ws_required_argument, NULL, LONGOPT_CAPTURE_COMMENT},
957 {"hexdump", ws_required_argument, NULL, LONGOPT_HEXDUMP},
958 {"selected-frame", ws_required_argument, NULL, LONGOPT_SELECTED_FRAME},
959 {"print-timers", ws_no_argument, NULL, LONGOPT_PRINT_TIMERS},
960 {0, 0, 0, 0}
962 gboolean arg_error = FALSE;
963 gboolean has_extcap_options = FALSE;
964 gboolean is_capturing = TRUE;
966 int err;
967 gchar *err_info;
968 gboolean exp_pdu_status;
969 volatile process_file_status_t status;
970 volatile gboolean draw_taps = FALSE;
971 volatile int exit_status = EXIT_SUCCESS;
972 #ifdef HAVE_LIBPCAP
973 int caps_queries = 0;
974 GList *if_list;
975 gchar *err_str, *err_str_secondary;
976 #else
977 gboolean capture_option_specified = FALSE;
978 volatile int max_packet_count = 0;
979 #endif
980 volatile int out_file_type = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
981 volatile gboolean out_file_name_res = FALSE;
982 volatile int in_file_type = WTAP_TYPE_AUTO;
983 gchar *volatile cf_name = NULL;
984 gchar *rfilter = NULL;
985 gchar *volatile dfilter = NULL;
986 dfilter_t *rfcode = NULL;
987 dfilter_t *dfcode = NULL;
988 e_prefs *prefs_p;
989 gchar *output_only = NULL;
990 gchar *volatile pdu_export_arg = NULL;
991 char *volatile exp_pdu_filename = NULL;
992 const gchar *volatile tls_session_keys_file = NULL;
993 exp_pdu_t exp_pdu_tap_data;
994 const gchar* elastic_mapping_filter = NULL;
997 * The leading + ensures that getopt_long() does not permute the argv[]
998 * entries.
1000 * We have to make sure that the first getopt_long() preserves the content
1001 * of argv[] for the subsequent getopt_long() call.
1003 * We use getopt_long() in both cases to ensure that we're using a routine
1004 * whose permutation behavior we can control in the same fashion on all
1005 * platforms, and so that, if we ever need to process a long argument before
1006 * doing further initialization, we can do so.
1008 * Glibc and Solaris libc document that a leading + disables permutation
1009 * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
1010 * and macOS don't document it, but do so anyway.
1012 * We do *not* use a leading - because the behavior of a leading - is
1013 * platform-dependent.
1015 #define OPTSTRING "+2" OPTSTRING_CAPTURE_COMMON OPTSTRING_DISSECT_COMMON OPTSTRING_READ_CAPTURE_COMMON "M:C:e:E:F:gG:hH:j:J:lo:O:PqQS:T:U:vVw:W:xX:z:"
1017 static const char optstring[] = OPTSTRING;
1020 * Set the C-language locale to the native environment and set the
1021 * code page to UTF-8 on Windows.
1023 #ifdef _WIN32
1024 setlocale(LC_ALL, ".UTF-8");
1025 #else
1026 setlocale(LC_ALL, "");
1027 #endif
1029 ws_tzset();
1031 cmdarg_err_init(tshark_cmdarg_err, tshark_cmdarg_err_cont);
1033 /* Initialize log handler early so we can have proper logging during startup. */
1034 ws_log_init("tshark", vcmdarg_err);
1036 /* Early logging command-line initialization. */
1037 ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION);
1039 ws_noisy("Finished log init and parsing command line log arguments");
1040 ws_debug("tshark started with %d args", argc);
1042 #ifdef _WIN32
1043 create_app_running_mutex();
1044 #endif /* _WIN32 */
1047 * Get credential information for later use, and drop privileges
1048 * before doing anything else.
1049 * Let the user know if anything happened.
1051 init_process_policies();
1052 relinquish_special_privs_perm();
1053 print_current_user();
1056 * Attempt to get the pathname of the directory containing the
1057 * executable file.
1059 err_msg = configuration_init(argv[0], NULL);
1060 if (err_msg != NULL) {
1061 fprintf(stderr,
1062 "tshark: Can't get pathname of directory containing the tshark program: %s.\n"
1063 "It won't be possible to capture traffic.\n"
1064 "Report this to the Wireshark developers.",
1065 err_msg);
1066 g_free(err_msg);
1069 initialize_funnel_ops();
1071 #ifdef _WIN32
1072 ws_init_dll_search_path();
1073 #ifdef HAVE_LIBPCAP
1074 /* Load wpcap if possible. Do this before collecting the run-time version information */
1075 load_wpcap();
1076 #endif /* HAVE_LIBPCAP */
1077 #endif /* _WIN32 */
1079 /* Initialize the version information. */
1080 ws_init_version_info("TShark",
1081 gather_tshark_compile_info, gather_tshark_runtime_info);
1083 /* Fail sometimes. Useful for testing fuzz scripts. */
1084 /* if (g_random_int_range(0, 100) < 5) abort(); */
1087 * In order to have the -X opts assigned before the wslua machine starts
1088 * we need to call getopt_long before epan_init() gets called.
1090 * In order to handle, for example, -o options, we also need to call it
1091 * *after* epan_init() gets called, so that the dissectors have had a
1092 * chance to register their preferences.
1094 * Spawning a bunch of extcap processes can delay program startup,
1095 * particularly on Windows. Check to see if we have any options that
1096 * might require extcap and set has_extcap_options = TRUE if that's
1097 * the case.
1099 * XXX - can we do this all with one getopt_long() call, saving the
1100 * arguments we can't handle until after initializing libwireshark,
1101 * and then process them after initializing libwireshark?
1103 ws_opterr = 0;
1105 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
1106 switch (opt) {
1107 case 'C': /* Configuration Profile */
1108 if (profile_exists (ws_optarg, FALSE)) {
1109 set_profile_name (ws_optarg);
1110 } else if (profile_exists (ws_optarg, TRUE)) {
1111 char *pf_dir_path, *pf_dir_path2, *pf_filename;
1112 /* Copy from global profile */
1113 if (create_persconffile_profile(ws_optarg, &pf_dir_path) == -1) {
1114 cmdarg_err("Can't create directory\n\"%s\":\n%s.",
1115 pf_dir_path, g_strerror(errno));
1117 g_free(pf_dir_path);
1118 exit_status = WS_EXIT_INVALID_FILE;
1119 goto clean_exit;
1121 if (copy_persconffile_profile(ws_optarg, ws_optarg, TRUE, &pf_filename,
1122 &pf_dir_path, &pf_dir_path2) == -1) {
1123 cmdarg_err("Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
1124 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
1126 g_free(pf_filename);
1127 g_free(pf_dir_path);
1128 g_free(pf_dir_path2);
1129 exit_status = WS_EXIT_INVALID_FILE;
1130 goto clean_exit;
1132 set_profile_name (ws_optarg);
1133 } else {
1134 cmdarg_err("Configuration Profile \"%s\" does not exist", ws_optarg);
1135 exit_status = WS_EXIT_INVALID_OPTION;
1136 goto clean_exit;
1138 break;
1139 case 'G':
1140 if (g_str_has_suffix(ws_optarg, "prefs")) {
1141 has_extcap_options = TRUE;
1143 is_capturing = FALSE;
1144 break;
1145 case 'i':
1146 has_extcap_options = TRUE;
1147 break;
1148 case 'o':
1149 if (g_str_has_prefix(ws_optarg, "extcap.")) {
1150 has_extcap_options = TRUE;
1152 break;
1153 case 'P': /* Print packet summary info even when writing to a file */
1154 print_packet_info = TRUE;
1155 print_summary = TRUE;
1156 break;
1157 case 'r': /* Read capture file x */
1158 cf_name = g_strdup(ws_optarg);
1159 is_capturing = FALSE;
1160 break;
1161 case 'O': /* Only output these protocols */
1162 output_only = g_strdup(ws_optarg);
1163 /* FALLTHROUGH */
1164 case 'V': /* Verbose */
1165 print_details = TRUE;
1166 print_packet_info = TRUE;
1167 break;
1168 case 'x': /* Print packet data in hex (and ASCII) */
1169 print_hex = TRUE;
1170 /* The user asked for hex output, so let's ensure they get it,
1171 * even if they're writing to a file.
1173 print_packet_info = TRUE;
1174 break;
1175 case 'X':
1176 ex_opt_add(ws_optarg);
1177 break;
1178 case 'h':
1179 case 'v':
1180 is_capturing = FALSE;
1181 break;
1182 case LONGOPT_ELASTIC_MAPPING_FILTER:
1183 elastic_mapping_filter = ws_optarg;
1184 break;
1185 default:
1186 break;
1190 #ifndef HAVE_LUA
1191 if (ex_opt_count("lua_script") > 0) {
1192 cmdarg_err("This version of TShark was not built with support for Lua scripting.");
1193 exit_status = WS_EXIT_INIT_FAILED;
1194 goto clean_exit;
1196 #endif /* HAVE_LUA */
1198 init_report_message("TShark", &tshark_report_routines);
1200 #ifdef HAVE_LIBPCAP
1201 capture_opts_init(&global_capture_opts, capture_opts_get_interface_list);
1202 capture_session_init(&global_capture_session, &cfile,
1203 capture_input_new_file, capture_input_new_packets,
1204 capture_input_drops, capture_input_error,
1205 capture_input_cfilter_error, capture_input_closed);
1206 #endif
1208 timestamp_set_type(TS_RELATIVE);
1209 timestamp_set_precision(TS_PREC_AUTO);
1210 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
1213 * Libwiretap must be initialized before libwireshark is, so that
1214 * dissection-time handlers for file-type-dependent blocks can
1215 * register using the file type/subtype value for the file type.
1217 wtap_init(TRUE);
1219 /* Register all dissectors; we must do this before checking for the
1220 "-G" flag, as the "-G" flag dumps information registered by the
1221 dissectors, and we must do it before we read the preferences, in
1222 case any dissectors register preferences. */
1223 if (!epan_init(NULL, NULL, TRUE)) {
1224 exit_status = WS_EXIT_INIT_FAILED;
1225 goto clean_exit;
1228 /* Register all tap listeners; we do this before we parse the arguments,
1229 as the "-z" argument can specify a registered tap. */
1231 register_all_tap_listeners(tap_reg_listener);
1233 /* Register extcap preferences only when needed. */
1234 if (has_extcap_options || is_capturing) {
1235 extcap_register_preferences();
1238 conversation_table_set_gui_info(init_iousers);
1239 endpoint_table_set_gui_info(init_endpoints);
1240 srt_table_iterate_tables(register_srt_tables, NULL);
1241 rtd_table_iterate_tables(register_rtd_tables, NULL);
1242 stat_tap_iterate_tables(register_simple_stat_tables, NULL);
1244 /* If invoked with the "-G" flag, we dump out information based on
1245 the argument to the "-G" flag; if no argument is specified,
1246 for backwards compatibility we dump out a glossary of display
1247 filter symbols.
1249 XXX - we do this here, for now, to support "-G" with no arguments.
1250 If none of our build or other processes uses "-G" with no arguments,
1251 we can just process it with the other arguments. */
1253 /* NOTE: This is before the preferences are loaded with
1254 * epan_load_settings() below, so if you add a new report
1255 * and it depends on the profile settings, call epan_load_settings()
1256 * first.
1258 * It is after addr_resolv_init() is called (done by epan_init()),
1259 * so "manuf", "enterprises", and "services" have the values from
1260 * the global and personal profile files already loaded.
1262 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
1263 proto_initialize_all_prefixes();
1265 if (argc == 2) {
1266 cmdarg_err("-G with no argument is deprecated and will removed in a future version.");
1267 cmdarg_err_cont("Generating fields glossary.");
1268 proto_registrar_dump_fields();
1269 } else {
1270 if (strcmp(argv[2], "column-formats") == 0)
1271 column_dump_column_formats();
1272 else if (strcmp(argv[2], "currentprefs") == 0) {
1273 epan_load_settings();
1274 write_prefs(NULL);
1276 else if (strcmp(argv[2], "decodes") == 0) {
1277 epan_load_settings();
1278 dissector_dump_decodes();
1279 } else if (strcmp(argv[2], "defaultprefs") == 0)
1280 write_prefs(NULL);
1281 else if (strcmp(argv[2], "dissector-tables") == 0)
1282 dissector_dump_dissector_tables();
1283 else if (strcmp(argv[2], "dissectors") == 0)
1284 dissector_dump_dissectors();
1285 else if (strcmp(argv[2], "elastic-mapping") == 0)
1286 proto_registrar_dump_elastic(elastic_mapping_filter);
1287 else if (strcmp(argv[2], "fieldcount") == 0) {
1288 /* return value for the test suite */
1289 exit_status = proto_registrar_dump_fieldcount();
1290 goto clean_exit;
1292 else if (strcmp(argv[2], "fields") == 0) {
1293 if (argc >= 4) {
1294 gboolean matched = proto_registrar_dump_field_completions(argv[3]);
1295 if (!matched) {
1296 cmdarg_err("No field or protocol begins with \"%s\"", argv[3]);
1297 exit_status = EXIT_FAILURE;
1298 goto clean_exit;
1301 else {
1302 proto_registrar_dump_fields();
1305 else if (strcmp(argv[2], "folders") == 0) {
1306 epan_load_settings();
1307 about_folders();
1308 } else if (strcmp(argv[2], "ftypes") == 0)
1309 proto_registrar_dump_ftypes();
1310 else if (strcmp(argv[2], "heuristic-decodes") == 0) {
1311 epan_load_settings();
1312 dissector_dump_heur_decodes();
1313 } else if (strcmp(argv[2], "manuf") == 0)
1314 ws_manuf_dump(stdout);
1315 else if (strcmp(argv[2], "enterprises") == 0)
1316 global_enterprises_dump(stdout);
1317 else if (strcmp(argv[2], "services") == 0)
1318 global_services_dump(stdout);
1319 else if (strcmp(argv[2], "plugins") == 0) {
1320 #ifdef HAVE_PLUGINS
1321 codecs_init();
1322 plugins_dump_all();
1323 #endif
1324 #ifdef HAVE_LUA
1325 wslua_plugins_dump_all();
1326 #endif
1327 extcap_dump_all();
1328 epan_plugins_dump_all();
1330 else if (strcmp(argv[2], "protocols") == 0) {
1331 epan_load_settings();
1332 proto_registrar_dump_protocols();
1333 } else if (strcmp(argv[2], "values") == 0)
1334 proto_registrar_dump_values();
1335 else if (strcmp(argv[2], "help") == 0)
1336 glossary_option_help();
1337 /* These are supported only for backwards compatibility and may or may not work
1338 * for a given user in a given directory on a given operating system with a given
1339 * command-line interpreter.
1341 else if (strcmp(argv[2], "?") == 0)
1342 glossary_option_help();
1343 else if (strcmp(argv[2], "-?") == 0)
1344 glossary_option_help();
1345 else {
1346 cmdarg_err("Invalid \"%s\" option for -G flag, enter -G help for more help.", argv[2]);
1347 exit_status = WS_EXIT_INVALID_OPTION;
1348 goto clean_exit;
1351 exit_status = EXIT_SUCCESS;
1352 goto clean_exit;
1355 ws_debug("tshark reading settings");
1357 /* Load libwireshark settings from the current profile. */
1358 prefs_p = epan_load_settings();
1359 prefs_loaded = TRUE;
1361 cap_file_init(&cfile);
1363 /* Print format defaults to this. */
1364 print_format = PR_FMT_TEXT;
1365 delimiter_char = " ";
1367 output_fields = output_fields_new();
1370 * To reset the options parser, set ws_optreset to 1 and set ws_optind to 1.
1372 * Also reset ws_opterr to 1, so that error messages are printed by
1373 * getopt_long().
1375 ws_optreset = 1;
1376 ws_optind = 1;
1377 ws_opterr = 1;
1379 /* Now get our args */
1380 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
1381 switch (opt) {
1382 case '2': /* Perform two-pass analysis */
1383 if(epan_auto_reset){
1384 cmdarg_err("-2 does not support auto session reset.");
1385 arg_error=TRUE;
1387 perform_two_pass_analysis = TRUE;
1388 break;
1389 case 'M':
1390 if(perform_two_pass_analysis){
1391 cmdarg_err("-M does not support two-pass analysis.");
1392 arg_error=TRUE;
1394 epan_auto_reset_count = get_positive_int(ws_optarg, "epan reset count");
1395 epan_auto_reset = TRUE;
1396 break;
1397 case 'a': /* autostop criteria */
1398 case 'b': /* Ringbuffer option */
1399 case 'f': /* capture filter */
1400 case 'g': /* enable group read access on file(s) */
1401 case 'i': /* Use interface x */
1402 case LONGOPT_SET_TSTAMP_TYPE: /* Set capture timestamp type */
1403 case 'p': /* Don't capture in promiscuous mode */
1404 #ifdef HAVE_PCAP_REMOTE
1405 case 'A': /* Authentication */
1406 #endif
1407 #ifdef HAVE_PCAP_CREATE
1408 case 'I': /* Capture in monitor mode, if available */
1409 #endif
1410 case 's': /* Set the snapshot (capture) length */
1411 case 'y': /* Set the pcap data link type */
1412 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
1413 case 'B': /* Buffer size */
1414 #endif
1415 case LONGOPT_COMPRESS_TYPE: /* compress type */
1416 case LONGOPT_CAPTURE_TMPDIR: /* capture temp directory */
1417 case LONGOPT_UPDATE_INTERVAL: /* sync pipe update interval */
1418 /* These are options only for packet capture. */
1419 #ifdef HAVE_LIBPCAP
1420 exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
1421 if (exit_status != 0) {
1422 goto clean_exit;
1424 #else
1425 capture_option_specified = TRUE;
1426 arg_error = TRUE;
1427 #endif
1428 break;
1429 case 'c': /* Stop after x packets */
1430 #ifdef HAVE_LIBPCAP
1431 exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
1432 if (exit_status != 0) {
1433 goto clean_exit;
1435 #else
1436 max_packet_count = get_positive_int(ws_optarg, "packet count");
1437 #endif
1438 break;
1439 case 'w': /* Write to file x */
1440 output_file_name = g_strdup(ws_optarg);
1441 #ifdef HAVE_LIBPCAP
1442 exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
1443 if (exit_status != 0) {
1444 goto clean_exit;
1446 #endif
1447 break;
1448 case 'C':
1449 /* already processed; just ignore it now */
1450 break;
1451 case 'D': /* Print a list of capture devices and exit */
1452 #ifdef HAVE_LIBPCAP
1453 exit_status = EXIT_SUCCESS;
1454 if_list = capture_interface_list(&err, &err_str,NULL);
1455 if (err != 0) {
1457 * An error occurred when fetching the local
1458 * interfaces. Report it.
1460 cmdarg_err("%s", err_str);
1461 g_free(err_str);
1462 exit_status = WS_EXIT_PCAP_ERROR;
1464 if (if_list == NULL) {
1466 * No interfaces were found. If that's not the
1467 * result of an error when fetching the local
1468 * interfaces, let the user know.
1470 if (err == 0) {
1471 cmdarg_err("There are no interfaces on which a capture can be done");
1472 exit_status = WS_EXIT_NO_INTERFACES;
1474 goto clean_exit;
1476 capture_opts_print_interfaces(if_list);
1477 free_interface_list(if_list);
1478 goto clean_exit;
1479 #else
1480 capture_option_specified = TRUE;
1481 arg_error = TRUE;
1482 #endif
1483 break;
1484 case 'e':
1485 /* Field entry */
1487 const char* col_field = try_convert_to_column_field(ws_optarg);
1488 if (col_field) {
1489 output_fields_add(output_fields, col_field);
1490 } else {
1491 header_field_info *hfi = proto_registrar_get_byalias(ws_optarg);
1492 if (hfi)
1493 output_fields_add(output_fields, hfi->abbrev);
1494 else
1495 output_fields_add(output_fields, ws_optarg);
1498 break;
1499 case 'E':
1500 /* Field option */
1501 if (!output_fields_set_option(output_fields, ws_optarg)) {
1502 cmdarg_err("\"%s\" is not a valid field output option=value pair.", ws_optarg);
1503 output_fields_list_options(stderr);
1504 exit_status = WS_EXIT_INVALID_OPTION;
1505 goto clean_exit;
1507 break;
1508 case 'F':
1509 out_file_type = wtap_name_to_file_type_subtype(ws_optarg);
1510 if (out_file_type < 0) {
1511 cmdarg_err("\"%s\" isn't a valid capture file type", ws_optarg);
1512 list_capture_types();
1513 exit_status = WS_EXIT_INVALID_OPTION;
1514 goto clean_exit;
1516 break;
1517 case 'G':
1518 cmdarg_err("-G only valid as first option");
1519 exit_status = WS_EXIT_INVALID_OPTION;
1520 goto clean_exit;
1521 break;
1522 case 'j':
1523 if (!protocolfilter_add_opt(ws_optarg, PF_NONE)) {
1524 exit_status = WS_EXIT_INVALID_OPTION;
1525 goto clean_exit;
1527 break;
1528 case 'J':
1529 if (!protocolfilter_add_opt(ws_optarg, PF_INCLUDE_CHILDREN)) {
1530 exit_status = WS_EXIT_INVALID_OPTION;
1531 goto clean_exit;
1533 break;
1534 case 'W': /* Select extra information to save in our capture file */
1535 /* This is patterned after the -N flag which may not be the best idea. */
1536 if (strchr(ws_optarg, 'n')) {
1537 out_file_name_res = TRUE;
1538 } else {
1539 cmdarg_err("Invalid -W argument \"%s\"; it must be one of:", ws_optarg);
1540 cmdarg_err_cont("\t'n' write network address resolution information (pcapng only)");
1541 exit_status = WS_EXIT_INVALID_OPTION;
1542 goto clean_exit;
1544 break;
1545 case 'H': /* Read address to name mappings from a hosts file */
1546 if (! add_hosts_file(ws_optarg))
1548 cmdarg_err("Can't read host entries from \"%s\"", ws_optarg);
1549 exit_status = WS_EXIT_INVALID_OPTION;
1550 goto clean_exit;
1552 out_file_name_res = TRUE;
1553 break;
1555 case 'h': /* Print help and exit */
1556 show_help_header("Dump and analyze network traffic.");
1557 print_usage(stdout);
1558 exit_status = EXIT_SUCCESS;
1559 goto clean_exit;
1560 break;
1561 case 'l': /* "Line-buffer" standard output */
1562 /* The ANSI C standard does not appear to *require* that a line-buffered
1563 stream be flushed to the host environment whenever a newline is
1564 written, it just says that, on such a stream, characters "are
1565 intended to be transmitted to or from the host environment as a
1566 block when a new-line character is encountered".
1568 The Visual C++ 6.0 C implementation doesn't do what is intended;
1569 even if you set a stream to be line-buffered, it still doesn't
1570 flush the buffer at the end of every line.
1572 The whole reason for the "-l" flag in either tcpdump or TShark
1573 is to allow the output of a live capture to be piped to a program
1574 or script and to have that script see the information for the
1575 packet as soon as it's printed, rather than having to wait until
1576 a standard I/O buffer fills up.
1578 So, if the "-l" flag is specified, we flush the standard output
1579 at the end of a packet. This will do the right thing if we're
1580 printing packet summary lines, and, as we print the entire protocol
1581 tree for a single packet without waiting for anything to happen,
1582 it should be as good as line-buffered mode if we're printing
1583 protocol trees - arguably even better, as it may do fewer
1584 writes. */
1585 line_buffered = TRUE;
1586 break;
1587 case 'L': /* Print list of link-layer types and exit */
1588 #ifdef HAVE_LIBPCAP
1589 caps_queries |= CAPS_QUERY_LINK_TYPES;
1590 #else
1591 capture_option_specified = TRUE;
1592 arg_error = TRUE;
1593 #endif
1594 break;
1595 case LONGOPT_LIST_TSTAMP_TYPES: /* List possible timestamp types */
1596 #ifdef HAVE_LIBPCAP
1597 caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES;
1598 #else
1599 capture_option_specified = TRUE;
1600 arg_error = TRUE;
1601 #endif
1602 break;
1603 case 'o': /* Override preference from command line */
1605 char *errmsg = NULL;
1607 switch (prefs_set_pref(ws_optarg, &errmsg)) {
1609 case PREFS_SET_OK:
1610 break;
1612 case PREFS_SET_SYNTAX_ERR:
1613 cmdarg_err("Invalid -o flag \"%s\"%s%s", ws_optarg,
1614 errmsg ? ": " : "", errmsg ? errmsg : "");
1615 g_free(errmsg);
1616 exit_status = WS_EXIT_INVALID_OPTION;
1617 goto clean_exit;
1618 break;
1620 case PREFS_SET_NO_SUCH_PREF:
1621 cmdarg_err("-o flag \"%s\" specifies unknown preference", ws_optarg);
1622 exit_status = WS_EXIT_INVALID_OPTION;
1623 goto clean_exit;
1624 break;
1626 case PREFS_SET_OBSOLETE:
1627 cmdarg_err("-o flag \"%s\" specifies obsolete preference", ws_optarg);
1628 exit_status = WS_EXIT_INVALID_OPTION;
1629 goto clean_exit;
1630 break;
1632 break;
1634 case 'q': /* Quiet */
1635 quiet = TRUE;
1636 break;
1637 case 'Q': /* Really quiet */
1638 quiet = TRUE;
1639 really_quiet = TRUE;
1640 break;
1641 case 'r':
1642 /* already processed; just ignore it now */
1643 break;
1644 case 'R': /* Read file filter */
1645 rfilter = ws_optarg;
1646 break;
1647 case 'P':
1648 /* already processed; just ignore it now */
1649 break;
1650 case 'S': /* Set the line Separator to be printed between packets */
1651 separator = ws_optarg;
1652 break;
1653 case 'T': /* printing Type */
1654 /* output_action has been already set. It means multiple -T. */
1655 if (output_action > WRITE_NONE) {
1656 cmdarg_err("Multiple -T parameters are unsupported");
1657 exit_status = WS_EXIT_INVALID_OPTION;
1658 goto clean_exit;
1660 print_packet_info = TRUE;
1661 if (strcmp(ws_optarg, "text") == 0) {
1662 output_action = WRITE_TEXT;
1663 print_format = PR_FMT_TEXT;
1664 } else if (strcmp(ws_optarg, "tabs") == 0) {
1665 output_action = WRITE_TEXT;
1666 print_format = PR_FMT_TEXT;
1667 delimiter_char = "\t";
1668 } else if (strcmp(ws_optarg, "ps") == 0) {
1669 output_action = WRITE_TEXT;
1670 print_format = PR_FMT_PS;
1671 } else if (strcmp(ws_optarg, "pdml") == 0) {
1672 output_action = WRITE_XML;
1673 print_details = TRUE; /* Need details */
1674 print_summary = FALSE; /* Don't allow summary */
1675 } else if (strcmp(ws_optarg, "psml") == 0) {
1676 output_action = WRITE_XML;
1677 print_details = FALSE; /* Don't allow details */
1678 print_summary = TRUE; /* Need summary */
1679 } else if (strcmp(ws_optarg, "fields") == 0) {
1680 output_action = WRITE_FIELDS;
1681 print_details = TRUE; /* Need full tree info */
1682 print_summary = FALSE; /* Don't allow summary */
1683 } else if (strcmp(ws_optarg, "json") == 0) {
1684 output_action = WRITE_JSON;
1685 print_details = TRUE; /* Need details */
1686 print_summary = FALSE; /* Don't allow summary */
1687 } else if (strcmp(ws_optarg, "ek") == 0) {
1688 output_action = WRITE_EK;
1689 if (!print_summary)
1690 print_details = TRUE;
1691 } else if (strcmp(ws_optarg, "jsonraw") == 0) {
1692 output_action = WRITE_JSON_RAW;
1693 print_details = TRUE; /* Need details */
1694 print_summary = FALSE; /* Don't allow summary */
1696 else {
1697 cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", ws_optarg); /* x */
1698 cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
1699 "\t specified by the -E option.\n"
1700 "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
1701 "\t details of a decoded packet. This information is equivalent to\n"
1702 "\t the packet details printed with the -V flag.\n"
1703 "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
1704 "\t the packets, or a multi-line view of the details of each of\n"
1705 "\t the packets, depending on whether the -V flag was specified.\n"
1706 "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
1707 "\t summary information of a decoded packet. This information is\n"
1708 "\t equivalent to the information shown in the one-line summary\n"
1709 "\t printed by default.\n"
1710 "\t\"json\" Packet Summary, an JSON-based format for the details\n"
1711 "\t summary information of a decoded packet. This information is \n"
1712 "\t equivalent to the packet details printed with the -V flag.\n"
1713 "\t\"jsonraw\" Packet Details, a JSON-based format for machine parsing\n"
1714 "\t including only raw hex decoded fields (same as -T json -x but\n"
1715 "\t without text decoding, only raw fields included). \n"
1716 "\t\"ek\" Packet Details, an EK JSON-based format for the bulk insert \n"
1717 "\t into elastic search cluster. This information is \n"
1718 "\t equivalent to the packet details printed with the -V flag.\n"
1719 "\t\"text\" Text of a human-readable one-line summary of each of the\n"
1720 "\t packets, or a multi-line view of the details of each of the\n"
1721 "\t packets, depending on whether the -V flag was specified.\n"
1722 "\t This is the default.\n"
1723 "\t\"tabs\" Similar to the text report except that each column of the\n"
1724 "\t human-readable one-line summary is delimited with an ASCII\n"
1725 "\t horizontal tab character.");
1726 exit_status = WS_EXIT_INVALID_OPTION;
1727 goto clean_exit;
1729 break;
1730 case 'U': /* Export PDUs to file */
1731 if (strcmp(ws_optarg, "") == 0 || strcmp(ws_optarg, "?") == 0) {
1732 list_export_pdu_taps();
1733 exit_status = WS_EXIT_INVALID_OPTION;
1734 goto clean_exit;
1736 pdu_export_arg = g_strdup(ws_optarg);
1737 break;
1738 case 'v': /* Show version and exit */
1739 show_version();
1740 /* We don't really have to cleanup here, but it's a convenient way to test
1741 * start-up and shut-down of the epan library without any UI-specific
1742 * cruft getting in the way. Makes the results of running
1743 * $ ./tools/valgrind-wireshark -n
1744 * much more useful. */
1745 epan_cleanup();
1746 extcap_cleanup();
1747 exit_status = EXIT_SUCCESS;
1748 goto clean_exit;
1749 case 'O': /* Only output these protocols */
1750 /* already processed; just ignore it now */
1751 break;
1752 case 'V': /* Verbose */
1753 /* already processed; just ignore it now */
1754 break;
1755 case 'x': /* Print packet data in hex (and ASCII) */
1756 /* already processed; just ignore it now */
1757 break;
1758 case 'X':
1759 /* already processed; just ignore it now */
1760 break;
1761 case 'Y':
1762 dfilter = g_strdup(ws_optarg);
1763 break;
1764 case 'z':
1765 /* We won't call the init function for the stat this soon
1766 as it would disallow MATE's fields (which are registered
1767 by the preferences set callback) from being used as
1768 part of a tap filter. Instead, we just add the argument
1769 to a list of stat arguments. */
1770 if (strcmp("help", ws_optarg) == 0) {
1771 fprintf(stderr, "tshark: The available statistics for the \"-z\" option are:\n");
1772 list_stat_cmd_args();
1773 exit_status = EXIT_SUCCESS;
1774 goto clean_exit;
1776 if (!process_stat_cmd_arg(ws_optarg)) {
1777 cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", ws_optarg);
1778 list_stat_cmd_args();
1779 exit_status = WS_EXIT_INVALID_OPTION;
1780 goto clean_exit;
1782 break;
1783 case 'd': /* Decode as rule */
1784 case 'K': /* Kerberos keytab file */
1785 case 'n': /* No name resolution */
1786 case 'N': /* Select what types of addresses/port #s to resolve */
1787 case 't': /* Time stamp type */
1788 case 'u': /* Seconds type */
1789 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
1790 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
1791 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
1792 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
1793 case LONGOPT_ONLY_PROTOCOLS: /* enable dissection of only this comma separated list of protocols */
1794 case LONGOPT_DISABLE_ALL_PROTOCOLS: /* enable dissection of protocol (that is disabled by default) */
1795 if (!dissect_opts_handle_opt(opt, ws_optarg)) {
1796 exit_status = WS_EXIT_INVALID_OPTION;
1797 goto clean_exit;
1799 break;
1800 case LONGOPT_EXPORT_OBJECTS: /* --export-objects */
1801 if (strcmp("help", ws_optarg) == 0) {
1802 fprintf(stderr, "tshark: The available export object types for the \"--export-objects\" option are:\n");
1803 eo_list_object_types();
1804 exit_status = EXIT_SUCCESS;
1805 goto clean_exit;
1807 if (!eo_tap_opt_add(ws_optarg)) {
1808 exit_status = WS_EXIT_INVALID_OPTION;
1809 goto clean_exit;
1811 break;
1812 case LONGOPT_EXPORT_TLS_SESSION_KEYS: /* --export-tls-session-keys */
1813 tls_session_keys_file = ws_optarg;
1814 break;
1815 case LONGOPT_COLOR: /* print in color where appropriate */
1816 dissect_color = TRUE;
1817 /* This has no effect if we don't print packet info or filter
1818 (we can filter on the coloring rules). Should we warn or
1819 error later if so, instead of silently ignoring it? */
1820 break;
1821 case LONGOPT_NO_DUPLICATE_KEYS:
1822 no_duplicate_keys = TRUE;
1823 node_children_grouper = proto_node_group_children_by_json_key;
1824 break;
1825 case LONGOPT_CAPTURE_COMMENT: /* capture comment */
1826 if (capture_comments == NULL) {
1827 capture_comments = g_ptr_array_new_with_free_func(g_free);
1829 g_ptr_array_add(capture_comments, g_strdup(ws_optarg));
1830 break;
1831 case LONGOPT_HEXDUMP:
1832 print_hex = TRUE;
1833 print_packet_info = TRUE;
1834 if (strcmp(ws_optarg, "all") == 0)
1835 hexdump_source_option = HEXDUMP_SOURCE_MULTI;
1836 else if (strcmp(ws_optarg, "frames") == 0)
1837 hexdump_source_option = HEXDUMP_SOURCE_PRIMARY;
1838 else if (strcmp(ws_optarg, "ascii") == 0)
1839 hexdump_ascii_option = HEXDUMP_ASCII_INCLUDE;
1840 else if (strcmp(ws_optarg, "delimit") == 0)
1841 hexdump_ascii_option = HEXDUMP_ASCII_DELIMIT;
1842 else if (strcmp(ws_optarg, "noascii") == 0)
1843 hexdump_ascii_option = HEXDUMP_ASCII_EXCLUDE;
1844 else if (strcmp("help", ws_optarg) == 0) {
1845 hexdump_option_help(stdout);
1846 exit_status = EXIT_SUCCESS;
1847 goto clean_exit;
1848 } else {
1849 fprintf(stderr, "tshark: \"%s\" is an invalid value for --hexdump <hexoption>\n", ws_optarg);
1850 fprintf(stderr, "For valid <hexoption> values enter: tshark --hexdump help\n");
1851 exit_status = WS_EXIT_INVALID_OPTION;
1852 goto clean_exit;
1854 break;
1855 case LONGOPT_SELECTED_FRAME:
1856 /* Hidden option to mark a frame as "selected". Used for testing and debugging.
1857 * Only active in two-pass mode. */
1858 if (!ws_strtou32(ws_optarg, NULL, &selected_frame_number)) {
1859 fprintf(stderr, "tshark: \"%s\" is not a valid frame number\n", ws_optarg);
1860 exit_status = WS_EXIT_INVALID_OPTION;
1861 goto clean_exit;
1863 break;
1864 case LONGOPT_PRINT_TIMERS:
1865 opt_print_timers = TRUE;
1866 break;
1867 default:
1868 case '?': /* Bad flag - print usage message */
1869 switch(ws_optopt) {
1870 case 'F':
1871 list_capture_types();
1872 break;
1873 default:
1874 print_usage(stderr);
1876 exit_status = WS_EXIT_INVALID_OPTION;
1877 goto clean_exit;
1878 break;
1882 /* set the default output action to TEXT */
1883 if (output_action == WRITE_NONE)
1884 output_action = WRITE_TEXT;
1886 /* set the default file type to pcapng */
1887 if (out_file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
1888 out_file_type = wtap_pcapng_file_type_subtype();
1891 * Print packet summary information is the default if neither -V or -x
1892 * were specified. Note that this is new behavior, which allows for the
1893 * possibility of printing only hex/ascii output without necessarily
1894 * requiring that either the summary or details be printed too.
1896 if (!print_summary && !print_details && !print_hex)
1897 print_summary = TRUE;
1899 if (no_duplicate_keys && output_action != WRITE_JSON && output_action != WRITE_JSON_RAW) {
1900 cmdarg_err("--no-duplicate-keys can only be used with \"-T json\" and \"-T jsonraw\"");
1901 exit_status = WS_EXIT_INVALID_OPTION;
1902 goto clean_exit;
1905 /* If we specified output fields, but not the output field type... */
1906 /* XXX: If we specfied both output fields with -e *and* protocol filters
1907 * with -j/-J, only the former are used. Should we warn or abort?
1908 * This also doesn't distinguish PDML from PSML, but shouldn't allow the
1909 * latter.
1911 if ((WRITE_FIELDS != output_action && WRITE_XML != output_action && WRITE_JSON != output_action && WRITE_EK != output_action) && 0 != output_fields_num_fields(output_fields)) {
1912 cmdarg_err("Output fields were specified with \"-e\", "
1913 "but \"-Tek, -Tfields, -Tjson or -Tpdml\" was not specified.");
1914 exit_status = WS_EXIT_INVALID_OPTION;
1915 goto clean_exit;
1916 } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
1917 cmdarg_err("\"-Tfields\" was specified, but no fields were "
1918 "specified with \"-e\".");
1920 exit_status = WS_EXIT_INVALID_OPTION;
1921 goto clean_exit;
1924 if (dissect_color) {
1925 if (!color_filters_init(&err_msg, NULL)) {
1926 fprintf(stderr, "%s\n", err_msg);
1927 g_free(err_msg);
1931 /* If no capture filter or display filter has been specified, and there are
1932 still command-line arguments, treat them as the tokens of a capture
1933 filter (if no "-r" flag was specified) or a display filter (if a "-r"
1934 flag was specified. */
1935 if (ws_optind < argc) {
1936 if (cf_name != NULL) {
1937 if (dfilter != NULL) {
1938 cmdarg_err("Display filters were specified both with \"-Y\" "
1939 "and with additional command-line arguments.");
1940 exit_status = WS_EXIT_INVALID_OPTION;
1941 goto clean_exit;
1943 dfilter = get_args_as_string(argc, argv, ws_optind);
1944 } else {
1945 #ifdef HAVE_LIBPCAP
1946 guint i;
1948 if (global_capture_opts.default_options.cfilter) {
1949 cmdarg_err("A default capture filter was specified both with \"-f\""
1950 " and with additional command-line arguments.");
1951 exit_status = WS_EXIT_INVALID_OPTION;
1952 goto clean_exit;
1954 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
1955 interface_options *interface_opts;
1956 interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
1957 if (interface_opts->cfilter == NULL) {
1958 interface_opts->cfilter = get_args_as_string(argc, argv, ws_optind);
1959 } else {
1960 cmdarg_err("A capture filter was specified both with \"-f\""
1961 " and with additional command-line arguments.");
1962 exit_status = WS_EXIT_INVALID_OPTION;
1963 goto clean_exit;
1966 global_capture_opts.default_options.cfilter = get_args_as_string(argc, argv, ws_optind);
1967 #else
1968 capture_option_specified = TRUE;
1969 #endif
1973 if (!output_file_name) {
1974 /* We're not saving the capture to a file; if "-q" wasn't specified,
1975 we should print packet information */
1976 if (!quiet)
1977 print_packet_info = TRUE;
1978 } else {
1979 const char *save_file = output_file_name;
1980 /* We're saving to a file; if we're writing to the standard output.
1981 and we'll also be writing dissected packets to the standard
1982 output, reject the request. At best, we could redirect that
1983 to the standard error; we *can't* write both to the standard
1984 output and have either of them be useful. */
1985 if (strcmp(save_file, "-") == 0 && print_packet_info) {
1986 cmdarg_err("You can't write both raw packet data and dissected packets"
1987 " to the standard output.");
1988 exit_status = WS_EXIT_INVALID_OPTION;
1989 goto clean_exit;
1993 #ifndef HAVE_LIBPCAP
1994 if (capture_option_specified)
1995 cmdarg_err("This version of TShark was not built with support for capturing packets.");
1996 #endif
1997 if (arg_error) {
1998 print_usage(stderr);
1999 exit_status = WS_EXIT_INVALID_OPTION;
2000 goto clean_exit;
2003 if (print_hex) {
2004 if (output_action != WRITE_TEXT && output_action != WRITE_JSON && output_action != WRITE_JSON_RAW && output_action != WRITE_EK) {
2005 cmdarg_err("Raw packet hex data can only be printed as text, PostScript, JSON, JSONRAW or EK JSON");
2006 exit_status = WS_EXIT_INVALID_OPTION;
2007 goto clean_exit;
2011 if (output_only != NULL) {
2012 char *ps;
2014 if (!print_details) {
2015 cmdarg_err("-O requires -V");
2016 exit_status = WS_EXIT_INVALID_OPTION;
2017 goto clean_exit;
2020 output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
2021 for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
2022 const char *name = ps;
2023 header_field_info *hfi = proto_registrar_get_byalias(name);
2024 if (hfi) {
2025 name = hfi->abbrev;
2027 g_hash_table_insert(output_only_tables, (gpointer)name, (gpointer)name);
2031 if (rfilter != NULL && !perform_two_pass_analysis) {
2032 cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
2033 exit_status = WS_EXIT_INVALID_OPTION;
2034 goto clean_exit;
2037 #ifdef HAVE_LIBPCAP
2038 if (caps_queries) {
2039 /* We're supposed to list the link-layer/timestamp types for an interface;
2040 did the user also specify a capture file to be read? */
2041 if (cf_name) {
2042 /* Yes - that's bogus. */
2043 cmdarg_err("You can't specify %s and a capture file to be read.",
2044 caps_queries & CAPS_QUERY_LINK_TYPES ? "-L" : "--list-time-stamp-types");
2045 exit_status = WS_EXIT_INVALID_OPTION;
2046 goto clean_exit;
2048 /* No - did they specify a ring buffer option? */
2049 if (global_capture_opts.multi_files_on) {
2050 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2051 exit_status = WS_EXIT_INVALID_OPTION;
2052 goto clean_exit;
2054 } else {
2055 if (cf_name) {
2057 * "-r" was specified, so we're reading a capture file.
2058 * Capture options don't apply here.
2061 /* We don't support capture filters when reading from a capture file
2062 (the BPF compiler doesn't support all link-layer types that we
2063 support in capture files we read). */
2064 if (global_capture_opts.default_options.cfilter) {
2065 cmdarg_err("Only read filters, not capture filters, "
2066 "can be specified when reading a capture file.");
2067 exit_status = WS_EXIT_INVALID_OPTION;
2068 goto clean_exit;
2070 if (global_capture_opts.multi_files_on) {
2071 cmdarg_err("Multiple capture files requested, but "
2072 "a capture isn't being done.");
2073 exit_status = WS_EXIT_INVALID_OPTION;
2074 goto clean_exit;
2076 if (global_capture_opts.has_file_duration) {
2077 cmdarg_err("Switching capture files after a time period was specified, but "
2078 "a capture isn't being done.");
2079 exit_status = WS_EXIT_INVALID_OPTION;
2080 goto clean_exit;
2082 if (global_capture_opts.has_file_interval) {
2083 cmdarg_err("Switching capture files after a time interval was specified, but "
2084 "a capture isn't being done.");
2085 exit_status = WS_EXIT_INVALID_OPTION;
2086 goto clean_exit;
2088 if (global_capture_opts.has_ring_num_files) {
2089 cmdarg_err("A ring buffer of capture files was specified, but "
2090 "a capture isn't being done.");
2091 exit_status = WS_EXIT_INVALID_OPTION;
2092 goto clean_exit;
2094 if (global_capture_opts.has_autostop_files) {
2095 cmdarg_err("A maximum number of capture files was specified, but "
2096 "a capture isn't being done.");
2097 exit_status = WS_EXIT_INVALID_OPTION;
2098 goto clean_exit;
2101 /* Note: TShark now allows the restriction of a _read_ file by packet count
2102 * and byte count as well as a write file. Other autostop options remain valid
2103 * only for a write file.
2105 if (global_capture_opts.has_autostop_duration) {
2106 cmdarg_err("A maximum capture time was specified, but "
2107 "a capture isn't being done.");
2108 exit_status = WS_EXIT_INVALID_OPTION;
2109 goto clean_exit;
2111 } else {
2113 * "-r" wasn't specified, so we're doing a live capture.
2115 gboolean use_pcapng = TRUE;
2117 if (perform_two_pass_analysis) {
2118 /* Two-pass analysis doesn't work with live capture since it requires us
2119 * to buffer packets until we've read all of them, but a live capture
2120 * has no useful/meaningful definition of "all" */
2121 cmdarg_err("Live captures do not support two-pass analysis.");
2122 exit_status = WS_EXIT_INVALID_OPTION;
2123 goto clean_exit;
2126 if (global_capture_opts.saving_to_file) {
2127 /* They specified a "-w" flag, so we'll be saving to a capture file. */
2129 /* When capturing, we only support writing pcap or pcapng format. */
2130 if (out_file_type == wtap_pcapng_file_type_subtype()) {
2131 use_pcapng = TRUE;
2132 } else if (out_file_type == wtap_pcap_file_type_subtype()) {
2133 use_pcapng = FALSE;
2134 } else {
2135 cmdarg_err("Live captures can only be saved in pcap or pcapng format.");
2136 exit_status = WS_EXIT_INVALID_OPTION;
2137 goto clean_exit;
2139 if (capture_comments != NULL && !use_pcapng) {
2140 cmdarg_err("Capture comments can only be written to a pcapng file.");
2141 exit_status = WS_EXIT_INVALID_OPTION;
2142 goto clean_exit;
2144 if (global_capture_opts.multi_files_on) {
2145 /* Multiple-file mode doesn't work under certain conditions:
2146 a) it doesn't work if you're writing to the standard output;
2147 b) it doesn't work if you're writing to a pipe;
2149 if (strcmp(global_capture_opts.save_file, "-") == 0) {
2150 cmdarg_err("Multiple capture files requested, but "
2151 "the capture is being written to the standard output.");
2152 exit_status = WS_EXIT_INVALID_OPTION;
2153 goto clean_exit;
2155 if (global_capture_opts.output_to_pipe) {
2156 cmdarg_err("Multiple capture files requested, but "
2157 "the capture file is a pipe.");
2158 exit_status = WS_EXIT_INVALID_OPTION;
2159 goto clean_exit;
2161 if (!global_capture_opts.has_autostop_filesize &&
2162 !global_capture_opts.has_file_duration &&
2163 !global_capture_opts.has_file_interval &&
2164 !global_capture_opts.has_file_packets) {
2165 cmdarg_err("Multiple capture files requested, but "
2166 "no maximum capture file size, duration, interval or packets were specified.");
2167 exit_status = WS_EXIT_INVALID_OPTION;
2168 goto clean_exit;
2171 /* Currently, we don't support read or display filters when capturing
2172 and saving the packets. */
2173 if (rfilter != NULL) {
2174 cmdarg_err("Read filters aren't supported when capturing and saving the captured packets.");
2175 exit_status = WS_EXIT_INVALID_OPTION;
2176 goto clean_exit;
2178 if (dfilter != NULL) {
2179 cmdarg_err("Display filters aren't supported when capturing and saving the captured packets.");
2180 exit_status = WS_EXIT_INVALID_OPTION;
2181 goto clean_exit;
2183 global_capture_opts.use_pcapng = use_pcapng;
2184 } else {
2185 /* They didn't specify a "-w" flag, so we won't be saving to a
2186 capture file. Check for options that only make sense if
2187 we're saving to a file. */
2188 if (global_capture_opts.has_autostop_filesize) {
2189 cmdarg_err("Maximum capture file size specified, but "
2190 "capture isn't being saved to a file.");
2191 exit_status = WS_EXIT_INVALID_OPTION;
2192 goto clean_exit;
2194 if (global_capture_opts.multi_files_on) {
2195 cmdarg_err("Multiple capture files requested, but "
2196 "the capture isn't being saved to a file.");
2197 exit_status = WS_EXIT_INVALID_OPTION;
2198 goto clean_exit;
2200 if (capture_comments != NULL) {
2201 cmdarg_err("Capture comments were specified, but "
2202 "the capture isn't being saved to a file.");
2203 exit_status = WS_EXIT_INVALID_OPTION;
2204 goto clean_exit;
2209 #endif
2212 * If capture comments were specified, -w also has to have been specified.
2214 if (capture_comments != NULL) {
2215 if (output_file_name) {
2216 /* They specified a "-w" flag, so we'll be saving to a capture file.
2217 * This is fine if they're writing in a format that supports
2218 * section block comments.
2220 if (wtap_file_type_subtype_supports_option(out_file_type,
2221 WTAP_BLOCK_SECTION,
2222 OPT_COMMENT) == OPTION_NOT_SUPPORTED) {
2223 GArray *writable_type_subtypes;
2225 cmdarg_err("Capture comments can only be written to files of the following types:");
2226 writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME);
2227 for (guint i = 0; i < writable_type_subtypes->len; i++) {
2228 int ft = g_array_index(writable_type_subtypes, int, i);
2230 if (wtap_file_type_subtype_supports_option(ft, WTAP_BLOCK_SECTION,
2231 OPT_COMMENT) != OPTION_NOT_SUPPORTED)
2232 cmdarg_err_cont(" %s - %s", wtap_file_type_subtype_name(ft),
2233 wtap_file_type_subtype_description(ft));
2235 exit_status = WS_EXIT_INVALID_OPTION;
2236 goto clean_exit;
2239 else {
2240 cmdarg_err("Capture comments were specified, but you aren't writing a capture file.");
2241 exit_status = WS_EXIT_INVALID_OPTION;
2242 goto clean_exit;
2246 err_msg = ws_init_sockets();
2247 if (err_msg != NULL)
2249 cmdarg_err("%s", err_msg);
2250 g_free(err_msg);
2251 cmdarg_err_cont("%s", please_report_bug());
2252 exit_status = WS_EXIT_INIT_FAILED;
2253 goto clean_exit;
2256 /* Notify all registered modules that have had any of their preferences
2257 changed either from one of the preferences file or from the command
2258 line that their preferences have changed. */
2259 prefs_apply_all();
2261 /* We can also enable specified taps for export object */
2262 start_exportobjects();
2264 /* At this point MATE will have registered its field array so we can
2265 check if the fields specified by the user are all good.
2268 GSList* it = NULL;
2269 GSList *invalid_fields = output_fields_valid(output_fields);
2270 if (invalid_fields != NULL) {
2272 cmdarg_err("Some fields aren't valid:");
2273 for (it=invalid_fields; it != NULL; it = g_slist_next(it)) {
2274 cmdarg_err_cont("\t%s", (gchar *)it->data);
2276 g_slist_free(invalid_fields);
2277 exit_status = WS_EXIT_INVALID_OPTION;
2278 goto clean_exit;
2282 if (ex_opt_count("read_format") > 0) {
2283 const gchar* name = ex_opt_get_next("read_format");
2284 in_file_type = open_info_name_to_type(name);
2285 if (in_file_type == WTAP_TYPE_AUTO) {
2286 cmdarg_err("\"%s\" isn't a valid read file format type", name? name : "");
2287 list_read_capture_types();
2288 exit_status = WS_EXIT_INVALID_OPTION;
2289 goto clean_exit;
2293 if (global_dissect_options.time_format != TS_NOT_SET)
2294 timestamp_set_type(global_dissect_options.time_format);
2295 if (global_dissect_options.time_precision != TS_PREC_NOT_SET)
2296 timestamp_set_precision(global_dissect_options.time_precision);
2299 * Enabled and disabled protocols and heuristic dissectors as per
2300 * command-line options.
2302 if (!setup_enabled_and_disabled_protocols()) {
2303 exit_status = WS_EXIT_INVALID_OPTION;
2304 goto clean_exit;
2307 /* Build the column format array */
2308 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2310 #ifdef HAVE_LIBPCAP
2311 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2312 capture_opts_trim_ring_num_files(&global_capture_opts);
2313 #endif
2315 if (rfilter != NULL) {
2316 ws_debug("Compiling read filter: '%s'", rfilter);
2317 if (!compile_dfilter(rfilter, &rfcode)) {
2318 epan_cleanup();
2319 extcap_cleanup();
2321 #ifdef HAVE_LIBPCAP
2322 warn_about_capture_filter(rfilter);
2323 #endif
2325 exit_status = WS_EXIT_INVALID_INTERFACE;
2326 goto clean_exit;
2329 cfile.rfcode = rfcode;
2331 if (dfilter != NULL) {
2332 ws_debug("Compiling display filter: '%s'", dfilter);
2333 if (!compile_dfilter(dfilter, &dfcode)) {
2334 epan_cleanup();
2335 extcap_cleanup();
2337 #ifdef HAVE_LIBPCAP
2338 warn_about_capture_filter(dfilter);
2339 #endif
2341 exit_status = WS_EXIT_INVALID_FILTER;
2342 goto clean_exit;
2345 cfile.dfcode = dfcode;
2347 if (print_packet_info) {
2348 /* If we're printing as text or PostScript, we have
2349 to create a print stream. */
2350 if (output_action == WRITE_TEXT) {
2351 switch (print_format) {
2353 case PR_FMT_TEXT:
2354 print_stream = print_stream_text_stdio_new(stdout);
2355 break;
2357 case PR_FMT_PS:
2358 print_stream = print_stream_ps_stdio_new(stdout);
2359 break;
2361 default:
2362 ws_assert_not_reached();
2367 /* PDU export requested. Take the ownership of the '-w' file, apply tap
2368 * filters and start tapping. */
2369 if (pdu_export_arg) {
2370 const char *exp_pdu_tap_name = pdu_export_arg;
2371 const char *exp_pdu_filter = dfilter; /* may be NULL to disable filter */
2372 char *exp_pdu_error;
2373 int exp_fd;
2374 char *comment;
2376 if (!cf_name) {
2377 cmdarg_err("PDUs export requires a capture file (specify with -r).");
2378 exit_status = WS_EXIT_INVALID_OPTION;
2379 goto clean_exit;
2381 /* Take ownership of the '-w' output file. */
2382 exp_pdu_filename = output_file_name;
2383 output_file_name = NULL;
2384 #ifdef HAVE_LIBPCAP
2385 global_capture_opts.save_file = NULL;
2386 #endif
2387 if (exp_pdu_filename == NULL) {
2388 cmdarg_err("PDUs export requires an output file (-w).");
2389 exit_status = WS_EXIT_INVALID_OPTION;
2390 goto clean_exit;
2393 exp_pdu_error = exp_pdu_pre_open(exp_pdu_tap_name, exp_pdu_filter,
2394 &exp_pdu_tap_data);
2395 if (exp_pdu_error) {
2396 cmdarg_err("Cannot register tap: %s", exp_pdu_error);
2397 g_free(exp_pdu_error);
2398 list_export_pdu_taps();
2399 exit_status = INVALID_TAP;
2400 goto clean_exit;
2403 if (strcmp(exp_pdu_filename, "-") == 0) {
2404 /* Write to the standard output. */
2405 exp_fd = 1;
2406 } else {
2407 exp_fd = ws_open(exp_pdu_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
2408 if (exp_fd == -1) {
2409 cmdarg_err("%s: %s", exp_pdu_filename, file_open_error_message(errno, TRUE));
2410 exit_status = WS_EXIT_INVALID_FILE;
2411 goto clean_exit;
2415 /* Activate the export PDU tap */
2416 /* Write to our output file with this comment (if the type supports it,
2417 * otherwise exp_pdu_open() will ignore the comment) */
2418 comment = ws_strdup_printf("Dump of PDUs from %s", cf_name);
2419 exp_pdu_status = exp_pdu_open(&exp_pdu_tap_data, exp_pdu_filename,
2420 out_file_type, exp_fd, comment,
2421 &err, &err_info);
2422 g_free(comment);
2423 if (!exp_pdu_status) {
2424 cfile_dump_open_failure_message(exp_pdu_filename, err, err_info,
2425 out_file_type);
2426 exit_status = INVALID_EXPORT;
2427 goto clean_exit;
2431 if (cf_name) {
2432 ws_debug("tshark: Opening capture file: %s", cf_name);
2434 * We're reading a capture file.
2436 if (cf_open(&cfile, cf_name, in_file_type, FALSE, &err) != CF_OK) {
2437 epan_cleanup();
2438 extcap_cleanup();
2439 exit_status = WS_EXIT_INVALID_FILE;
2440 goto clean_exit;
2443 /* Start statistics taps; we do so after successfully opening the
2444 capture file, so we know we have something to compute stats
2445 on, and after registering all dissectors, so that MATE will
2446 have registered its field array so we can have a tap filter
2447 with one of MATE's late-registered fields as part of the
2448 filter. */
2449 start_requested_stats();
2451 /* Do we need to do dissection of packets? That depends on, among
2452 other things, what taps are listening, so determine that after
2453 starting the statistics taps. */
2454 do_dissection = must_do_dissection(rfcode, dfcode, pdu_export_arg);
2455 ws_debug("tshark: do_dissection = %s", do_dissection ? "TRUE" : "FALSE");
2457 /* Process the packets in the file */
2458 ws_debug("tshark: invoking process_cap_file() to process the packets");
2459 TRY {
2460 status = process_cap_file(&cfile, output_file_name, out_file_type, out_file_name_res,
2461 #ifdef HAVE_LIBPCAP
2462 global_capture_opts.has_autostop_packets ? global_capture_opts.autostop_packets : 0,
2463 global_capture_opts.has_autostop_filesize ? global_capture_opts.autostop_filesize : 0,
2464 global_capture_opts.has_autostop_written_packets ? global_capture_opts.autostop_written_packets : 0);
2465 #else
2466 max_packet_count,
2469 #endif
2471 CATCH(OutOfMemoryError) {
2472 fprintf(stderr,
2473 "Out Of Memory.\n"
2474 "\n"
2475 "Sorry, but TShark has to terminate now.\n"
2476 "\n"
2477 "More information and workarounds can be found at\n"
2478 WS_WIKI_URL("KnownBugs/OutOfMemory") "\n");
2479 status = PROCESS_FILE_ERROR;
2481 ENDTRY;
2483 switch (status) {
2485 case PROCESS_FILE_SUCCEEDED:
2486 /* Everything worked OK; draw the taps. */
2487 draw_taps = TRUE;
2488 break;
2490 case PROCESS_FILE_NO_FILE_PROCESSED:
2491 /* We never got to try to read the file, so there are no tap
2492 results to dump. Exit with an error status. */
2493 exit_status = 2;
2494 break;
2496 case PROCESS_FILE_ERROR:
2497 /* We still dump out the results of taps, etc., as we might have
2498 read some packets; however, we exit with an error status. */
2499 draw_taps = TRUE;
2500 exit_status = 2;
2501 break;
2503 case PROCESS_FILE_INTERRUPTED:
2504 /* The user interrupted the read process; Don't dump out the
2505 result of taps, etc., and exit with an error status. */
2506 exit_status = 2;
2507 break;
2510 if (pdu_export_arg) {
2511 if (!exp_pdu_close(&exp_pdu_tap_data, &err, &err_info)) {
2512 cfile_close_failure_message(exp_pdu_filename, err, err_info);
2513 exit_status = 2;
2515 g_free(pdu_export_arg);
2516 g_free(exp_pdu_filename);
2518 } else {
2519 ws_debug("tshark: no capture file specified");
2520 /* No capture file specified, so we're supposed to do a live capture
2521 or get a list of link-layer types for a live capture device;
2522 do we have support for live captures? */
2523 #ifdef HAVE_LIBPCAP
2524 #ifdef _WIN32
2525 /* Warn the user if npf.sys isn't loaded. */
2526 if (!npf_sys_is_running()) {
2527 fprintf(stderr, "The NPF driver isn't running. You may have trouble "
2528 "capturing or\nlisting interfaces.\n");
2530 #endif /* _WIN32 */
2532 /* if no interface was specified, pick a default */
2533 exit_status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2534 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2535 if (exit_status != 0) {
2536 goto clean_exit;
2540 * If requested, list the link layer types and/or time stamp types
2541 * and exit.
2543 if (caps_queries) {
2544 guint i;
2546 /* Get the list of link-layer types for the capture devices. */
2547 exit_status = EXIT_SUCCESS;
2548 GList *if_cap_queries = NULL;
2549 if_cap_query_t *if_cap_query;
2550 GHashTable *capability_hash;
2551 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2552 interface_options *interface_opts;
2553 interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
2554 if_cap_query = g_new(if_cap_query_t, 1);
2555 if_cap_query->name = interface_opts->name;
2556 if_cap_query->monitor_mode = interface_opts->monitor_mode;
2557 if_cap_query->auth_username = NULL;
2558 if_cap_query->auth_password = NULL;
2559 #ifdef HAVE_PCAP_REMOTE
2560 if (interface_opts->auth_type == CAPTURE_AUTH_PWD) {
2561 if_cap_query->auth_username = interface_opts->auth_username;
2562 if_cap_query->auth_password = interface_opts->auth_password;
2564 #endif
2565 if_cap_queries = g_list_prepend(if_cap_queries, if_cap_query);
2567 if_cap_queries = g_list_reverse(if_cap_queries);
2568 capability_hash = capture_get_if_list_capabilities(if_cap_queries, &err_str, &err_str_secondary, NULL);
2569 g_list_free_full(if_cap_queries, g_free);
2570 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2571 interface_options *interface_opts;
2572 interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
2573 if_capabilities_t *caps;
2574 caps = g_hash_table_lookup(capability_hash, interface_opts->name);
2575 if (caps == NULL) {
2576 cmdarg_err("%s%s%s", err_str, err_str_secondary ? "\n" : "", err_str_secondary ? err_str_secondary : "");
2577 g_free(err_str);
2578 g_free(err_str_secondary);
2579 exit_status = WS_EXIT_INVALID_CAPABILITY;
2580 break;
2582 exit_status = capture_opts_print_if_capabilities(caps, interface_opts,
2583 caps_queries);
2584 if (exit_status != EXIT_SUCCESS) {
2585 break;
2588 g_hash_table_destroy(capability_hash);
2589 goto clean_exit;
2593 * If the standard error isn't a terminal, don't print packet counts,
2594 * as they won't show up on the user's terminal and they'll get in
2595 * the way of error messages in the file (to which we assume the
2596 * standard error was redirected; if it's redirected to the null
2597 * device, there's no point in printing packet counts anyway).
2599 * Otherwise, if we're printing packet information and the standard
2600 * output is a terminal (which we assume means the standard output and
2601 * error are going to the same terminal), don't print packet counts,
2602 * as they'll get in the way of the packet information.
2604 * Otherwise, if the user specified -q, don't print packet counts.
2606 * Otherwise, print packet counts.
2608 * XXX - what if the user wants to do a live capture, doesn't want
2609 * to save it to a file, doesn't want information printed for each
2610 * packet, does want some "-z" statistic, and wants packet counts
2611 * so they know whether they're seeing any packets? -q will
2612 * suppress the information printed for each packet, but it'll
2613 * also suppress the packet counts.
2615 if (!ws_isatty(ws_fileno(stderr)))
2616 print_packet_counts = FALSE;
2617 else if (print_packet_info && ws_isatty(ws_fileno(stdout)))
2618 print_packet_counts = FALSE;
2619 else if (quiet)
2620 print_packet_counts = FALSE;
2621 else
2622 print_packet_counts = TRUE;
2624 ws_debug("tshark: performing live capture");
2626 /* Start statistics taps; we should only do so after the capture
2627 started successfully, so we know we have something to compute
2628 stats, but we currently don't check for that - see below.
2630 We do so after registering all dissectors, so that MATE will
2631 have registered its field array so we can have a tap filter
2632 with one of MATE's late-registered fields as part of the
2633 filter. */
2634 start_requested_stats();
2636 /* Do we need to do dissection of packets? That depends on, among
2637 other things, what taps are listening, so determine that after
2638 starting the statistics taps. */
2639 do_dissection = must_do_dissection(rfcode, dfcode, pdu_export_arg);
2640 ws_debug("tshark: do_dissection = %s", do_dissection ? "TRUE" : "FALSE");
2642 /* We're doing live capture; if the capture child is writing to a pipe,
2643 we can't do dissection, because that would mean two readers for
2644 the pipe, tshark and whatever else. */
2645 if (do_dissection && global_capture_opts.output_to_pipe) {
2646 if (tap_listeners_require_dissection()) {
2647 cmdarg_err("Taps aren't supported when capturing and saving to a pipe.");
2648 exit_status = WS_EXIT_INVALID_OPTION;
2649 goto clean_exit;
2651 if (print_packet_info) {
2652 cmdarg_err("Printing dissected packets isn't supported when capturing and saving to a pipe.");
2653 exit_status = WS_EXIT_INVALID_OPTION;
2654 goto clean_exit;
2656 /* We already checked the next three reasons for supersets of
2657 capturing and saving to a pipe, but this doesn't hurt. */
2658 if (pdu_export_arg) {
2659 cmdarg_err("PDUs export isn't supported when capturing and saving to a pipe.");
2660 exit_status = WS_EXIT_INVALID_OPTION;
2661 goto clean_exit;
2663 if (rfcode != NULL) {
2664 cmdarg_err("Read filters aren't supported when capturing and saving to a pipe.");
2665 exit_status = WS_EXIT_INVALID_OPTION;
2666 goto clean_exit;
2668 if (dfcode != NULL) {
2669 cmdarg_err("Display filters aren't supported when capturing and saving to a pipe.");
2670 exit_status = WS_EXIT_INVALID_OPTION;
2671 goto clean_exit;
2673 /* There's some other reason we're dissecting. */
2674 cmdarg_err("Dissection isn't supported when capturing and saving to a pipe.");
2675 exit_status = WS_EXIT_INVALID_OPTION;
2676 goto clean_exit;
2679 /* Write a preamble if we're printing one. Do this after all checking
2680 * for invalid options, so we don't print just a preamble and quit. */
2681 if (print_packet_info) {
2682 if (!write_preamble(&cfile)) {
2683 show_print_file_io_error();
2684 exit_status = WS_EXIT_INVALID_FILE;
2685 goto clean_exit;
2690 * XXX - this returns FALSE if an error occurred, but it also
2691 * returns FALSE if the capture stops because a time limit
2692 * was reached (and possibly other limits), so we can't assume
2693 * it means an error.
2695 * The capture code is a bit twisty, so it doesn't appear to
2696 * be an easy fix. We just ignore the return value for now.
2697 * Instead, pass on the exit status from the capture child.
2699 capture();
2700 exit_status = global_capture_session.fork_child_status;
2702 if (print_packet_info) {
2703 if (!write_finale()) {
2704 show_print_file_io_error();
2709 * If we never got a capture file, don't draw the taps; we not only
2710 * didn't capture any packets, we never even did any capturing.
2712 if (cfile.filename != NULL)
2713 draw_taps = TRUE;
2714 #else
2715 /* No - complain. */
2716 cmdarg_err("This version of TShark was not built with support for capturing packets.");
2717 exit_status = INVALID_CAPTURE;
2718 goto clean_exit;
2719 #endif
2722 if (cfile.provider.frames != NULL) {
2723 free_frame_data_sequence(cfile.provider.frames);
2724 cfile.provider.frames = NULL;
2727 if (draw_taps)
2728 draw_tap_listeners(TRUE);
2730 if (tls_session_keys_file) {
2731 gsize keylist_length;
2732 gchar *keylist = ssl_export_sessions(&keylist_length);
2733 write_file_binary_mode(tls_session_keys_file, keylist, keylist_length);
2734 g_free(keylist);
2737 if (opt_print_timers) {
2738 if (cf_name == NULL) {
2739 /* We're doind a live capture. That isn't currently supported
2740 * with timers. */
2741 ws_message("Ignoring option --print-timers because we are doing a live capture");
2743 else {
2744 print_elapsed_json(cf_name, dfilter);
2748 /* Memory cleanup */
2749 reset_tap_listeners();
2750 funnel_dump_all_text_windows();
2751 epan_free(cfile.epan);
2752 epan_cleanup();
2753 extcap_cleanup();
2755 output_fields_free(output_fields);
2756 output_fields = NULL;
2758 clean_exit:
2759 cf_close(&cfile);
2760 g_free(cf_name);
2761 destroy_print_stream(print_stream);
2762 g_free(output_file_name);
2763 #ifdef HAVE_LIBPCAP
2764 capture_opts_cleanup(&global_capture_opts);
2765 if (cached_if_list) {
2766 free_interface_list(cached_if_list);
2768 #endif
2769 col_cleanup(&cfile.cinfo);
2770 wtap_cleanup();
2771 free_progdirs();
2772 dfilter_free(dfcode);
2773 g_free(dfilter);
2774 return exit_status;
2777 gboolean loop_running = FALSE;
2778 guint32 packet_count = 0;
2780 static epan_t *
2781 tshark_epan_new(capture_file *cf)
2783 static const struct packet_provider_funcs funcs = {
2784 cap_file_provider_get_frame_ts,
2785 cap_file_provider_get_interface_name,
2786 cap_file_provider_get_interface_description,
2787 NULL,
2790 return epan_new(&cf->provider, &funcs);
2793 #ifdef HAVE_LIBPCAP
2794 static gboolean
2795 capture(void)
2797 volatile gboolean ret = TRUE;
2798 GString *str;
2799 GMainContext *ctx;
2800 #ifndef _WIN32
2801 struct sigaction action, oldaction;
2802 #endif
2804 /* Create new dissection section. */
2805 epan_free(cfile.epan);
2806 cfile.epan = tshark_epan_new(&cfile);
2808 #ifdef _WIN32
2809 /* Catch a CTRL+C event and, if we get it, clean up and exit. */
2810 SetConsoleCtrlHandler(capture_cleanup, TRUE);
2811 #else /* _WIN32 */
2812 /* Catch SIGINT and SIGTERM and, if we get either of them,
2813 clean up and exit. If SIGHUP isn't being ignored, catch
2814 it too and, if we get it, clean up and exit.
2816 We restart any read that was in progress, so that it doesn't
2817 disrupt reading from the sync pipe. The signal handler tells
2818 the capture child to finish; it will report that it finished,
2819 or will exit abnormally, so we'll stop reading from the sync
2820 pipe, pick up the exit status, and quit. */
2821 memset(&action, 0, sizeof(action));
2822 action.sa_handler = capture_cleanup;
2823 action.sa_flags = SA_RESTART;
2824 sigemptyset(&action.sa_mask);
2825 sigaction(SIGTERM, &action, NULL);
2826 sigaction(SIGINT, &action, NULL);
2827 sigaction(SIGHUP, NULL, &oldaction);
2828 if (oldaction.sa_handler == SIG_DFL)
2829 sigaction(SIGHUP, &action, NULL);
2831 #ifdef SIGINFO
2832 /* Catch SIGINFO and, if we get it and we're capturing to a file in
2833 quiet mode, report the number of packets we've captured.
2835 Again, restart any read that was in progress, so that it doesn't
2836 disrupt reading from the sync pipe. */
2837 action.sa_handler = report_counts_siginfo;
2838 action.sa_flags = SA_RESTART;
2839 sigemptyset(&action.sa_mask);
2840 sigaction(SIGINFO, &action, NULL);
2841 #endif /* SIGINFO */
2842 #endif /* _WIN32 */
2844 global_capture_session.state = CAPTURE_PREPARING;
2846 /* Let the user know which interfaces were chosen. */
2847 str = get_iface_list_string(&global_capture_opts, IFLIST_QUOTE_IF_DESCRIPTION);
2848 if (really_quiet == FALSE)
2849 fprintf(stderr, "Capturing on %s\n", str->str);
2850 fflush(stderr);
2851 g_string_free(str, TRUE);
2853 ret = sync_pipe_start(&global_capture_opts, capture_comments,
2854 &global_capture_session, &global_info_data, NULL);
2856 if (!ret)
2857 return FALSE;
2860 * Force synchronous resolution of IP addresses; we're doing only
2861 * one pass, so we can't do it in the background and fix up past
2862 * dissections.
2864 set_resolution_synchrony(TRUE);
2866 /* the actual capture loop */
2867 ctx = g_main_context_default();
2868 loop_running = TRUE;
2872 while (loop_running)
2874 g_main_context_iteration(ctx, TRUE);
2877 CATCH(OutOfMemoryError) {
2878 fprintf(stderr,
2879 "Out Of Memory.\n"
2880 "\n"
2881 "Sorry, but TShark has to terminate now.\n"
2882 "\n"
2883 "More information and workarounds can be found at\n"
2884 WS_WIKI_URL("KnownBugs/OutOfMemory") "\n");
2885 abort();
2887 ENDTRY;
2888 return ret;
2891 /* capture child detected an error */
2892 static void
2893 capture_input_error(capture_session *cap_session _U_, char *error_msg, char *secondary_error_msg)
2895 /* The primary message might be an empty string, e.g. when the error was
2896 * from extcap. (The extcap stderr is gathered when the session closes
2897 * and printed in capture_input_closed below.) */
2898 if (*error_msg != '\0') {
2899 cmdarg_err("%s", error_msg);
2900 if (secondary_error_msg != NULL && *secondary_error_msg != '\0') {
2901 /* We have both primary and secondary messages. */
2902 cmdarg_err_cont("%s", secondary_error_msg);
2908 /* capture child detected an capture filter related error */
2909 static void
2910 capture_input_cfilter_error(capture_session *cap_session, guint i, const char *error_message)
2912 capture_options *capture_opts = cap_session->capture_opts;
2913 dfilter_t *rfcode = NULL;
2914 interface_options *interface_opts;
2916 ws_assert(i < capture_opts->ifaces->len);
2917 interface_opts = &g_array_index(capture_opts->ifaces, interface_options, i);
2919 if (dfilter_compile(interface_opts->cfilter, &rfcode, NULL) && rfcode != NULL) {
2920 cmdarg_err(
2921 "Invalid capture filter \"%s\" for interface '%s'.\n"
2922 "\n"
2923 "That string looks like a valid display filter; however, it isn't a valid\n"
2924 "capture filter (%s).\n"
2925 "\n"
2926 "Note that display filters and capture filters don't have the same syntax,\n"
2927 "so you can't use most display filter expressions as capture filters.\n"
2928 "\n"
2929 "See the User's Guide for a description of the capture filter syntax.",
2930 interface_opts->cfilter, interface_opts->descr, error_message);
2931 dfilter_free(rfcode);
2932 } else {
2933 cmdarg_err(
2934 "Invalid capture filter \"%s\" for interface '%s'.\n"
2935 "\n"
2936 "That string isn't a valid capture filter (%s).\n"
2937 "See the User's Guide for a description of the capture filter syntax.",
2938 interface_opts->cfilter, interface_opts->descr, error_message);
2943 /* capture child tells us we have a new (or the first) capture file */
2944 static bool
2945 capture_input_new_file(capture_session *cap_session, gchar *new_file)
2947 capture_options *capture_opts = cap_session->capture_opts;
2948 capture_file *cf = cap_session->cf;
2949 gboolean is_tempfile;
2950 int err;
2952 if (really_quiet == FALSE) {
2953 if (cap_session->state == CAPTURE_PREPARING) {
2954 ws_info("Capture started.");
2956 ws_info("File: \"%s\"", new_file);
2959 ws_assert(cap_session->state == CAPTURE_PREPARING || cap_session->state == CAPTURE_RUNNING);
2961 /* free the old filename */
2962 if (capture_opts->save_file != NULL) {
2964 /* we start a new capture file, close the old one (if we had one before) */
2965 if (cf->state != FILE_CLOSED) {
2966 cf_close(cf);
2969 g_free(capture_opts->save_file);
2970 is_tempfile = FALSE;
2972 epan_free(cf->epan);
2973 cf->epan = tshark_epan_new(cf);
2974 } else {
2975 /* we didn't had a save_file before, must be a tempfile */
2976 is_tempfile = TRUE;
2979 /* save the new filename */
2980 capture_opts->save_file = g_strdup(new_file);
2982 /* if we are in real-time mode, open the new file now */
2983 if (do_dissection) {
2984 /* this is probably unnecessary, but better safe than sorry */
2985 cap_session->cf->open_type = WTAP_TYPE_AUTO;
2986 /* Attempt to open the capture file and set up to read from it. */
2987 switch(cf_open(cap_session->cf, capture_opts->save_file, WTAP_TYPE_AUTO, is_tempfile, &err)) {
2988 case CF_OK:
2989 break;
2990 case CF_ERROR:
2991 /* Don't unlink (delete) the save file - leave it around,
2992 for debugging purposes. */
2993 g_free(capture_opts->save_file);
2994 capture_opts->save_file = NULL;
2995 return FALSE;
2997 } else if (quiet && is_tempfile) {
2998 cf->state = FILE_READ_ABORTED;
2999 cf->filename = g_strdup(new_file);
3000 cf->is_tempfile = is_tempfile;
3003 cap_session->state = CAPTURE_RUNNING;
3005 return TRUE;
3009 /* capture child tells us we have new packets to read */
3010 static void
3011 capture_input_new_packets(capture_session *cap_session, int to_read)
3013 gboolean ret;
3014 int err;
3015 gchar *err_info;
3016 gint64 data_offset;
3017 capture_file *cf = cap_session->cf;
3018 gboolean filtering_tap_listeners;
3019 guint tap_flags;
3021 #ifdef SIGINFO
3023 * Prevent a SIGINFO handler from writing to the standard error while
3024 * we're doing so or writing to the standard output; instead, have it
3025 * just set a flag telling us to print that information when we're done.
3027 infodelay = TRUE;
3028 #endif /* SIGINFO */
3030 /* Do we have any tap listeners with filters? */
3031 filtering_tap_listeners = have_filtering_tap_listeners();
3033 /* Get the union of the flags for all tap listeners. */
3034 tap_flags = union_of_tap_listener_flags();
3036 if (do_dissection) {
3037 gboolean create_proto_tree;
3038 epan_dissect_t *edt;
3039 wtap_rec rec;
3040 Buffer buf;
3043 * Determine whether we need to create a protocol tree.
3044 * We do if:
3046 * we're going to apply a read filter;
3048 * we're going to apply a display filter;
3050 * we're going to print the protocol tree;
3052 * one of the tap listeners is going to apply a filter;
3054 * one of the tap listeners requires a protocol tree;
3056 * a postdissector wants field values or protocols
3057 * on the first pass;
3059 * we have custom columns (which require field values, which
3060 * currently requires that we build a protocol tree).
3062 create_proto_tree =
3063 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
3064 (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
3065 have_custom_cols(&cf->cinfo) || dissect_color);
3067 /* The protocol tree will be "visible", i.e., nothing faked, only if
3068 we're printing packet details, which is true if we're printing stuff
3069 ("print_packet_info" is true) and we're in verbose mode
3070 ("packet_details" is true). But if we specified certain fields with
3071 "-e", we'll prime those directly later. */
3072 bool visible = print_packet_info && print_details && output_fields_num_fields(output_fields) == 0;
3073 edt = epan_dissect_new(cf->epan, create_proto_tree, visible);
3075 wtap_rec_init(&rec);
3076 ws_buffer_init(&buf, 1514);
3078 while (to_read-- && cf->provider.wth) {
3079 wtap_cleareof(cf->provider.wth);
3080 ret = wtap_read(cf->provider.wth, &rec, &buf, &err, &err_info, &data_offset);
3081 reset_epan_mem(cf, edt, create_proto_tree, print_packet_info && print_details);
3082 if (ret == FALSE) {
3083 /* read from file failed, tell the capture child to stop */
3084 sync_pipe_stop(cap_session);
3085 wtap_close(cf->provider.wth);
3086 cf->provider.wth = NULL;
3087 } else {
3088 ret = process_packet_single_pass(cf, edt, data_offset, &rec, &buf,
3089 tap_flags);
3091 if (ret != FALSE) {
3092 /* packet successfully read and gone through the "Read Filter" */
3093 packet_count++;
3095 wtap_rec_reset(&rec);
3098 epan_dissect_free(edt);
3100 wtap_rec_cleanup(&rec);
3101 ws_buffer_free(&buf);
3103 } else {
3105 * Dumpcap's doing all the work; we're not doing any dissection.
3106 * Count all the packets it wrote.
3108 packet_count += to_read;
3111 if (print_packet_counts) {
3112 /* We're printing packet counts. */
3113 if (packet_count != 0) {
3114 fprintf(stderr, "\r%u ", packet_count);
3115 /* stderr could be line buffered */
3116 fflush(stderr);
3120 #ifdef SIGINFO
3122 * Allow SIGINFO handlers to write.
3124 infodelay = FALSE;
3127 * If a SIGINFO handler asked us to write out capture counts, do so.
3129 if (infoprint)
3130 report_counts();
3131 #endif /* SIGINFO */
3134 static void
3135 report_counts(void)
3137 if ((print_packet_counts == FALSE) && (really_quiet == FALSE)) {
3138 /* Report the count only if we aren't printing a packet count
3139 as packets arrive. */
3140 fprintf(stderr, "%u packet%s captured\n", packet_count,
3141 plurality(packet_count, "", "s"));
3143 #ifdef SIGINFO
3144 infoprint = FALSE; /* we just reported it */
3145 #endif /* SIGINFO */
3148 #ifdef SIGINFO
3149 static void
3150 report_counts_siginfo(int signum _U_)
3152 int sav_errno = errno;
3153 /* If we've been told to delay printing, just set a flag asking
3154 that we print counts (if we're supposed to), otherwise print
3155 the count of packets captured (if we're supposed to). */
3156 if (infodelay)
3157 infoprint = TRUE;
3158 else
3159 report_counts();
3160 errno = sav_errno;
3162 #endif /* SIGINFO */
3165 /* capture child detected any packet drops? */
3166 static void
3167 capture_input_drops(capture_session *cap_session _U_, guint32 dropped, const char* interface_name)
3169 if (print_packet_counts) {
3170 /* We're printing packet counts to stderr.
3171 Send a newline so that we move to the line after the packet count. */
3172 fprintf(stderr, "\n");
3175 if (dropped != 0) {
3176 /* We're printing packet counts to stderr.
3177 Send a newline so that we move to the line after the packet count. */
3178 if (interface_name != NULL) {
3179 fprintf(stderr, "%u packet%s dropped from %s\n", dropped, plurality(dropped, "", "s"), interface_name);
3180 } else {
3181 fprintf(stderr, "%u packet%s dropped\n", dropped, plurality(dropped, "", "s"));
3188 * Capture child closed its side of the pipe, report any error and
3189 * do the required cleanup.
3191 static void
3192 capture_input_closed(capture_session *cap_session _U_, gchar *msg)
3194 if (msg != NULL && *msg != '\0')
3195 fprintf(stderr, "tshark: %s\n", msg);
3197 report_counts();
3199 loop_running = FALSE;
3202 #ifdef _WIN32
3203 static BOOL WINAPI
3204 capture_cleanup(DWORD ctrltype _U_)
3206 /* CTRL_C_EVENT is sort of like SIGINT, CTRL_BREAK_EVENT is unique to
3207 Windows, CTRL_CLOSE_EVENT is sort of like SIGHUP, CTRL_LOGOFF_EVENT
3208 is also sort of like SIGHUP, and CTRL_SHUTDOWN_EVENT is sort of
3209 like SIGTERM at least when the machine's shutting down.
3211 For now, we handle them all as indications that we should clean up
3212 and quit, just as we handle SIGINT, SIGHUP, and SIGTERM in that
3213 way on UNIX.
3215 We must return TRUE so that no other handler - such as one that would
3216 terminate the process - gets called.
3218 XXX - for some reason, typing ^C to TShark, if you run this in
3219 a Cygwin console window in at least some versions of Cygwin,
3220 causes TShark to terminate immediately; this routine gets
3221 called, but the main loop doesn't get a chance to run and
3222 exit cleanly, at least if this is compiled with Microsoft Visual
3223 C++ (i.e., it's a property of the Cygwin console window or Bash;
3224 it happens if TShark is not built with Cygwin - for all I know,
3225 building it with Cygwin may make the problem go away). */
3227 /* tell the capture child to stop */
3228 sync_pipe_stop(&global_capture_session);
3230 /* don't stop our own loop already here, otherwise status messages and
3231 * cleanup wouldn't be done properly. The child will indicate the stop of
3232 * everything by calling capture_input_closed() later */
3234 return TRUE;
3236 #else
3237 static void
3238 capture_cleanup(int signum _U_)
3240 /* tell the capture child to stop */
3241 sync_pipe_stop(&global_capture_session);
3243 /* don't stop our own loop already here, otherwise status messages and
3244 * cleanup wouldn't be done properly. The child will indicate the stop of
3245 * everything by calling capture_input_closed() later */
3247 #endif /* _WIN32 */
3248 #endif /* HAVE_LIBPCAP */
3250 static gboolean
3251 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
3252 gint64 offset, wtap_rec *rec, Buffer *buf)
3254 frame_data fdlocal;
3255 guint32 framenum;
3256 gboolean passed;
3257 gint64 elapsed_start;
3259 /* The frame number of this packet is one more than the count of
3260 frames in this packet. */
3261 framenum = cf->count + 1;
3263 /* If we're not running a display filter and we're not printing any
3264 packet information, we don't need to do a dissection. This means
3265 that all packets can be marked as 'passed'. */
3266 passed = TRUE;
3268 frame_data_init(&fdlocal, framenum, rec, offset, cum_bytes);
3270 /* If we're going to run a read filter or a display filter, set up to
3271 do a dissection and do so. (This is the first pass of two passes
3272 over the packets, so we will not be printing any information
3273 from the dissection or running taps on the packet; if we're doing
3274 any of that, we'll do it in the second pass.) */
3275 if (edt) {
3276 if (gbl_resolv_flags.network_name || gbl_resolv_flags.maxmind_geoip) {
3277 /* If we're doing async lookups, send any that are queued and
3278 * retrieve results.
3280 * Ideally we'd force any lookups that need to happen on the second pass
3281 * to be sent asynchronously on this pass so the results would be ready.
3282 * That will happen if they're involved in a filter (because we prime the
3283 * tree below), but not currently for taps, if we're printing packet
3284 * summaries or details, etc.
3286 * XXX - If we're running a read filter that depends on a resolved
3287 * name, we should be doing synchronous lookups in that case. Also
3288 * marking the dependent frames below might not work with a display
3289 * filter that depends on a resolved name.
3291 host_name_lookup_process();
3294 column_info *cinfo = NULL;
3296 /* If we're running a read filter, prime the epan_dissect_t with that
3297 filter. */
3298 if (cf->rfcode)
3299 epan_dissect_prime_with_dfilter(edt, cf->rfcode);
3301 if (cf->dfcode)
3302 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
3304 /* This is the first pass, so prime the epan_dissect_t with the
3305 hfids postdissectors want on the first pass. */
3306 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
3308 frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
3309 &cf->provider.ref, cf->provider.prev_dis);
3310 if (cf->provider.ref == &fdlocal) {
3311 ref_frame = fdlocal;
3312 cf->provider.ref = &ref_frame;
3315 /* If we're applying a filter that needs the columns, construct them. */
3316 if (dfilter_requires_columns(cf->rfcode) || dfilter_requires_columns(cf->dfcode)) {
3317 cinfo = &cf->cinfo;
3320 elapsed_start = g_get_monotonic_time();
3321 epan_dissect_run(edt, cf->cd_t, rec,
3322 frame_tvbuff_new_buffer(&cf->provider, &fdlocal, buf),
3323 &fdlocal, cinfo);
3324 tshark_elapsed.first_pass.dissect += g_get_monotonic_time() - elapsed_start;
3326 /* Run the read filter if we have one. */
3327 if (cf->rfcode) {
3328 elapsed_start = g_get_monotonic_time();
3329 passed = dfilter_apply_edt(cf->rfcode, edt);
3330 tshark_elapsed.first_pass.dfilter_read += g_get_monotonic_time() - elapsed_start;
3334 if (passed) {
3335 frame_data_set_after_dissect(&fdlocal, &cum_bytes);
3336 cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
3338 /* If we're not doing dissection then there won't be any dependent frames.
3339 * More importantly, edt.pi.fd.dependent_frames won't be initialized because
3340 * epan hasn't been initialized.
3341 * if we *are* doing dissection, then mark the dependent frames, but only
3342 * if a display filter was given and it matches this packet.
3344 if (edt && cf->dfcode) {
3345 elapsed_start = g_get_monotonic_time();
3346 if (dfilter_apply_edt(cf->dfcode, edt) && edt->pi.fd->dependent_frames) {
3347 g_hash_table_foreach(edt->pi.fd->dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
3350 if (selected_frame_number != 0 && selected_frame_number == cf->count + 1) {
3351 /* If we are doing dissection and we have a "selected frame"
3352 * then load that frame's references (if any) onto the compiled
3353 * display filter. Selected frame number is ordinal, count is cardinal. */
3354 dfilter_load_field_references(cf->dfcode, edt->tree);
3356 tshark_elapsed.first_pass.dfilter_filter += g_get_monotonic_time() - elapsed_start;
3359 cf->count++;
3360 } else {
3361 /* if we don't add it to the frame_data_sequence, clean it up right now
3362 * to avoid leaks */
3363 frame_data_destroy(&fdlocal);
3366 if (edt)
3367 epan_dissect_reset(edt);
3369 return passed;
3373 * Set if reading a file was interrupted by a CTRL_ event on Windows or
3374 * a signal on UN*X.
3376 static gboolean read_interrupted = FALSE;
3378 #ifdef _WIN32
3379 static BOOL WINAPI
3380 read_cleanup(DWORD ctrltype _U_)
3382 /* CTRL_C_EVENT is sort of like SIGINT, CTRL_BREAK_EVENT is unique to
3383 Windows, CTRL_CLOSE_EVENT is sort of like SIGHUP, CTRL_LOGOFF_EVENT
3384 is also sort of like SIGHUP, and CTRL_SHUTDOWN_EVENT is sort of
3385 like SIGTERM at least when the machine's shutting down.
3387 For now, we handle them all as indications that we should clean up
3388 and quit, just as we handle SIGINT, SIGHUP, and SIGTERM in that
3389 way on UNIX.
3391 We must return TRUE so that no other handler - such as one that would
3392 terminate the process - gets called.
3394 XXX - for some reason, typing ^C to TShark, if you run this in
3395 a Cygwin console window in at least some versions of Cygwin,
3396 causes TShark to terminate immediately; this routine gets
3397 called, but the main loop doesn't get a chance to run and
3398 exit cleanly, at least if this is compiled with Microsoft Visual
3399 C++ (i.e., it's a property of the Cygwin console window or Bash;
3400 it happens if TShark is not built with Cygwin - for all I know,
3401 building it with Cygwin may make the problem go away). */
3403 /* tell the read to stop */
3404 read_interrupted = TRUE;
3406 return TRUE;
3408 #else
3409 static void
3410 read_cleanup(int signum _U_)
3412 /* tell the read to stop */
3413 read_interrupted = TRUE;
3415 #endif /* _WIN32 */
3417 typedef enum {
3418 PASS_SUCCEEDED,
3419 PASS_READ_ERROR,
3420 PASS_WRITE_ERROR,
3421 PASS_INTERRUPTED
3422 } pass_status_t;
3424 static pass_status_t
3425 process_cap_file_first_pass(capture_file *cf, int max_packet_count,
3426 gint64 max_byte_count, int *err, gchar **err_info)
3428 wtap_rec rec;
3429 Buffer buf;
3430 epan_dissect_t *edt = NULL;
3431 gint64 data_offset;
3432 pass_status_t status = PASS_SUCCEEDED;
3433 int framenum = 0;
3435 wtap_rec_init(&rec);
3436 ws_buffer_init(&buf, 1514);
3438 /* Allocate a frame_data_sequence for all the frames. */
3439 cf->provider.frames = new_frame_data_sequence();
3441 if (do_dissection) {
3442 gboolean create_proto_tree;
3445 * Determine whether we need to create a protocol tree.
3446 * We do if:
3448 * we're going to apply a read filter;
3450 * we're going to apply a display filter;
3452 * a postdissector wants field values or protocols
3453 * on the first pass.
3455 create_proto_tree =
3456 (cf->rfcode != NULL || cf->dfcode != NULL || postdissectors_want_hfids() || dissect_color);
3458 ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
3460 /* We're not going to display the protocol tree on this pass,
3461 so it's not going to be "visible". */
3462 edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
3465 ws_debug("tshark: reading records for first pass");
3466 *err = 0;
3467 while (wtap_read(cf->provider.wth, &rec, &buf, err, err_info, &data_offset)) {
3468 if (read_interrupted) {
3469 status = PASS_INTERRUPTED;
3470 break;
3472 framenum++;
3474 if (process_packet_first_pass(cf, edt, data_offset, &rec, &buf)) {
3475 /* Stop reading if we hit a stop condition */
3476 if (max_packet_count > 0 && framenum >= max_packet_count) {
3477 ws_debug("tshark: max_packet_count (%d) reached", max_packet_count);
3478 *err = 0; /* This is not an error */
3479 break;
3481 if (max_byte_count != 0 && data_offset >= max_byte_count) {
3482 ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached",
3483 data_offset, max_byte_count);
3484 *err = 0; /* This is not an error */
3485 break;
3488 wtap_rec_reset(&rec);
3490 if (*err != 0)
3491 status = PASS_READ_ERROR;
3493 if (edt)
3494 epan_dissect_free(edt);
3496 /* Close the sequential I/O side, to free up memory it requires. */
3497 wtap_sequential_close(cf->provider.wth);
3499 /* Allow the protocol dissectors to free up memory that they
3500 * don't need after the sequential run-through of the packets. */
3501 postseq_cleanup_all_protocols();
3503 cf->provider.prev_dis = NULL;
3504 cf->provider.prev_cap = NULL;
3506 ws_buffer_free(&buf);
3507 wtap_rec_cleanup(&rec);
3509 return status;
3512 static gboolean
3513 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
3514 frame_data *fdata, wtap_rec *rec,
3515 Buffer *buf, guint tap_flags _U_)
3517 column_info *cinfo;
3518 gboolean passed;
3519 wtap_block_t block = NULL;
3520 gint64 elapsed_start;
3522 /* If we're not running a display filter and we're not printing any
3523 packet information, we don't need to do a dissection. This means
3524 that all packets can be marked as 'passed'. */
3525 passed = TRUE;
3527 /* If we're going to print packet information, or we're going to
3528 run a read filter, or we're going to process taps, set up to
3529 do a dissection and do so. (This is the second pass of two
3530 passes over the packets; that's the pass where we print
3531 packet information or run taps.) */
3532 if (edt) {
3533 /* If we're running a display filter, prime the epan_dissect_t with that
3534 filter. */
3535 if (cf->dfcode)
3536 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
3538 col_custom_prime_edt(edt, &cf->cinfo);
3540 output_fields_prime_edt(edt, output_fields);
3541 /* The PDML spec requires a 'geninfo' pseudo-protocol that needs
3542 * information from our 'frame' protocol.
3544 if (output_fields_num_fields(output_fields) != 0 &&
3545 output_action == WRITE_XML) {
3546 epan_dissect_prime_with_hfid(edt, proto_registrar_get_id_byname("frame"));
3549 /* We only need the columns if either
3550 1) some tap or filter needs the columns
3552 2) we're printing packet info but we're *not* verbose; in verbose
3553 mode, we print the protocol tree, not the protocol summary.
3555 3) there is a column mapped to an individual field
3557 if ((tap_listeners_require_columns()) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields) || dfilter_requires_columns(cf->dfcode))
3558 cinfo = &cf->cinfo;
3559 else
3560 cinfo = NULL;
3562 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
3563 &cf->provider.ref, cf->provider.prev_dis);
3564 if (cf->provider.ref == fdata) {
3565 ref_frame = *fdata;
3566 cf->provider.ref = &ref_frame;
3569 if (dissect_color) {
3570 color_filters_prime_edt(edt);
3571 fdata->need_colorize = 1;
3574 /* epan_dissect_run (and epan_dissect_reset) unref the block.
3575 * We need it later, e.g. in order to copy the options. */
3576 block = wtap_block_ref(rec->block);
3577 elapsed_start = g_get_monotonic_time();
3578 epan_dissect_run_with_taps(edt, cf->cd_t, rec,
3579 frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
3580 fdata, cinfo);
3581 tshark_elapsed.second_pass.dissect += g_get_monotonic_time() - elapsed_start;
3583 /* Run the display filter if we have one. */
3584 if (cf->dfcode) {
3585 elapsed_start = g_get_monotonic_time();
3586 passed = dfilter_apply_edt(cf->dfcode, edt);
3587 tshark_elapsed.second_pass.dfilter_filter += g_get_monotonic_time() - elapsed_start;
3591 if (passed) {
3592 frame_data_set_after_dissect(fdata, &cum_bytes);
3593 /* Process this packet. */
3594 if (print_packet_info) {
3595 /* We're printing packet information; print the information for
3596 this packet. */
3597 print_packet(cf, edt);
3599 /* If we're doing "line-buffering", flush the standard output
3600 after every packet. See the comment above, for the "-l"
3601 option, for an explanation of why we do that. */
3602 if (line_buffered)
3603 fflush(stdout);
3605 if (ferror(stdout)) {
3606 show_print_file_io_error();
3607 exit(2);
3610 cf->provider.prev_dis = fdata;
3612 cf->provider.prev_cap = fdata;
3614 if (edt) {
3615 epan_dissect_reset(edt);
3616 rec->block = block;
3618 return passed || fdata->dependent_of_displayed;
3621 static gboolean
3622 process_new_idbs(wtap *wth, wtap_dumper *pdh, int *err, gchar **err_info)
3624 wtap_block_t if_data;
3626 while ((if_data = wtap_get_next_interface_description(wth)) != NULL) {
3628 * Only add interface blocks if the output file supports (meaning
3629 * *requires*) them.
3631 * That mean that the abstract interface provided by libwiretap
3632 * involves WTAP_BLOCK_IF_ID_AND_INFO blocks.
3634 if (pdh != NULL) {
3635 if (wtap_file_type_subtype_supports_block(wtap_dump_file_type_subtype(pdh), WTAP_BLOCK_IF_ID_AND_INFO) != BLOCK_NOT_SUPPORTED) {
3636 if (!wtap_dump_add_idb(pdh, if_data, err, err_info))
3637 return FALSE;
3641 return TRUE;
3644 static pass_status_t
3645 process_cap_file_second_pass(capture_file *cf, wtap_dumper *pdh,
3646 int *err, gchar **err_info,
3647 volatile guint32 *err_framenum,
3648 int max_write_packet_count)
3650 wtap_rec rec;
3651 Buffer buf;
3652 int framenum = 0;
3653 int write_framenum = 0;
3654 frame_data *fdata;
3655 gboolean filtering_tap_listeners;
3656 guint tap_flags;
3657 epan_dissect_t *edt = NULL;
3658 pass_status_t status = PASS_SUCCEEDED;
3661 * Process whatever IDBs we haven't seen yet. This will be all
3662 * the IDBs in the file, as we've finished reading it; they'll
3663 * all be at the beginning of the output file.
3665 if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
3666 *err_framenum = 0;
3667 return PASS_WRITE_ERROR;
3670 wtap_rec_init(&rec);
3671 ws_buffer_init(&buf, 1514);
3673 /* Do we have any tap listeners with filters? */
3674 filtering_tap_listeners = have_filtering_tap_listeners();
3676 /* Get the union of the flags for all tap listeners. */
3677 tap_flags = union_of_tap_listener_flags();
3679 if (do_dissection) {
3680 gboolean create_proto_tree;
3683 * Determine whether we need to create a protocol tree.
3684 * We do if:
3686 * we're going to apply a display filter;
3688 * we're going to print the protocol tree;
3690 * one of the tap listeners requires a protocol tree;
3692 * we have custom columns (which require field values, which
3693 * currently requires that we build a protocol tree).
3695 create_proto_tree =
3696 (cf->dfcode || print_details || filtering_tap_listeners ||
3697 (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo) || dissect_color);
3699 ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
3701 /* The protocol tree will be "visible", i.e., nothing faked, only if
3702 we're printing packet details, which is true if we're printing stuff
3703 ("print_packet_info" is true) and we're in verbose mode
3704 ("packet_details" is true). But if we specified certain fields with
3705 "-e", we'll prime those directly later. */
3706 bool visible = print_packet_info && print_details && output_fields_num_fields(output_fields) == 0;
3707 edt = epan_dissect_new(cf->epan, create_proto_tree, visible);
3711 * Force synchronous resolution of IP addresses; in this pass, we
3712 * can't do it in the background and fix up past dissections.
3714 set_resolution_synchrony(TRUE);
3716 for (framenum = 1; framenum <= (int)cf->count; framenum++) {
3717 if (read_interrupted) {
3718 status = PASS_INTERRUPTED;
3719 break;
3721 fdata = frame_data_sequence_find(cf->provider.frames, framenum);
3722 if (!wtap_seek_read(cf->provider.wth, fdata->file_off, &rec, &buf, err,
3723 err_info)) {
3724 /* Error reading from the input file. */
3725 status = PASS_READ_ERROR;
3726 break;
3728 ws_debug("tshark: invoking process_packet_second_pass() for frame #%d", framenum);
3729 if (process_packet_second_pass(cf, edt, fdata, &rec, &buf, tap_flags)) {
3730 /* Either there's no read filtering or this packet passed the
3731 filter, so, if we're writing to a capture file, write
3732 this packet out. */
3733 write_framenum++;
3734 if (pdh != NULL) {
3735 ws_debug("tshark: writing packet #%d to outfile packet #%d", framenum, write_framenum);
3736 if (!wtap_dump(pdh, &rec, ws_buffer_start_ptr(&buf), err, err_info)) {
3737 /* Error writing to the output file. */
3738 ws_debug("tshark: error writing to a capture file (%d)", *err);
3739 *err_framenum = framenum;
3740 status = PASS_WRITE_ERROR;
3741 break;
3743 /* Stop reading if we hit a stop condition */
3744 if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) {
3745 ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count);
3746 *err = 0; /* This is not an error */
3747 break;
3751 wtap_rec_reset(&rec);
3754 if (edt)
3755 epan_dissect_free(edt);
3757 ws_buffer_free(&buf);
3758 wtap_rec_cleanup(&rec);
3760 return status;
3763 static pass_status_t
3764 process_cap_file_single_pass(capture_file *cf, wtap_dumper *pdh,
3765 int max_packet_count, gint64 max_byte_count,
3766 int max_write_packet_count,
3767 int *err, gchar **err_info,
3768 volatile guint32 *err_framenum)
3770 wtap_rec rec;
3771 Buffer buf;
3772 gboolean create_proto_tree = FALSE;
3773 gboolean filtering_tap_listeners;
3774 guint tap_flags;
3775 int framenum = 0;
3776 int write_framenum = 0;
3777 epan_dissect_t *edt = NULL;
3778 gint64 data_offset;
3779 pass_status_t status = PASS_SUCCEEDED;
3781 wtap_rec_init(&rec);
3782 ws_buffer_init(&buf, 1514);
3784 /* Do we have any tap listeners with filters? */
3785 filtering_tap_listeners = have_filtering_tap_listeners();
3787 /* Get the union of the flags for all tap listeners. */
3788 tap_flags = union_of_tap_listener_flags();
3790 if (do_dissection) {
3792 * Determine whether we need to create a protocol tree.
3793 * We do if:
3795 * we're going to apply a read filter;
3797 * we're going to apply a display filter;
3799 * we're going to print the protocol tree;
3801 * one of the tap listeners is going to apply a filter;
3803 * one of the tap listeners requires a protocol tree;
3805 * a postdissector wants field values or protocols
3806 * on the first pass;
3808 * we have custom columns (which require field values, which
3809 * currently requires that we build a protocol tree).
3811 create_proto_tree =
3812 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
3813 (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
3814 have_custom_cols(&cf->cinfo) || dissect_color);
3816 ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
3818 /* The protocol tree will be "visible", i.e., nothing faked, only if
3819 we're printing packet details, which is true if we're printing stuff
3820 ("print_packet_info" is true) and we're in verbose mode
3821 ("packet_details" is true). But if we specified certain fields with
3822 "-e", we'll prime those directly later. */
3823 bool visible = print_packet_info && print_details && output_fields_num_fields(output_fields) == 0;
3824 edt = epan_dissect_new(cf->epan, create_proto_tree, visible);
3828 * Force synchronous resolution of IP addresses; we're doing only
3829 * one pass, so we can't do it in the background and fix up past
3830 * dissections.
3832 set_resolution_synchrony(TRUE);
3834 *err = 0;
3835 while (wtap_read(cf->provider.wth, &rec, &buf, err, err_info, &data_offset)) {
3836 if (read_interrupted) {
3837 status = PASS_INTERRUPTED;
3838 break;
3840 framenum++;
3843 * Process whatever IDBs we haven't seen yet.
3845 if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
3846 *err_framenum = framenum;
3847 status = PASS_WRITE_ERROR;
3848 break;
3851 ws_debug("tshark: processing packet #%d", framenum);
3853 reset_epan_mem(cf, edt, create_proto_tree, print_packet_info && print_details);
3855 if (process_packet_single_pass(cf, edt, data_offset, &rec, &buf, tap_flags)) {
3856 /* Either there's no read filtering or this packet passed the
3857 filter, so, if we're writing to a capture file, write
3858 this packet out. */
3859 write_framenum++;
3860 if (pdh != NULL) {
3861 ws_debug("tshark: writing packet #%d to outfile as #%d",
3862 framenum, write_framenum);
3863 if (!wtap_dump(pdh, &rec, ws_buffer_start_ptr(&buf), err, err_info)) {
3864 /* Error writing to the output file. */
3865 ws_debug("tshark: error writing to a capture file (%d)", *err);
3866 *err_framenum = framenum;
3867 status = PASS_WRITE_ERROR;
3868 break;
3872 /* Stop reading if we hit a stop condition */
3873 if (max_packet_count > 0 && framenum >= max_packet_count) {
3874 ws_debug("tshark: max_packet_count (%d) reached", max_packet_count);
3875 *err = 0; /* This is not an error */
3876 break;
3878 if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) {
3879 ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count);
3880 *err = 0; /* This is not an error */
3881 break;
3883 if (max_byte_count != 0 && data_offset >= max_byte_count) {
3884 ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached",
3885 data_offset, max_byte_count);
3886 *err = 0; /* This is not an error */
3887 break;
3889 wtap_rec_reset(&rec);
3891 if (status == PASS_SUCCEEDED) {
3892 if (*err != 0) {
3893 /* Error reading from the input file. */
3894 status = PASS_READ_ERROR;
3895 } else {
3897 * Process whatever IDBs we haven't seen yet.
3899 if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
3900 *err_framenum = framenum;
3901 status = PASS_WRITE_ERROR;
3906 if (edt)
3907 epan_dissect_free(edt);
3909 ws_buffer_free(&buf);
3910 wtap_rec_cleanup(&rec);
3912 return status;
3915 static process_file_status_t
3916 process_cap_file(capture_file *cf, char *save_file, int out_file_type,
3917 gboolean out_file_name_res, int max_packet_count, gint64 max_byte_count,
3918 int max_write_packet_count)
3920 process_file_status_t status = PROCESS_FILE_SUCCEEDED;
3921 wtap_dumper *pdh;
3922 #ifndef _WIN32
3923 struct sigaction action, oldaction;
3924 #endif
3925 int err = 0, err_pass1 = 0;
3926 gchar *err_info = NULL, *err_info_pass1 = NULL;
3927 volatile guint32 err_framenum;
3928 wtap_dump_params params = WTAP_DUMP_PARAMS_INIT;
3929 char *shb_user_appl;
3930 pass_status_t first_pass_status, second_pass_status;
3931 gint64 elapsed_start;
3933 if (save_file != NULL) {
3934 /* Set up to write to the capture file. */
3935 wtap_dump_params_init_no_idbs(&params, cf->provider.wth);
3937 /* If we don't have an application name add TShark */
3938 if (wtap_block_get_string_option_value(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, &shb_user_appl) != WTAP_OPTTYPE_SUCCESS) {
3939 /* this is free'd by wtap_block_unref() later */
3940 wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, "%s", get_appname_and_version());
3942 if (capture_comments != NULL) {
3943 for (guint i = 0; i < capture_comments->len; i++) {
3944 wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0),
3945 OPT_COMMENT, "%s",
3946 (char *)g_ptr_array_index(capture_comments, i));
3950 ws_debug("tshark: writing format type %d, to %s", out_file_type, save_file);
3951 if (strcmp(save_file, "-") == 0) {
3952 /* Write to the standard output. */
3953 pdh = wtap_dump_open_stdout(out_file_type, WTAP_UNCOMPRESSED, &params,
3954 &err, &err_info);
3955 } else {
3956 pdh = wtap_dump_open(save_file, out_file_type, WTAP_UNCOMPRESSED, &params,
3957 &err, &err_info);
3960 g_free(params.idb_inf);
3961 params.idb_inf = NULL;
3963 if (pdh == NULL) {
3964 /* We couldn't set up to write to the capture file. */
3965 cfile_dump_open_failure_message(save_file, err, err_info,
3966 out_file_type);
3967 status = PROCESS_FILE_NO_FILE_PROCESSED;
3968 goto out;
3970 } else {
3971 /* Set up to print packet information. */
3972 if (print_packet_info) {
3973 if (!write_preamble(cf)) {
3974 show_print_file_io_error();
3975 status = PROCESS_FILE_NO_FILE_PROCESSED;
3976 goto out;
3979 pdh = NULL;
3982 #ifdef _WIN32
3983 /* Catch a CTRL+C event and, if we get it, clean up and exit. */
3984 SetConsoleCtrlHandler(read_cleanup, TRUE);
3985 #else /* _WIN32 */
3986 /* Catch SIGINT and SIGTERM and, if we get either of them,
3987 clean up and exit. If SIGHUP isn't being ignored, catch
3988 it too and, if we get it, clean up and exit.
3990 We restart any read that was in progress, so that it doesn't
3991 disrupt reading from the sync pipe. The signal handler tells
3992 the capture child to finish; it will report that it finished,
3993 or will exit abnormally, so we'll stop reading from the sync
3994 pipe, pick up the exit status, and quit. */
3995 memset(&action, 0, sizeof(action));
3996 action.sa_handler = read_cleanup;
3997 action.sa_flags = SA_RESTART;
3998 sigemptyset(&action.sa_mask);
3999 sigaction(SIGTERM, &action, NULL);
4000 sigaction(SIGINT, &action, NULL);
4001 sigaction(SIGHUP, NULL, &oldaction);
4002 if (oldaction.sa_handler == SIG_DFL)
4003 sigaction(SIGHUP, &action, NULL);
4004 #endif /* _WIN32 */
4006 if (perform_two_pass_analysis) {
4007 ws_debug("tshark: perform_two_pass_analysis, do_dissection=%s", do_dissection ? "TRUE" : "FALSE");
4009 elapsed_start = g_get_monotonic_time();
4010 first_pass_status = process_cap_file_first_pass(cf, max_packet_count,
4011 max_byte_count,
4012 &err_pass1,
4013 &err_info_pass1);
4014 tshark_elapsed.elapsed_first_pass = g_get_monotonic_time() - elapsed_start;
4016 ws_debug("tshark: done with first pass");
4018 if (first_pass_status == PASS_INTERRUPTED) {
4019 /* The first pass was interrupted; skip the second pass.
4020 It won't be run, so it won't get an error. */
4021 second_pass_status = PASS_SUCCEEDED;
4022 } else {
4024 * If we got a read error on the first pass, we still do the second
4025 * pass, so we can at least process the packets we read, and then
4026 * report the first-pass error after the second pass (and before
4027 * we report any second-pass errors), so all the errors show up
4028 * at the end.
4030 elapsed_start = g_get_monotonic_time();
4031 second_pass_status = process_cap_file_second_pass(cf, pdh, &err, &err_info,
4032 &err_framenum,
4033 max_write_packet_count);
4034 tshark_elapsed.elapsed_second_pass = g_get_monotonic_time() - elapsed_start;
4036 ws_debug("tshark: done with second pass");
4039 else {
4040 /* !perform_two_pass_analysis */
4041 ws_debug("tshark: perform one pass analysis, do_dissection=%s", do_dissection ? "TRUE" : "FALSE");
4043 first_pass_status = PASS_SUCCEEDED; /* There is no first pass */
4045 elapsed_start = g_get_monotonic_time();
4046 second_pass_status = process_cap_file_single_pass(cf, pdh,
4047 max_packet_count,
4048 max_byte_count,
4049 max_write_packet_count,
4050 &err, &err_info,
4051 &err_framenum);
4052 tshark_elapsed.elapsed_first_pass = g_get_monotonic_time() - elapsed_start;
4054 ws_debug("tshark: done with single pass");
4057 if (first_pass_status != PASS_SUCCEEDED ||
4058 second_pass_status != PASS_SUCCEEDED) {
4060 * At least one of the passes didn't succeed; either it got a failure
4061 * or it was interrupted.
4063 if (first_pass_status != PASS_INTERRUPTED ||
4064 second_pass_status != PASS_INTERRUPTED) {
4065 /* At least one of the passes got an error. */
4066 ws_debug("tshark: something failed along the line (%d)", err);
4068 * If we're printing packet data, and the standard output and error
4069 * are going to the same place, flush the standard output, so everything
4070 * buffered up is written, and then print a newline to the standard
4071 * error before printing the error message, to separate it from the
4072 * packet data. (Alas, that only works on UN*X; st_dev is meaningless,
4073 * and the _fstat() documentation at Microsoft doesn't indicate whether
4074 * st_ino is even supported.)
4076 #ifndef _WIN32
4077 if (print_packet_info) {
4078 ws_statb64 stat_stdout, stat_stderr;
4080 if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
4081 if (stat_stdout.st_dev == stat_stderr.st_dev &&
4082 stat_stdout.st_ino == stat_stderr.st_ino) {
4083 fflush(stdout);
4084 fprintf(stderr, "\n");
4088 #endif
4090 /* Report status of pass 1 of two-pass processing. */
4091 switch (first_pass_status) {
4093 case PASS_SUCCEEDED:
4094 /* No problem. */
4095 break;
4097 case PASS_READ_ERROR:
4098 /* Read error. */
4099 cfile_read_failure_message(cf->filename, err_pass1, err_info_pass1);
4100 status = PROCESS_FILE_ERROR;
4101 break;
4103 case PASS_WRITE_ERROR:
4104 /* Won't happen on the first pass. */
4105 break;
4107 case PASS_INTERRUPTED:
4108 /* Not an error, so nothing to report. */
4109 status = PROCESS_FILE_INTERRUPTED;
4110 break;
4113 /* Report status of pass 2 of two-pass processing or the only pass
4114 of one-pass processing. */
4115 switch (second_pass_status) {
4117 case PASS_SUCCEEDED:
4118 /* No problem. */
4119 break;
4121 case PASS_READ_ERROR:
4122 /* Read error. */
4123 cfile_read_failure_message(cf->filename, err, err_info);
4124 status = PROCESS_FILE_ERROR;
4125 break;
4127 case PASS_WRITE_ERROR:
4128 /* Write error.
4129 XXX - framenum is not necessarily the frame number in
4130 the input file if there was a read filter. */
4131 cfile_write_failure_message(cf->filename, save_file, err, err_info,
4132 err_framenum, out_file_type);
4133 status = PROCESS_FILE_ERROR;
4134 break;
4136 case PASS_INTERRUPTED:
4137 /* Not an error, so nothing to report. */
4138 status = PROCESS_FILE_INTERRUPTED;
4139 break;
4142 if (save_file != NULL) {
4143 if (second_pass_status != PASS_WRITE_ERROR) {
4144 if (pdh && out_file_name_res) {
4145 /* XXX: This doesn't work as expected. First, it should be
4146 * moved to between the first and second passes (if doing
4147 * two-pass mode), so that the new NRB appears before packets,
4148 * which is better for subsequent one-pass mode. It never works
4149 * well in one-pass mode.
4151 * Second, it only writes hosts that we've done lookups for,
4152 * which means unless packet details are printed (or there's
4153 * a display filter that matches something that will do a host
4154 * lookup, e.g. -Y "ip") it doesn't actually have anything
4155 * in the list to save. Notably, that includes the case of
4156 * "tshark [-2] -H hosts.txt -r <infile> -w <outfile>",
4157 * which a user would certainly expect to dissect packets,
4158 * lookup hostnames, and add them to an NRB for later use.
4159 * A workaround is if "-V > /dev/null" is added, but who
4160 * expects that?
4162 * A third issue is that name resolution blocks aren't
4163 * written for live captures.
4165 if (!wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list())) {
4166 cmdarg_err("The file format \"%s\" doesn't support name resolution information.",
4167 wtap_file_type_subtype_name(out_file_type));
4170 /* Now close the capture file. */
4171 if (!wtap_dump_close(pdh, NULL, &err, &err_info)) {
4172 cfile_close_failure_message(save_file, err, err_info);
4173 status = PROCESS_FILE_ERROR;
4175 } else {
4176 /* We got a write error; it was reported, so just close the dump file
4177 without bothering to check for further errors. */
4178 wtap_dump_close(pdh, NULL, &err, &err_info);
4179 g_free(err_info);
4180 status = PROCESS_FILE_ERROR;
4182 } else {
4183 if (print_packet_info) {
4184 if (!write_finale()) {
4185 show_print_file_io_error();
4186 status = PROCESS_FILE_ERROR;
4191 out:
4192 wtap_close(cf->provider.wth);
4193 cf->provider.wth = NULL;
4195 wtap_dump_params_cleanup(&params);
4197 return status;
4200 static gboolean
4201 process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset,
4202 wtap_rec *rec, Buffer *buf, guint tap_flags _U_)
4204 frame_data fdata;
4205 column_info *cinfo;
4206 gboolean passed;
4207 wtap_block_t block = NULL;
4208 gint64 elapsed_start;
4210 /* Count this packet. */
4211 cf->count++;
4213 /* If we're not running a display filter and we're not printing any
4214 packet information, we don't need to do a dissection. This means
4215 that all packets can be marked as 'passed'. */
4216 passed = TRUE;
4218 frame_data_init(&fdata, cf->count, rec, offset, cum_bytes);
4220 /* If we're going to print packet information, or we're going to
4221 run a read filter, or we're going to process taps, set up to
4222 do a dissection and do so. (This is the one and only pass
4223 over the packets, so, if we'll be printing packet information
4224 or running taps, we'll be doing it here.) */
4225 if (edt) {
4226 /* If we're running a filter, prime the epan_dissect_t with that
4227 filter. */
4228 if (cf->dfcode)
4229 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
4231 /* This is the first and only pass, so prime the epan_dissect_t
4232 with the hfids postdissectors want on the first pass. */
4233 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
4235 col_custom_prime_edt(edt, &cf->cinfo);
4237 output_fields_prime_edt(edt, output_fields);
4238 /* The PDML spec requires a 'geninfo' pseudo-protocol that needs
4239 * information from our 'frame' protocol.
4241 if (output_fields_num_fields(output_fields) != 0 &&
4242 output_action == WRITE_XML) {
4243 epan_dissect_prime_with_hfid(edt, proto_registrar_get_id_byname("frame"));
4246 /* We only need the columns if either
4247 1) some tap or filter needs the columns
4249 2) we're printing packet info but we're *not* verbose; in verbose
4250 mode, we print the protocol tree, not the protocol summary.
4252 3) there is a column mapped as an individual field */
4253 if ((tap_listeners_require_columns()) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields) || dfilter_requires_columns(cf->dfcode))
4254 cinfo = &cf->cinfo;
4255 else
4256 cinfo = NULL;
4258 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
4259 &cf->provider.ref, cf->provider.prev_dis);
4260 if (cf->provider.ref == &fdata) {
4261 ref_frame = fdata;
4262 cf->provider.ref = &ref_frame;
4265 if (dissect_color) {
4266 color_filters_prime_edt(edt);
4267 fdata.need_colorize = 1;
4270 /* epan_dissect_run (and epan_dissect_reset) unref the block.
4271 * We need it later, e.g. in order to copy the options. */
4272 block = wtap_block_ref(rec->block);
4273 elapsed_start = g_get_monotonic_time();
4274 epan_dissect_run_with_taps(edt, cf->cd_t, rec,
4275 frame_tvbuff_new_buffer(&cf->provider, &fdata, buf),
4276 &fdata, cinfo);
4277 tshark_elapsed.first_pass.dissect += g_get_monotonic_time() - elapsed_start;
4279 /* Run the filter if we have it. */
4280 if (cf->dfcode) {
4281 elapsed_start = g_get_monotonic_time();
4282 passed = dfilter_apply_edt(cf->dfcode, edt);
4283 tshark_elapsed.first_pass.dfilter_filter += g_get_monotonic_time() - elapsed_start;
4287 if (passed) {
4288 frame_data_set_after_dissect(&fdata, &cum_bytes);
4290 /* Process this packet. */
4291 if (print_packet_info) {
4292 /* We're printing packet information; print the information for
4293 this packet. */
4294 ws_assert(edt);
4295 print_packet(cf, edt);
4297 /* If we're doing "line-buffering", flush the standard output
4298 after every packet. See the comment above, for the "-l"
4299 option, for an explanation of why we do that. */
4300 if (line_buffered)
4301 fflush(stdout);
4303 if (ferror(stdout)) {
4304 show_print_file_io_error();
4305 exit(2);
4309 /* this must be set after print_packet() [bug #8160] */
4310 prev_dis_frame = fdata;
4311 cf->provider.prev_dis = &prev_dis_frame;
4314 prev_cap_frame = fdata;
4315 cf->provider.prev_cap = &prev_cap_frame;
4317 if (edt) {
4318 epan_dissect_reset(edt);
4319 frame_data_destroy(&fdata);
4320 rec->block = block;
4322 return passed;
4325 static gboolean
4326 write_preamble(capture_file *cf)
4328 switch (output_action) {
4330 case WRITE_TEXT:
4331 return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
4333 case WRITE_XML:
4334 if (print_details)
4335 write_pdml_preamble(stdout, cf->filename);
4336 else
4337 write_psml_preamble(&cf->cinfo, stdout);
4338 return !ferror(stdout);
4340 case WRITE_FIELDS:
4341 write_fields_preamble(output_fields, stdout);
4342 return !ferror(stdout);
4344 case WRITE_JSON:
4345 case WRITE_JSON_RAW:
4346 jdumper = write_json_preamble(stdout);
4347 return !ferror(stdout);
4349 case WRITE_EK:
4350 return TRUE;
4352 default:
4353 ws_assert_not_reached();
4354 return FALSE;
4358 static char *
4359 get_line_buf(size_t len)
4361 static char *line_bufp = NULL;
4362 static size_t line_buf_len = 256;
4363 size_t new_line_buf_len;
4365 for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
4366 new_line_buf_len *= 2)
4368 if (line_bufp == NULL) {
4369 line_buf_len = new_line_buf_len;
4370 line_bufp = (char *)g_malloc(line_buf_len + 1);
4371 } else {
4372 if (new_line_buf_len > line_buf_len) {
4373 line_buf_len = new_line_buf_len;
4374 line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
4377 return line_bufp;
4380 static inline void
4381 put_string(char *dest, const char *str, size_t str_len)
4383 memcpy(dest, str, str_len);
4384 dest[str_len] = '\0';
4387 static inline void
4388 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
4390 size_t i;
4392 for (i = str_len; i < str_with_spaces; i++)
4393 *dest++ = ' ';
4395 put_string(dest, str, str_len);
4398 static inline void
4399 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
4401 size_t i;
4403 memcpy(dest, str, str_len);
4404 for (i = str_len; i < str_with_spaces; i++)
4405 dest[i] = ' ';
4407 dest[str_with_spaces] = '\0';
4410 static gboolean
4411 print_columns(capture_file *cf, const epan_dissect_t *edt)
4413 char *line_bufp;
4414 int i;
4415 size_t buf_offset;
4416 size_t column_len;
4417 size_t col_len;
4418 col_item_t* col_item;
4419 gchar str_format[11];
4420 const color_filter_t *color_filter = NULL;
4422 line_bufp = get_line_buf(256);
4423 buf_offset = 0;
4424 *line_bufp = '\0';
4426 if (dissect_color)
4427 color_filter = edt->pi.fd->color_filter;
4429 for (i = 0; i < cf->cinfo.num_cols; i++) {
4430 col_item = &cf->cinfo.columns[i];
4431 /* Skip columns not marked as visible. */
4432 if (!get_column_visible(i))
4433 continue;
4434 const gchar* col_text = get_column_text(&cf->cinfo, i);
4435 switch (col_item->col_fmt) {
4436 case COL_NUMBER:
4437 column_len = col_len = strlen(col_text);
4438 if (column_len < 5)
4439 column_len = 5;
4440 line_bufp = get_line_buf(buf_offset + column_len);
4441 put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
4442 break;
4444 case COL_CLS_TIME:
4445 case COL_REL_TIME:
4446 case COL_ABS_TIME:
4447 case COL_ABS_YMD_TIME: /* XXX - wider */
4448 case COL_ABS_YDOY_TIME: /* XXX - wider */
4449 case COL_UTC_TIME:
4450 case COL_UTC_YMD_TIME: /* XXX - wider */
4451 case COL_UTC_YDOY_TIME: /* XXX - wider */
4452 column_len = col_len = strlen(col_text);
4453 if (column_len < 10)
4454 column_len = 10;
4455 line_bufp = get_line_buf(buf_offset + column_len);
4456 put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
4457 break;
4459 case COL_DEF_SRC:
4460 case COL_RES_SRC:
4461 case COL_UNRES_SRC:
4462 case COL_DEF_DL_SRC:
4463 case COL_RES_DL_SRC:
4464 case COL_UNRES_DL_SRC:
4465 case COL_DEF_NET_SRC:
4466 case COL_RES_NET_SRC:
4467 case COL_UNRES_NET_SRC:
4468 column_len = col_len = strlen(col_text);
4469 if (column_len < 12)
4470 column_len = 12;
4471 line_bufp = get_line_buf(buf_offset + column_len);
4472 put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
4473 break;
4475 case COL_DEF_DST:
4476 case COL_RES_DST:
4477 case COL_UNRES_DST:
4478 case COL_DEF_DL_DST:
4479 case COL_RES_DL_DST:
4480 case COL_UNRES_DL_DST:
4481 case COL_DEF_NET_DST:
4482 case COL_RES_NET_DST:
4483 case COL_UNRES_NET_DST:
4484 column_len = col_len = strlen(col_text);
4485 if (column_len < 12)
4486 column_len = 12;
4487 line_bufp = get_line_buf(buf_offset + column_len);
4488 put_string_spaces(line_bufp + buf_offset, col_text, col_len, column_len);
4489 break;
4491 default:
4492 column_len = strlen(col_text);
4493 line_bufp = get_line_buf(buf_offset + column_len);
4494 put_string(line_bufp + buf_offset, col_text, column_len);
4495 break;
4497 buf_offset += column_len;
4498 if (i != cf->cinfo.num_cols - 1) {
4500 * This isn't the last column, so we need to print a
4501 * separator between this column and the next.
4503 * If we printed a network source and are printing a
4504 * network destination of the same type next, separate
4505 * them with a UTF-8 right arrow; if we printed a network
4506 * destination and are printing a network source of the same
4507 * type next, separate them with a UTF-8 left arrow;
4508 * otherwise separate them with a space.
4510 * We add enough space to the buffer for " \xe2\x86\x90 "
4511 * or " \xe2\x86\x92 ", even if we're only adding " ".
4513 line_bufp = get_line_buf(buf_offset + 5);
4514 switch (col_item->col_fmt) {
4516 case COL_DEF_SRC:
4517 case COL_RES_SRC:
4518 case COL_UNRES_SRC:
4519 switch (cf->cinfo.columns[i+1].col_fmt) {
4521 case COL_DEF_DST:
4522 case COL_RES_DST:
4523 case COL_UNRES_DST:
4524 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
4525 put_string(line_bufp + buf_offset, str_format, 5);
4526 buf_offset += 5;
4527 break;
4529 default:
4530 put_string(line_bufp + buf_offset, delimiter_char, 1);
4531 buf_offset += 1;
4532 break;
4534 break;
4536 case COL_DEF_DL_SRC:
4537 case COL_RES_DL_SRC:
4538 case COL_UNRES_DL_SRC:
4539 switch (cf->cinfo.columns[i+1].col_fmt) {
4541 case COL_DEF_DL_DST:
4542 case COL_RES_DL_DST:
4543 case COL_UNRES_DL_DST:
4544 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
4545 put_string(line_bufp + buf_offset, str_format, 5);
4546 buf_offset += 5;
4547 break;
4549 default:
4550 put_string(line_bufp + buf_offset, delimiter_char, 1);
4551 buf_offset += 1;
4552 break;
4554 break;
4556 case COL_DEF_NET_SRC:
4557 case COL_RES_NET_SRC:
4558 case COL_UNRES_NET_SRC:
4559 switch (cf->cinfo.columns[i+1].col_fmt) {
4561 case COL_DEF_NET_DST:
4562 case COL_RES_NET_DST:
4563 case COL_UNRES_NET_DST:
4564 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
4565 put_string(line_bufp + buf_offset, str_format, 5);
4566 buf_offset += 5;
4567 break;
4569 default:
4570 put_string(line_bufp + buf_offset, delimiter_char, 1);
4571 buf_offset += 1;
4572 break;
4574 break;
4576 case COL_DEF_DST:
4577 case COL_RES_DST:
4578 case COL_UNRES_DST:
4579 switch (cf->cinfo.columns[i+1].col_fmt) {
4581 case COL_DEF_SRC:
4582 case COL_RES_SRC:
4583 case COL_UNRES_SRC:
4584 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
4585 put_string(line_bufp + buf_offset, str_format, 5);
4586 buf_offset += 5;
4587 break;
4589 default:
4590 put_string(line_bufp + buf_offset, delimiter_char, 1);
4591 buf_offset += 1;
4592 break;
4594 break;
4596 case COL_DEF_DL_DST:
4597 case COL_RES_DL_DST:
4598 case COL_UNRES_DL_DST:
4599 switch (cf->cinfo.columns[i+1].col_fmt) {
4601 case COL_DEF_DL_SRC:
4602 case COL_RES_DL_SRC:
4603 case COL_UNRES_DL_SRC:
4604 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
4605 put_string(line_bufp + buf_offset, str_format, 5);
4606 buf_offset += 5;
4607 break;
4609 default:
4610 put_string(line_bufp + buf_offset, delimiter_char, 1);
4611 buf_offset += 1;
4612 break;
4614 break;
4616 case COL_DEF_NET_DST:
4617 case COL_RES_NET_DST:
4618 case COL_UNRES_NET_DST:
4619 switch (cf->cinfo.columns[i+1].col_fmt) {
4621 case COL_DEF_NET_SRC:
4622 case COL_RES_NET_SRC:
4623 case COL_UNRES_NET_SRC:
4624 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
4625 put_string(line_bufp + buf_offset, str_format, 5);
4626 buf_offset += 5;
4627 break;
4629 default:
4630 put_string(line_bufp + buf_offset, delimiter_char, 1);
4631 buf_offset += 1;
4632 break;
4634 break;
4636 default:
4637 put_string(line_bufp + buf_offset, delimiter_char, 1);
4638 buf_offset += 1;
4639 break;
4644 if (dissect_color && color_filter != NULL)
4645 return print_line_color(print_stream, 0, line_bufp, &color_filter->fg_color, &color_filter->bg_color);
4646 else
4647 return print_line(print_stream, 0, line_bufp);
4650 static gboolean
4651 print_packet(capture_file *cf, epan_dissect_t *edt)
4653 if (print_summary || output_fields_has_cols(output_fields))
4654 /* Just fill in the columns. */
4655 epan_dissect_fill_in_columns(edt, FALSE, TRUE);
4657 /* Print summary columns and/or protocol tree */
4658 switch (output_action) {
4660 case WRITE_TEXT:
4661 if (print_summary && !print_columns(cf, edt))
4662 return FALSE;
4663 if (print_details) {
4664 if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
4665 print_hex, edt, output_only_tables, print_stream))
4666 return FALSE;
4667 if (!print_hex) {
4668 if (!print_line(print_stream, 0, separator))
4669 return FALSE;
4672 break;
4674 case WRITE_XML:
4675 if (print_summary) {
4676 write_psml_columns(edt, stdout, dissect_color);
4677 return !ferror(stdout);
4679 if (print_details) {
4680 write_pdml_proto_tree(output_fields, edt, &cf->cinfo, stdout, dissect_color);
4681 printf("\n");
4682 return !ferror(stdout);
4684 break;
4686 case WRITE_FIELDS:
4687 if (print_summary) {
4688 /*No non-verbose "fields" format */
4689 ws_assert_not_reached();
4691 if (print_details) {
4692 write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
4693 printf("\n");
4694 return !ferror(stdout);
4696 break;
4698 case WRITE_JSON:
4699 if (print_summary)
4700 ws_assert_not_reached();
4701 if (print_details) {
4702 write_json_proto_tree(output_fields, print_dissections_expanded,
4703 print_hex, edt, &cf->cinfo, node_children_grouper, &jdumper);
4704 return !ferror(stdout);
4706 break;
4708 case WRITE_JSON_RAW:
4709 if (print_summary)
4710 ws_assert_not_reached();
4711 if (print_details) {
4712 write_json_proto_tree(output_fields, print_dissections_none,
4713 TRUE, edt, &cf->cinfo, node_children_grouper, &jdumper);
4714 return !ferror(stdout);
4716 break;
4718 case WRITE_EK:
4719 write_ek_proto_tree(output_fields, print_summary, print_hex,
4720 edt, &cf->cinfo, stdout);
4721 return !ferror(stdout);
4723 default:
4724 ws_assert_not_reached();
4727 if (print_hex) {
4728 if (print_summary || print_details) {
4729 if (!print_line(print_stream, 0, ""))
4730 return FALSE;
4732 if (!print_hex_data(print_stream, edt, hexdump_source_option | hexdump_ascii_option))
4733 return FALSE;
4734 if (!print_line(print_stream, 0, separator))
4735 return FALSE;
4737 return TRUE;
4740 static gboolean
4741 write_finale(void)
4743 switch (output_action) {
4745 case WRITE_TEXT:
4746 return print_finale(print_stream);
4748 case WRITE_XML:
4749 if (print_details)
4750 write_pdml_finale(stdout);
4751 else
4752 write_psml_finale(stdout);
4753 return !ferror(stdout);
4755 case WRITE_FIELDS:
4756 write_fields_finale(output_fields, stdout);
4757 return !ferror(stdout);
4759 case WRITE_JSON:
4760 case WRITE_JSON_RAW:
4761 write_json_finale(&jdumper);
4762 return !ferror(stdout);
4764 case WRITE_EK:
4765 return TRUE;
4767 default:
4768 ws_assert_not_reached();
4769 return FALSE;
4773 void
4774 cf_close(capture_file *cf)
4776 if (cf->state == FILE_CLOSED)
4777 return; /* Nothing to do */
4779 if (cf->provider.wth != NULL) {
4780 wtap_close(cf->provider.wth);
4781 cf->provider.wth = NULL;
4783 /* We have no file open... */
4784 if (cf->filename != NULL) {
4785 /* If it's a temporary file, remove it. */
4786 if (cf->is_tempfile)
4787 ws_unlink(cf->filename);
4788 g_free(cf->filename);
4789 cf->filename = NULL;
4792 /* We have no file open. */
4793 cf->state = FILE_CLOSED;
4796 cf_status_t
4797 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
4799 wtap *wth;
4800 gchar *err_info;
4802 wth = wtap_open_offline(fname, type, err, &err_info, perform_two_pass_analysis);
4803 if (wth == NULL)
4804 goto fail;
4806 /* The open succeeded. Fill in the information for this file. */
4808 cf->provider.wth = wth;
4809 cf->f_datalen = 0; /* not used, but set it anyway */
4811 /* Set the file name because we need it to set the follow stream filter.
4812 XXX - is that still true? We need it for other reasons, though,
4813 in any case. */
4814 cf->filename = g_strdup(fname);
4816 /* Indicate whether it's a permanent or temporary file. */
4817 cf->is_tempfile = is_tempfile;
4819 /* No user changes yet. */
4820 cf->unsaved_changes = FALSE;
4822 cf->cd_t = wtap_file_type_subtype(cf->provider.wth);
4823 cf->open_type = type;
4824 cf->count = 0;
4825 cf->drops_known = FALSE;
4826 cf->drops = 0;
4827 cf->snap = wtap_snapshot_length(cf->provider.wth);
4828 nstime_set_zero(&cf->elapsed_time);
4829 cf->provider.ref = NULL;
4830 cf->provider.prev_dis = NULL;
4831 cf->provider.prev_cap = NULL;
4833 cf->state = FILE_READ_IN_PROGRESS;
4835 /* Create new epan session for dissection. */
4836 epan_free(cf->epan);
4837 cf->epan = tshark_epan_new(cf);
4839 wtap_set_cb_new_ipv4(cf->provider.wth, add_ipv4_name);
4840 wtap_set_cb_new_ipv6(cf->provider.wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
4841 wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
4843 return CF_OK;
4845 fail:
4846 cfile_open_failure_message(fname, *err, err_info);
4847 return CF_ERROR;
4850 static void
4851 show_print_file_io_error(void)
4853 switch (errno) {
4855 case ENOSPC:
4856 cmdarg_err("Not all the packets could be printed because there is "
4857 "no space left on the file system.");
4858 break;
4860 #ifdef EDQUOT
4861 case EDQUOT:
4862 cmdarg_err("Not all the packets could be printed because you are "
4863 "too close to, or over your disk quota.");
4864 break;
4865 #endif
4867 case EPIPE:
4869 * This almost certainly means "the next program after us in
4870 * the pipeline exited before we were finished writing", so
4871 * this isn't a real error, it just means we're done. (We
4872 * don't get SIGPIPE because libwireshark ignores SIGPIPE
4873 * to avoid getting killed if writing to the MaxMind process
4874 * gets SIGPIPE because that process died.)
4876 * Presumably either that program exited deliberately (for
4877 * example, "head -N" read N lines and printed them), in
4878 * which case there's no error to report, or it terminated
4879 * due to an error or a signal, in which case *that's* the
4880 * error and that error has been reported.
4882 break;
4884 default:
4885 #ifdef _WIN32
4886 if (errno == EINVAL && _doserrno == ERROR_NO_DATA) {
4888 * XXX - on Windows, a write to a pipe where the read side
4889 * has been closed apparently may return the Windows error
4890 * ERROR_BROKEN_PIPE, which the Visual Studio C library maps
4891 * to EPIPE, or may return the Windows error ERROR_NO_DATA,
4892 * which the Visual Studio C library maps to EINVAL.
4894 * Either of those almost certainly means "the next program
4895 * after us in the pipeline exited before we were finished
4896 * writing", so, if _doserrno is ERROR_NO_DATA, this isn't
4897 * a real error, it just means we're done. (Windows doesn't
4898 * SIGPIPE.)
4900 * Presumably either that program exited deliberately (for
4901 * example, "head -N" read N lines and printed them), in
4902 * which case there's no error to report, or it terminated
4903 * due to an error or a signal, in which case *that's* the
4904 * error and that error has been reported.
4906 break;
4910 * It's a different error; report it, but with the error
4911 * message for _doserrno, which will give more detail
4912 * than just "Invalid argument".
4914 cmdarg_err("An error occurred while printing packets: %s.",
4915 win32strerror(_doserrno));
4916 #else
4917 cmdarg_err("An error occurred while printing packets: %s.",
4918 g_strerror(errno));
4919 #endif
4920 break;
4925 * Report an error in command-line arguments.
4927 static void
4928 tshark_cmdarg_err(const char *msg_format, va_list ap)
4930 fprintf(stderr, "tshark: ");
4931 vfprintf(stderr, msg_format, ap);
4932 fprintf(stderr, "\n");
4936 * Report additional information for an error in command-line arguments.
4938 static void
4939 tshark_cmdarg_err_cont(const char *msg_format, va_list ap)
4941 vfprintf(stderr, msg_format, ap);
4942 fprintf(stderr, "\n");
4945 static void
4946 reset_epan_mem(capture_file *cf,epan_dissect_t *edt, gboolean tree, gboolean visual)
4948 if (!epan_auto_reset || (cf->count < epan_auto_reset_count))
4949 return;
4951 fprintf(stderr, "resetting session.\n");
4953 epan_dissect_cleanup(edt);
4954 epan_free(cf->epan);
4956 cf->epan = tshark_epan_new(cf);
4957 epan_dissect_init(edt, cf->epan, tree, visual);
4958 cf->count = 0;