TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags
[wireshark-sm.git] / tshark.c
blob49442f17206a4497bee479e7ce0f0fa711ed354d
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/please_report_bug.h>
50 #include <wsutil/wslog.h>
51 #include <wsutil/ws_assert.h>
52 #include <wsutil/strtoi.h>
53 #include <cli_main.h>
54 #include <wsutil/version_info.h>
55 #include <wiretap/wtap_opttypes.h>
57 #include "globals.h"
58 #include <epan/timestamp.h>
59 #include <epan/packet.h>
60 #ifdef HAVE_LUA
61 #include <epan/wslua/init_wslua.h>
62 #endif
63 #include <epan/disabled_protos.h>
64 #include <epan/prefs.h>
65 #include <epan/column.h>
66 #include <epan/decode_as.h>
67 #include <epan/print.h>
68 #include <epan/addr_resolv.h>
69 #include <epan/enterprises.h>
70 #include <epan/manuf.h>
71 #include <epan/services.h>
72 #ifdef HAVE_LIBPCAP
73 #include "ui/capture_ui_utils.h"
74 #endif
75 #include "ui/taps.h"
76 #include "ui/util.h"
77 #include "ui/ws_ui_util.h"
78 #include "ui/decode_as_utils.h"
79 #include "wsutil/filter_files.h"
80 #include "ui/cli/tshark-tap.h"
81 #include "ui/cli/tap-exportobject.h"
82 #include "ui/tap_export_pdu.h"
83 #include "ui/dissect_opts.h"
84 #include "ui/ssl_key_export.h"
85 #include "ui/failure_message.h"
86 #include "ui/capture_opts.h"
87 #if defined(HAVE_LIBSMI)
88 #include "epan/oids.h"
89 #endif
90 #include "epan/maxmind_db.h"
91 #include <epan/epan_dissect.h>
92 #include <epan/tap.h>
93 #include <epan/stat_tap_ui.h>
94 #include <epan/conversation_table.h>
95 #include <epan/srt_table.h>
96 #include <epan/rtd_table.h>
97 #include <epan/ex-opt.h>
98 #include <epan/exported_pdu.h>
99 #include <epan/secrets.h>
101 #include "capture/capture-pcap-util.h"
103 #ifdef HAVE_LIBPCAP
104 #include "capture/capture_ifinfo.h"
105 #ifdef _WIN32
106 #include "capture/capture-wpcap.h"
107 #endif /* _WIN32 */
108 #include <capture/capture_session.h>
109 #include <capture/capture_sync.h>
110 #include <ui/capture_info.h>
111 #endif /* HAVE_LIBPCAP */
112 #include <epan/funnel.h>
114 #include <wsutil/str_util.h>
115 #include <wsutil/utf8_entities.h>
116 #include <wsutil/json_dumper.h>
117 #include <wsutil/wslog.h>
118 #ifdef _WIN32
119 #include <wsutil/win32-utils.h>
120 #endif
122 #include "extcap.h"
124 #ifdef HAVE_PLUGINS
125 #include <wsutil/codecs.h>
126 #include <wsutil/plugins.h>
127 #endif
129 /* Additional exit codes */
130 #define INVALID_EXPORT 2
131 #define INVALID_TAP 2
132 #define INVALID_CAPTURE 2
134 #define LONGOPT_EXPORT_OBJECTS LONGOPT_BASE_APPLICATION+1
135 #define LONGOPT_COLOR LONGOPT_BASE_APPLICATION+2
136 #define LONGOPT_NO_DUPLICATE_KEYS LONGOPT_BASE_APPLICATION+3
137 #define LONGOPT_ELASTIC_MAPPING_FILTER LONGOPT_BASE_APPLICATION+4
138 #define LONGOPT_EXPORT_TLS_SESSION_KEYS LONGOPT_BASE_APPLICATION+5
139 #define LONGOPT_CAPTURE_COMMENT LONGOPT_BASE_APPLICATION+6
140 #define LONGOPT_HEXDUMP LONGOPT_BASE_APPLICATION+7
141 #define LONGOPT_SELECTED_FRAME LONGOPT_BASE_APPLICATION+8
142 #define LONGOPT_PRINT_TIMERS LONGOPT_BASE_APPLICATION+9
143 #define LONGOPT_GLOBAL_PROFILE LONGOPT_BASE_APPLICATION+10
144 #define LONGOPT_COMPRESS LONGOPT_BASE_APPLICATION+11
146 capture_file cfile;
148 static uint32_t cum_bytes;
149 static frame_data ref_frame;
150 static frame_data prev_dis_frame;
151 static frame_data prev_cap_frame;
153 static bool perform_two_pass_analysis;
154 static uint32_t epan_auto_reset_count;
155 static bool epan_auto_reset;
157 static uint32_t selected_frame_number;
160 * The way the packet decode is to be written.
162 typedef enum {
163 WRITE_NONE, /* dummy initial state */
164 WRITE_TEXT, /* summary or detail text */
165 WRITE_XML, /* PDML or PSML */
166 WRITE_FIELDS, /* User defined list of fields */
167 WRITE_JSON, /* JSON */
168 WRITE_JSON_RAW, /* JSON only raw hex */
169 WRITE_EK /* JSON bulk insert to Elasticsearch */
170 /* Add CSV and the like here */
171 } output_action_e;
173 static output_action_e output_action;
174 static bool do_dissection; /* true if we have to dissect each packet */
175 static bool print_packet_info; /* true if we're to print packet information */
176 static bool print_summary; /* true if we're to print packet summary information */
177 static bool print_details; /* true if we're to print packet details information */
178 static bool print_hex; /* true if we're to print hex/ascii information */
179 static bool line_buffered;
180 static bool quiet;
181 static bool really_quiet;
182 static char* delimiter_char = " ";
183 static bool dissect_color;
184 static unsigned hexdump_source_option = HEXDUMP_SOURCE_MULTI; /* Default - Enable legacy multi-source mode */
185 static unsigned hexdump_ascii_option = HEXDUMP_ASCII_INCLUDE; /* Default - Enable legacy undelimited ASCII dump */
187 static print_format_e print_format = PR_FMT_TEXT;
188 static print_stream_t *print_stream;
190 static char *output_file_name;
192 static output_fields_t* output_fields;
194 static bool no_duplicate_keys;
195 static proto_node_children_grouper_func node_children_grouper = proto_node_group_children_by_unique;
197 static json_dumper jdumper;
199 /* The line separator used between packets, changeable via the -S option */
200 static const char *separator = "";
202 /* Per-file comments to be added to the output file. */
203 static GPtrArray *capture_comments;
205 static bool prefs_loaded;
207 #ifdef HAVE_LIBPCAP
209 * true if we're to print packet counts to keep track of captured packets.
211 static bool print_packet_counts;
213 static capture_options global_capture_opts;
214 static capture_session global_capture_session;
215 static info_data_t global_info_data;
217 #ifdef SIGINFO
218 static bool infodelay; /* if true, don't print capture info in SIGINFO handler */
219 static bool infoprint; /* if true, print capture info after clearing infodelay */
220 #endif /* SIGINFO */
222 static bool capture(void);
223 static bool capture_input_new_file(capture_session *cap_session,
224 char *new_file);
225 static void capture_input_new_packets(capture_session *cap_session,
226 int to_read);
227 static void capture_input_drops(capture_session *cap_session, uint32_t dropped,
228 const char* interface_name);
229 static void capture_input_error(capture_session *cap_session,
230 char *error_msg, char *secondary_error_msg);
231 static void capture_input_cfilter_error(capture_session *cap_session,
232 unsigned i, const char *error_message);
233 static void capture_input_closed(capture_session *cap_session, char *msg);
235 static void report_counts(void);
236 #ifdef _WIN32
237 static BOOL WINAPI capture_cleanup(DWORD);
238 #else /* _WIN32 */
239 static void capture_cleanup(int);
240 #ifdef SIGINFO
241 static void report_counts_siginfo(int);
242 #endif /* SIGINFO */
243 #endif /* _WIN32 */
244 #endif /* HAVE_LIBPCAP */
246 static void reset_epan_mem(capture_file *cf, epan_dissect_t *edt, bool tree, bool visual);
248 typedef enum {
249 PROCESS_FILE_SUCCEEDED,
250 PROCESS_FILE_NO_FILE_PROCESSED,
251 PROCESS_FILE_ERROR,
252 PROCESS_FILE_INTERRUPTED
253 } process_file_status_t;
254 static process_file_status_t process_cap_file(capture_file *, char *, int, bool, int, int64_t, int, wtap_compression_type);
256 static bool process_packet_single_pass(capture_file *cf,
257 epan_dissect_t *edt, int64_t offset, wtap_rec *rec, Buffer *buf,
258 unsigned tap_flags);
259 static void show_print_file_io_error(void);
260 static bool write_preamble(capture_file *cf);
261 static bool print_packet(capture_file *cf, epan_dissect_t *edt);
262 static bool write_finale(void);
264 static GHashTable *output_only_tables;
266 static bool opt_print_timers;
267 struct elapsed_pass_s {
268 int64_t dissect;
269 int64_t dfilter_read;
270 int64_t dfilter_filter;
272 static struct {
273 int64_t dfilter_expand;
274 int64_t dfilter_compile;
275 struct elapsed_pass_s first_pass;
276 int64_t elapsed_first_pass;
277 struct elapsed_pass_s second_pass;
278 int64_t elapsed_second_pass;
280 tshark_elapsed;
282 static void
283 print_elapsed_json(const char *cf_name, const char *dfilter)
285 json_dumper dumper = {
286 .output_file = stderr,
287 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT,
290 if (tshark_elapsed.elapsed_first_pass == 0) {
291 // Should not happen
292 ws_warning("Print timers requested but no timing info provided");
293 return;
296 #define DUMP(name, val) \
297 json_dumper_set_member_name(&dumper, name); \
298 json_dumper_value_anyf(&dumper, "%"PRId64, val)
300 json_dumper_begin_object(&dumper);
301 json_dumper_set_member_name(&dumper, "version");
302 json_dumper_value_string(&dumper, get_ws_vcs_version_info_short());
303 if (cf_name) {
304 json_dumper_set_member_name(&dumper, "path");
305 json_dumper_value_string(&dumper, cf_name);
307 if (dfilter) {
308 json_dumper_set_member_name(&dumper, "filter");
309 json_dumper_value_string(&dumper, dfilter);
311 json_dumper_set_member_name(&dumper, "time_unit");
312 json_dumper_value_string(&dumper, "microseconds");
313 DUMP("elapsed", tshark_elapsed.elapsed_first_pass +
314 tshark_elapsed.elapsed_second_pass);
315 DUMP("dfilter_expand", tshark_elapsed.dfilter_expand);
316 DUMP("dfilter_compile", tshark_elapsed.dfilter_compile);
317 json_dumper_begin_array(&dumper);
318 json_dumper_begin_object(&dumper);
319 DUMP("elapsed", tshark_elapsed.elapsed_first_pass);
320 DUMP("dissect", tshark_elapsed.first_pass.dissect);
321 DUMP("display_filter", tshark_elapsed.first_pass.dfilter_filter);
322 DUMP("read_filter", tshark_elapsed.first_pass.dfilter_read);
323 json_dumper_end_object(&dumper);
324 if (tshark_elapsed.elapsed_second_pass) {
325 json_dumper_begin_object(&dumper);
326 DUMP("elapsed", tshark_elapsed.elapsed_second_pass);
327 DUMP("dissect", tshark_elapsed.second_pass.dissect);
328 DUMP("display_filter", tshark_elapsed.second_pass.dfilter_filter);
329 DUMP("read_filter", tshark_elapsed.second_pass.dfilter_read);
330 json_dumper_end_object(&dumper);
332 json_dumper_end_array(&dumper);
333 json_dumper_end_object(&dumper);
334 json_dumper_finish(&dumper);
337 static void
338 list_capture_types(void)
340 GArray *writable_type_subtypes;
342 fprintf(stderr, "tshark: The available capture file types for the \"-F\" flag are:\n");
343 writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME);
344 for (unsigned i = 0; i < writable_type_subtypes->len; i++) {
345 int ft = g_array_index(writable_type_subtypes, int, i);
346 fprintf(stderr, " %s - %s\n", wtap_file_type_subtype_name(ft),
347 wtap_file_type_subtype_description(ft));
349 g_array_free(writable_type_subtypes, TRUE);
352 static void
353 list_output_compression_types(void) {
354 GSList *output_compression_types;
356 fprintf(stderr, "tshark: The available output compression type(s) for the \"--compress\" flag are:\n");
357 output_compression_types = wtap_get_all_output_compression_type_names_list();
358 for (GSList *compression_type = output_compression_types;
359 compression_type != NULL;
360 compression_type = g_slist_next(compression_type)) {
361 fprintf(stderr, " %s\n", (const char *)compression_type->data);
364 g_slist_free(output_compression_types);
367 struct string_elem {
368 const char *sstr; /* The short string */
369 const char *lstr; /* The long string */
372 static int
373 string_compare(const void *a, const void *b)
375 return strcmp(((const struct string_elem *)a)->sstr,
376 ((const struct string_elem *)b)->sstr);
379 static void
380 string_elem_print(void *data)
382 fprintf(stderr, " %s - %s\n",
383 ((struct string_elem *)data)->sstr,
384 ((struct string_elem *)data)->lstr);
387 static void
388 list_read_capture_types(void)
390 unsigned i;
391 size_t num_file_types;
392 struct string_elem *captypes;
393 GSList *list = NULL;
394 const char *magic = "Magic-value-based";
395 const char *heuristic = "Heuristics-based";
397 /* How many readable file types are there? */
398 num_file_types = 0;
399 for (i = 0; open_routines[i].name != NULL; i++)
400 num_file_types++;
401 captypes = g_new(struct string_elem, num_file_types);
403 fprintf(stderr, "tshark: The available read file types for the \"-X read_format:\" option are:\n");
404 for (i = 0; i < num_file_types && open_routines[i].name != NULL; i++) {
405 captypes[i].sstr = open_routines[i].name;
406 captypes[i].lstr = (open_routines[i].type == OPEN_INFO_MAGIC) ? magic : heuristic;
407 list = g_slist_insert_sorted(list, &captypes[i], string_compare);
409 g_slist_free_full(list, string_elem_print);
410 g_free(captypes);
413 static void
414 list_export_pdu_taps(void)
416 fprintf(stderr, "tshark: The available export tap names and the encapsulation types they produce for the \"-U tap_name\" option are:\n");
417 for (GSList *export_pdu_tap_name_list = get_export_pdu_tap_list();
418 export_pdu_tap_name_list != NULL;
419 export_pdu_tap_name_list = g_slist_next(export_pdu_tap_name_list)) {
420 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)));
424 static void
425 print_usage(FILE *output)
427 fprintf(output, "\n");
428 fprintf(output, "Usage: tshark [options] ...\n");
429 fprintf(output, "\n");
431 #ifdef HAVE_LIBPCAP
432 fprintf(output, "Capture interface:\n");
433 fprintf(output, " -i <interface>, --interface <interface>\n");
434 fprintf(output, " name or idx of interface (def: first non-loopback)\n");
435 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
436 fprintf(output, " -s <snaplen>, --snapshot-length <snaplen>\n");
437 #ifdef HAVE_PCAP_CREATE
438 fprintf(output, " packet snapshot length (def: appropriate maximum)\n");
439 #else
440 fprintf(output, " packet snapshot length (def: %u)\n", WTAP_MAX_PACKET_SIZE_STANDARD);
441 #endif
442 fprintf(output, " -p, --no-promiscuous-mode\n");
443 fprintf(output, " don't capture in promiscuous mode\n");
444 #ifdef HAVE_PCAP_CREATE
445 fprintf(output, " -I, --monitor-mode capture in monitor mode, if available\n");
446 #endif
447 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
448 fprintf(output, " -B <buffer size>, --buffer-size <buffer size>\n");
449 fprintf(output, " size of kernel buffer in MiB (def: %dMiB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
450 #endif
451 fprintf(output, " -y <link type>, --linktype <link type>\n");
452 fprintf(output, " link layer type (def: first appropriate)\n");
453 fprintf(output, " --time-stamp-type <type> timestamp method for interface\n");
454 fprintf(output, " -D, --list-interfaces print list of interfaces and exit\n");
455 fprintf(output, " -L, --list-data-link-types\n");
456 fprintf(output, " print list of link-layer types of iface and exit\n");
457 fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n");
458 fprintf(output, "\n");
459 fprintf(output, "Capture display:\n");
460 fprintf(output, " --update-interval interval between updates with new packets, in milliseconds (def: %dms)\n", DEFAULT_UPDATE_INTERVAL);
461 fprintf(output, "Capture stop conditions:\n");
462 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
463 fprintf(output, " -a <autostop cond.> ..., --autostop <autostop cond.> ...\n");
464 fprintf(output, " duration:NUM - stop after NUM seconds\n");
465 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
466 fprintf(output, " files:NUM - stop after NUM files\n");
467 fprintf(output, " packets:NUM - stop after NUM packets\n");
468 /*fprintf(output, "\n");*/
469 fprintf(output, "Capture output:\n");
470 fprintf(output, " -b <ringbuffer opt.> ..., --ring-buffer <ringbuffer opt.>\n");
471 fprintf(output, " duration:NUM - switch to next file after NUM secs\n");
472 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
473 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
474 fprintf(output, " packets:NUM - switch to next file after NUM packets\n");
475 fprintf(output, " interval:NUM - switch to next file when the time is\n");
476 fprintf(output, " an exact multiple of NUM secs\n");
477 fprintf(output, " printname:FILE - print filename to FILE when written\n");
478 fprintf(output, " (can use 'stdout' or 'stderr')\n");
479 #endif /* HAVE_LIBPCAP */
480 #ifdef HAVE_PCAP_REMOTE
481 fprintf(output, "RPCAP options:\n");
482 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
483 #endif
484 /*fprintf(output, "\n");*/
485 fprintf(output, "Input file:\n");
486 fprintf(output, " -r <infile>, --read-file <infile>\n");
487 fprintf(output, " set the filename to read from (or '-' for stdin)\n");
489 fprintf(output, "\n");
490 fprintf(output, "Processing:\n");
491 fprintf(output, " -2 perform a two-pass analysis\n");
492 fprintf(output, " -M <packet count> perform session auto reset\n");
493 fprintf(output, " -R <read filter>, --read-filter <read filter>\n");
494 fprintf(output, " packet Read filter in Wireshark display filter syntax\n");
495 fprintf(output, " (requires -2)\n");
496 fprintf(output, " -Y <display filter>, --display-filter <display filter>\n");
497 fprintf(output, " packet displaY filter in Wireshark display filter\n");
498 fprintf(output, " syntax\n");
499 fprintf(output, " -n disable all name resolutions (def: \"mNd\" enabled, or\n");
500 fprintf(output, " as set in preferences)\n");
501 // Note: the order of the flags here matches the options in the settings dialog e.g. "dsN" only have an effect if "n" is set
502 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mtndsNvg\"\n");
503 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
504 fprintf(output, " \"Decode As\", see the man page for details\n");
505 fprintf(output, " Example: tcp.port==8888,http\n");
506 fprintf(output, " -H <hosts file> read a list of entries from a hosts file, which will\n");
507 fprintf(output, " then be written to a capture file. (Implies -W n)\n");
508 fprintf(output, " --enable-protocol <proto_name>\n");
509 fprintf(output, " enable dissection of proto_name\n");
510 fprintf(output, " --disable-protocol <proto_name>\n");
511 fprintf(output, " disable dissection of proto_name\n");
512 fprintf(output, " --only-protocols <protocols>\n");
513 fprintf(output, " Only enable dissection of these protocols, comma\n");
514 fprintf(output, " separated. Disable everything else\n");
515 fprintf(output, " --disable-all-protocols\n");
516 fprintf(output, " Disable dissection of all protocols\n");
517 fprintf(output, " --enable-heuristic <short_name>\n");
518 fprintf(output, " enable dissection of heuristic protocol\n");
519 fprintf(output, " --disable-heuristic <short_name>\n");
520 fprintf(output, " disable dissection of heuristic protocol\n");
522 /*fprintf(output, "\n");*/
523 fprintf(output, "Output:\n");
524 fprintf(output, " -w <outfile|-> write packets to a pcapng-format file named \"outfile\"\n");
525 fprintf(output, " (or '-' for stdout). If the output filename has the\n");
526 fprintf(output, " .gz extension, it will be compressed to a gzip archive\n");
527 fprintf(output, " --capture-comment <comment>\n");
528 fprintf(output, " add a capture file comment, if supported\n");
529 fprintf(output, " -C <config profile> start with specified configuration profile\n");
530 fprintf(output, " --global-profile use the global profile instead of personal profile\n");
531 fprintf(output, " -F <output file type> set the output file type; default is pcapng.\n");
532 fprintf(output, " an empty \"-F\" option will list the file types\n");
533 fprintf(output, " -V add output of packet tree (Packet Details)\n");
534 fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
535 fprintf(output, " separated\n");
536 fprintf(output, " -P, --print print packet summary even when writing to a file\n");
537 fprintf(output, " -S <separator> the line separator to print between packets\n");
538 fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
539 fprintf(output, " --hexdump <hexoption> add hexdump, set options for data source and ASCII dump\n");
540 fprintf(output, " all dump all data sources (-x default)\n");
541 fprintf(output, " frames dump only frame data source\n");
542 fprintf(output, " ascii include ASCII dump text (-x default)\n");
543 fprintf(output, " delimit delimit ASCII dump text with '|' characters\n");
544 fprintf(output, " noascii exclude ASCII dump text\n");
545 fprintf(output, " help display help for --hexdump and exit\n");
546 fprintf(output, " -T pdml|ps|psml|json|jsonraw|ek|tabs|text|fields|?\n");
547 fprintf(output, " format of text output (def: text)\n");
548 fprintf(output, " -j <protocolfilter> protocols layers filter if -T ek|pdml|json selected\n");
549 fprintf(output, " (e.g. \"ip ip.flags text\", filter does not expand child\n");
550 fprintf(output, " nodes, unless child is specified also in the filter)\n");
551 fprintf(output, " -J <protocolfilter> top level protocol filter if -T ek|pdml|json selected\n");
552 fprintf(output, " (e.g. \"http tcp\", filter which expands all child nodes)\n");
553 fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
554 fprintf(output, " _ws.col.info)\n");
555 fprintf(output, " this option can be repeated to print multiple fields\n");
556 fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
557 fprintf(output, " bom=y|n print a UTF-8 BOM\n");
558 fprintf(output, " header=y|n switch headers on and off\n");
559 fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
560 fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
561 fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
562 fprintf(output, " aggregator\n");
563 fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
564 fprintf(output, " -t (a|ad|adoy|d|dd|e|r|u|ud|udoy)[.[N]]|.[N]\n");
565 fprintf(output, " output format of time stamps (def: r: rel. to first)\n");
566 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
567 fprintf(output, " -l flush standard output after each packet\n");
568 fprintf(output, " (implies --update-interval 0)\n");
569 fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
570 fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
571 fprintf(output, " -g enable group read access on the output file(s)\n");
572 fprintf(output, " -W n Save extra information in the file, if supported.\n");
573 fprintf(output, " n = write network address resolution information\n");
574 fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
575 fprintf(output, " -U tap_name PDUs export mode, see the man page for details\n");
576 fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
577 fprintf(output, " --export-objects <protocol>,<destdir>\n");
578 fprintf(output, " save exported objects for a protocol to a directory\n");
579 fprintf(output, " named \"destdir\"\n");
580 fprintf(output, " --export-tls-session-keys <keyfile>\n");
581 fprintf(output, " export TLS Session Keys to a file named \"keyfile\"\n");
582 fprintf(output, " --color color output text similarly to the Wireshark GUI,\n");
583 fprintf(output, " requires a terminal with 24-bit color support\n");
584 fprintf(output, " Also supplies color attributes to pdml and psml formats\n");
585 fprintf(output, " (Note that attributes are nonstandard)\n");
586 fprintf(output, " --no-duplicate-keys If -T json is specified, merge duplicate keys in an object\n");
587 fprintf(output, " into a single key with as value a json array containing all\n");
588 fprintf(output, " values\n");
589 fprintf(output, " --elastic-mapping-filter <protocols> If -G elastic-mapping is specified, put only the\n");
590 fprintf(output, " specified protocols within the mapping file\n");
591 fprintf(output, " --temp-dir <directory> write temporary files to this directory\n");
592 fprintf(output, " (default: %s)\n", g_get_tmp_dir());
593 fprintf(output, " --compress <type> compress the output file using the type compression format\n");
594 fprintf(output, "\n");
596 ws_log_print_usage(output);
597 fprintf(output, "\n");
599 fprintf(output, "Miscellaneous:\n");
600 fprintf(output, " -h, --help display this help and exit\n");
601 fprintf(output, " -v, --version display version info and exit\n");
602 fprintf(output, " -o <name>:<value> ... override preference setting\n");
603 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
604 fprintf(output, " -G [report] dump one of several available reports and exit\n");
605 fprintf(output, " default report=\"fields\"\n");
606 fprintf(output, " use \"-G help\" for more help\n");
607 #ifdef __linux__
608 fprintf(output, "\n");
609 fprintf(output, "Dumpcap can benefit from an enabled BPF JIT compiler if available.\n");
610 fprintf(output, "You might want to enable it by executing:\n");
611 fprintf(output, " \"echo 1 > /proc/sys/net/core/bpf_jit_enable\"\n");
612 fprintf(output, "Note that this can make your system less secure!\n");
613 #endif
617 static void
618 glossary_option_help(void)
620 FILE *output;
622 output = stdout;
624 fprintf(output, "%s\n", get_appname_and_version());
626 fprintf(output, "\n");
627 fprintf(output, "Usage: tshark -G [report]\n");
628 fprintf(output, "\n");
629 fprintf(output, "Glossary table reports:\n");
630 fprintf(output, " -G column-formats dump column format codes and exit\n");
631 fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
632 fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
633 fprintf(output, " -G dissectors dump registered dissector names\n");
634 fprintf(output, " -G elastic-mapping dump ElasticSearch mapping file\n");
635 fprintf(output, " -G enterprises dump IANA Private Enterprise Number (PEN) table\n");
636 fprintf(output, " -G fieldcount dump count of header fields and exit\n");
637 fprintf(output, " -G fields,[prefix] dump fields glossary and exit\n");
638 fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
639 fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
640 fprintf(output, " -G manuf dump ethernet manufacturer tables\n");
641 fprintf(output, " -G plugins dump installed plugins and exit\n");
642 fprintf(output, " -G protocols dump protocols in registration database and exit\n");
643 fprintf(output, " -G services dump transport service (port) names\n");
644 fprintf(output, " -G values dump value, range, true/false strings and exit\n");
645 fprintf(output, "\n");
646 fprintf(output, "Preference reports:\n");
647 fprintf(output, " -G currentprefs dump current preferences and exit\n");
648 fprintf(output, " -G defaultprefs dump default preferences and exit\n");
649 fprintf(output, " -G folders dump about:folders\n");
650 fprintf(output, "\n");
653 static void
654 hexdump_option_help(FILE *output)
656 fprintf(output, "%s\n", get_appname_and_version());
657 fprintf(output, "\n");
658 fprintf(output, "tshark: Valid --hexdump <hexoption> values include:\n");
659 fprintf(output, "\n");
660 fprintf(output, "Data source options:\n");
661 fprintf(output, " all add hexdump, dump all data sources (-x default)\n");
662 fprintf(output, " frames add hexdump, dump only frame data source\n");
663 fprintf(output, "\n");
664 fprintf(output, "ASCII options:\n");
665 fprintf(output, " ascii add hexdump, include ASCII dump text (-x default)\n");
666 fprintf(output, " delimit add hexdump, delimit ASCII dump text with '|' characters\n");
667 fprintf(output, " noascii add hexdump, exclude ASCII dump text\n");
668 fprintf(output, "\n");
669 fprintf(output, "Miscellaneous:\n");
670 fprintf(output, " help display this help and exit\n");
671 fprintf(output, "\n");
672 fprintf(output, "Example:\n");
673 fprintf(output, "\n");
674 fprintf(output, " $ tshark ... --hexdump frames --hexdump delimit ...\n");
675 fprintf(output, "\n");
678 static void
679 print_current_user(void)
681 char *cur_user, *cur_group;
683 if (started_with_special_privs()) {
684 cur_user = get_cur_username();
685 cur_group = get_cur_groupname();
686 fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
687 cur_user, cur_group);
688 g_free(cur_user);
689 g_free(cur_group);
690 if (running_with_special_privs()) {
691 fprintf(stderr, " This could be dangerous.");
693 fprintf(stderr, "\n");
697 static void
698 gather_tshark_compile_info(feature_list l)
700 /* Capture libraries */
701 gather_caplibs_compile_info(l);
702 epan_gather_compile_info(l);
705 static void
706 gather_tshark_runtime_info(feature_list l)
708 #ifdef HAVE_LIBPCAP
709 gather_caplibs_runtime_info(l);
710 #endif
712 /* stuff used by libwireshark */
713 epan_gather_runtime_info(l);
716 static bool
717 _compile_dfilter(const char *text, dfilter_t **dfp, const char *caller)
719 bool ok;
720 df_error_t *df_err;
721 char *err_off;
722 char *expanded;
723 int64_t elapsed_start;
725 elapsed_start = g_get_monotonic_time();
726 expanded = dfilter_expand(text, &df_err);
727 if (expanded == NULL) {
728 cmdarg_err("%s", df_err->msg);
729 df_error_free(&df_err);
730 return false;
732 tshark_elapsed.dfilter_expand = g_get_monotonic_time() - elapsed_start;
734 elapsed_start = g_get_monotonic_time();
735 ok = dfilter_compile_full(expanded, dfp, &df_err, DF_OPTIMIZE, caller);
736 if (!ok ) {
737 cmdarg_err("%s", df_err->msg);
739 if (df_err->loc.col_start >= 0) {
740 err_off = ws_strdup_underline(NULL, df_err->loc.col_start, df_err->loc.col_len);
741 cmdarg_err_cont(" %s", expanded);
742 cmdarg_err_cont(" %s", err_off);
743 g_free(err_off);
745 df_error_free(&df_err);
747 tshark_elapsed.dfilter_compile = g_get_monotonic_time() - elapsed_start;
749 g_free(expanded);
750 return ok;
753 #define compile_dfilter(text, dfp) _compile_dfilter(text, dfp, __func__)
755 static bool
756 protocolfilter_add_opt(const char* arg, pf_flags filter_flags)
758 char **newfilter = NULL;
759 for (newfilter = wmem_strsplit(wmem_epan_scope(), arg, " ", -1); *newfilter; newfilter++) {
760 if (strcmp(*newfilter, "") == 0) {
761 /* Don't treat the empty string as an intended field abbreviation
762 * to output, consecutive spaces on the command line probably
763 * aren't intentional.
765 continue;
767 if (!output_fields_add_protocolfilter(output_fields, *newfilter, filter_flags)) {
768 cmdarg_err("%s was already specified with different filter flags. Overwriting previous protocol filter.", *newfilter);
771 return true;
774 static void
775 about_folders(void)
777 const char *constpath;
778 char *path;
779 int i;
780 char **resultArray;
782 /* "file open" */
785 * Fetching the "File" dialogs folder not implemented.
786 * This is arguably just a pwd for a ui/cli .
789 /* temp */
790 constpath = g_get_tmp_dir();
791 #ifdef HAVE_LIBPCAP
792 /* global_capture_opts only exists in this case */
793 if (global_capture_opts.temp_dir)
794 constpath = global_capture_opts.temp_dir;
795 #endif
796 printf("%-21s\t%s\n", "Temp:", constpath);
798 /* pers conf */
799 path = get_persconffile_path("", false);
800 printf("%-21s\t%s\n", "Personal configuration:", path);
801 g_free(path);
803 /* global conf */
804 constpath = get_datafile_dir();
805 if (constpath != NULL) {
806 printf("%-21s\t%s\n", "Global configuration:", constpath);
809 /* system */
810 constpath = get_systemfile_dir();
811 printf("%-21s\t%s\n", "System:", constpath);
813 /* program */
814 constpath = get_progfile_dir();
815 printf("%-21s\t%s\n", "Program:", constpath);
817 #ifdef HAVE_PLUGINS
818 /* pers plugins */
819 printf("%-21s\t%s\n", "Personal Plugins:", get_plugins_pers_dir_with_version());
821 /* global plugins */
822 printf("%-21s\t%s\n", "Global Plugins:", get_plugins_dir_with_version());
823 #endif
825 #ifdef HAVE_LUA
826 /* pers lua plugins */
827 printf("%-21s\t%s\n", "Personal Lua Plugins:", get_plugins_pers_dir());
829 /* global lua plugins */
830 printf("%-21s\t%s\n", "Global Lua Plugins:", get_plugins_dir());
831 #endif
833 /* Personal Extcap */
834 constpath = get_extcap_pers_dir();
836 resultArray = g_strsplit(constpath, G_SEARCHPATH_SEPARATOR_S, 10);
837 for(i = 0; resultArray[i]; i++)
838 printf("%-21s\t%s\n", "Personal Extcap path:", g_strstrip(resultArray[i]));
840 g_strfreev(resultArray);
842 /* Global Extcap */
843 constpath = get_extcap_dir();
845 resultArray = g_strsplit(constpath, G_SEARCHPATH_SEPARATOR_S, 10);
846 for(i = 0; resultArray[i]; i++)
847 printf("%-21s\t%s\n", "Global Extcap path:", g_strstrip(resultArray[i]));
849 g_strfreev(resultArray);
851 /* MaxMindDB */
852 path = maxmind_db_get_paths();
854 resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 10);
856 for(i = 0; resultArray[i]; i++)
857 printf("%-21s\t%s\n", "MaxMind database path:", g_strstrip(resultArray[i]));
859 g_strfreev(resultArray);
860 g_free(path);
862 #ifdef HAVE_LIBSMI
863 /* SMI MIBs/PIBs */
864 path = oid_get_default_mib_path();
866 resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 20);
868 for(i = 0; resultArray[i]; i++)
869 printf("%-21s\t%s\n", "MIB/PIB path:", g_strstrip(resultArray[i]));
871 g_strfreev(resultArray);
872 g_free(path);
873 #endif
877 static int
878 dump_glossary(const char* glossary, const char* elastic_mapping_filter)
880 int exit_status = EXIT_SUCCESS;
881 /* If invoked with the "-G" flag, we dump out information based on
882 the argument to the "-G" flag.
885 /* This is now called after the preferences are loaded and all
886 * the command line options are handled, including -o, -d,
887 * --[enable|disable]-[protocol|heuristic].
888 * Some UATs can register new fields (e.g. HTTP/2), so for most
889 * cases load everything.
891 * prefs_reset() is used for defaultprefs to get the default values.
892 * Note that makes it difficult to use defaultprefs in concert with
893 * any other glossary (we could do it last.)
895 proto_initialize_all_prefixes();
897 if (strcmp(glossary, "column-formats") == 0)
898 column_dump_column_formats();
899 else if (strcmp(glossary, "currentprefs") == 0) {
900 write_prefs(NULL);
902 else if (strcmp(glossary, "decodes") == 0) {
903 dissector_dump_decodes();
904 } else if (strcmp(glossary, "defaultprefs") == 0) {
905 prefs_reset();
906 write_prefs(NULL);
907 } else if (strcmp(glossary, "dissector-tables") == 0)
908 dissector_dump_dissector_tables();
909 else if (strcmp(glossary, "dissectors") == 0)
910 dissector_dump_dissectors();
911 else if (strcmp(glossary, "elastic-mapping") == 0)
912 proto_registrar_dump_elastic(elastic_mapping_filter);
913 else if (strncmp(glossary, "elastic-mapping,", strlen("elastic-mapping,")) == 0) {
914 elastic_mapping_filter = glossary + strlen("elastic-mapping,");
915 proto_registrar_dump_elastic(elastic_mapping_filter);
917 else if (strcmp(glossary, "fieldcount") == 0) {
918 /* return value for the test suite */
919 exit_status = proto_registrar_dump_fieldcount();
921 else if (strcmp(glossary, "fields") == 0) {
922 proto_registrar_dump_fields();
924 else if (strncmp(glossary, "fields,", strlen("fields,")) == 0) {
925 const char* prefix = glossary + strlen("fields,");
926 bool matched = proto_registrar_dump_field_completions(prefix);
927 if (!matched) {
928 cmdarg_err("No field or protocol begins with \"%s\"", prefix);
929 exit_status = EXIT_FAILURE;
932 else if (strcmp(glossary, "folders") == 0) {
933 about_folders();
934 } else if (strcmp(glossary, "ftypes") == 0)
935 proto_registrar_dump_ftypes();
936 else if (strcmp(glossary, "heuristic-decodes") == 0) {
937 dissector_dump_heur_decodes();
938 } else if (strcmp(glossary, "manuf") == 0)
939 ws_manuf_dump(stdout);
940 else if (strcmp(glossary, "enterprises") == 0)
941 global_enterprises_dump(stdout);
942 else if (strcmp(glossary, "services") == 0)
943 global_services_dump(stdout);
944 else if (strcmp(glossary, "plugins") == 0) {
945 #ifdef HAVE_PLUGINS
946 codecs_init();
947 plugins_dump_all();
948 #endif
949 #ifdef HAVE_LUA
950 wslua_plugins_dump_all();
951 #endif
952 extcap_dump_all();
954 else if (strcmp(glossary, "protocols") == 0) {
955 proto_registrar_dump_protocols();
956 } else if (strcmp(glossary, "values") == 0)
957 proto_registrar_dump_values();
958 else if (strcmp(glossary, "help") == 0)
959 glossary_option_help();
960 /* These are supported only for backwards compatibility and may or may not work
961 * for a given user in a given directory on a given operating system with a given
962 * command-line interpreter.
964 else if (strcmp(glossary, "?") == 0)
965 glossary_option_help();
966 else if (strcmp(glossary, "-?") == 0)
967 glossary_option_help();
968 else {
969 cmdarg_err("Invalid \"%s\" option for -G flag, enter -G help for more help.", glossary);
970 exit_status = WS_EXIT_INVALID_OPTION;
973 return exit_status;
976 static bool
977 must_do_dissection(dfilter_t *rfcode, dfilter_t *dfcode,
978 char *volatile pdu_export_arg)
980 /* We have to dissect each packet if:
982 we're printing information about each packet;
984 we're using a read filter on the packets;
986 we're using a display filter on the packets;
988 we're exporting PDUs;
990 we're using any taps that need dissection. */
991 return print_packet_info || rfcode || dfcode || pdu_export_arg ||
992 tap_listeners_require_dissection();
995 #ifdef HAVE_LIBPCAP
997 * Check whether a purported *shark packet-matching expression (display
998 * or read filter) looks like a capture filter and, if so, print a
999 * warning.
1001 * Used, for example, if the string in question isn't a valid packet-
1002 * matching expression.
1004 static void
1005 warn_about_capture_filter(const char *rfilter)
1007 struct bpf_program fcode;
1008 pcap_t *pc;
1010 pc = pcap_open_dead(DLT_EN10MB, MIN_PACKET_SIZE);
1011 if (pc != NULL) {
1012 if (pcap_compile(pc, &fcode, rfilter, 0, 0) != -1) {
1013 pcap_freecode(&fcode);
1014 cmdarg_err_cont(
1015 " Note: That read filter code looks like a valid capture filter;\n"
1016 " maybe you mixed them up?");
1018 pcap_close(pc);
1021 #endif
1023 #ifdef HAVE_LIBPCAP
1024 static GList *cached_if_list;
1026 static GList *
1027 capture_opts_get_interface_list(int *err, char **err_str)
1029 if (cached_if_list == NULL) {
1031 * This isn't a GUI tool, so no need for a callback.
1033 cached_if_list = capture_interface_list(err, err_str, NULL);
1036 * Routines expect to free the returned interface list, so return
1037 * a deep copy.
1039 return interface_list_copy(cached_if_list);
1041 #endif
1044 main(int argc, char *argv[])
1046 char *err_msg;
1047 int opt;
1048 static const struct ws_option long_options[] = {
1049 {"help", ws_no_argument, NULL, 'h'},
1050 {"version", ws_no_argument, NULL, 'v'},
1051 LONGOPT_CAPTURE_COMMON
1052 LONGOPT_DISSECT_COMMON
1053 LONGOPT_READ_CAPTURE_COMMON
1054 {"print", ws_no_argument, NULL, 'P'},
1055 {"export-objects", ws_required_argument, NULL, LONGOPT_EXPORT_OBJECTS},
1056 {"export-tls-session-keys", ws_required_argument, NULL, LONGOPT_EXPORT_TLS_SESSION_KEYS},
1057 {"color", ws_no_argument, NULL, LONGOPT_COLOR},
1058 {"no-duplicate-keys", ws_no_argument, NULL, LONGOPT_NO_DUPLICATE_KEYS},
1059 {"elastic-mapping-filter", ws_required_argument, NULL, LONGOPT_ELASTIC_MAPPING_FILTER},
1060 {"capture-comment", ws_required_argument, NULL, LONGOPT_CAPTURE_COMMENT},
1061 {"hexdump", ws_required_argument, NULL, LONGOPT_HEXDUMP},
1062 {"selected-frame", ws_required_argument, NULL, LONGOPT_SELECTED_FRAME},
1063 {"print-timers", ws_no_argument, NULL, LONGOPT_PRINT_TIMERS},
1064 {"global-profile", ws_no_argument, NULL, LONGOPT_GLOBAL_PROFILE},
1065 {"compress", ws_required_argument, NULL, LONGOPT_COMPRESS},
1066 {0, 0, 0, 0}
1068 bool arg_error = false;
1069 bool has_extcap_options = false;
1070 volatile bool is_capturing = true;
1072 int err;
1073 char *err_info;
1074 bool exp_pdu_status;
1075 volatile process_file_status_t status;
1076 volatile bool draw_taps = false;
1077 volatile int exit_status = EXIT_SUCCESS;
1078 #ifdef HAVE_LIBPCAP
1079 int caps_queries = 0;
1080 GList *if_list;
1081 char *err_str, *err_str_secondary;
1082 #else
1083 bool capture_option_specified = false;
1084 volatile int max_packet_count = 0;
1085 #endif
1086 volatile int out_file_type = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
1087 volatile bool out_file_name_res = false;
1088 volatile int in_file_type = WTAP_TYPE_AUTO;
1089 char *volatile cf_name = NULL;
1090 char *rfilter = NULL;
1091 char *volatile dfilter = NULL;
1092 dfilter_t *rfcode = NULL;
1093 dfilter_t *dfcode = NULL;
1094 e_prefs *prefs_p;
1095 char *output_only = NULL;
1096 char *volatile pdu_export_arg = NULL;
1097 char *volatile exp_pdu_filename = NULL;
1098 const char *volatile tls_session_keys_file = NULL;
1099 exp_pdu_t exp_pdu_tap_data;
1100 const char* glossary = NULL;
1101 const char* elastic_mapping_filter = NULL;
1102 wtap_compression_type volatile compression_type = WTAP_UNKNOWN_COMPRESSION;
1105 * The leading + ensures that getopt_long() does not permute the argv[]
1106 * entries.
1108 * We have to make sure that the first getopt_long() preserves the content
1109 * of argv[] for the subsequent getopt_long() call.
1111 * We use getopt_long() in both cases to ensure that we're using a routine
1112 * whose permutation behavior we can control in the same fashion on all
1113 * platforms, and so that, if we ever need to process a long argument before
1114 * doing further initialization, we can do so.
1116 * Glibc and Solaris libc document that a leading + disables permutation
1117 * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
1118 * and macOS don't document it, but do so anyway.
1120 * We do *not* use a leading - because the behavior of a leading - is
1121 * platform-dependent.
1123 #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:"
1125 static const char optstring[] = OPTSTRING;
1127 /* Set the program name. */
1128 g_set_prgname("tshark");
1131 * Set the C-language locale to the native environment and set the
1132 * code page to UTF-8 on Windows.
1134 #ifdef _WIN32
1135 setlocale(LC_ALL, ".UTF-8");
1136 #else
1137 setlocale(LC_ALL, "");
1138 #endif
1140 ws_tzset();
1142 cmdarg_err_init(stderr_cmdarg_err, stderr_cmdarg_err_cont);
1144 /* Initialize log handler early so we can have proper logging during startup. */
1145 ws_log_init(vcmdarg_err);
1147 /* Early logging command-line initialization. */
1148 ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION);
1150 ws_noisy("Finished log init and parsing command line log arguments");
1151 ws_debug("tshark started with %d args", argc);
1153 #ifdef _WIN32
1154 create_app_running_mutex();
1155 #endif /* _WIN32 */
1158 * Get credential information for later use, and drop privileges
1159 * before doing anything else.
1160 * Let the user know if anything happened.
1162 init_process_policies();
1163 relinquish_special_privs_perm();
1164 print_current_user();
1167 * Attempt to get the pathname of the directory containing the
1168 * executable file.
1170 err_msg = configuration_init(argv[0]);
1171 if (err_msg != NULL) {
1172 fprintf(stderr,
1173 "tshark: Can't get pathname of directory containing the tshark program: %s.\n"
1174 "It won't be possible to capture traffic.\n"
1175 "Report this to the Wireshark developers.",
1176 err_msg);
1177 g_free(err_msg);
1180 initialize_funnel_ops();
1182 #ifdef _WIN32
1183 ws_init_dll_search_path();
1184 #ifdef HAVE_LIBPCAP
1185 /* Load wpcap if possible. Do this before collecting the run-time version information */
1186 load_wpcap();
1187 #endif /* HAVE_LIBPCAP */
1188 #endif /* _WIN32 */
1190 /* Initialize the version information. */
1191 ws_init_version_info("TShark",
1192 gather_tshark_compile_info, gather_tshark_runtime_info);
1194 /* Fail sometimes. Useful for testing fuzz scripts. */
1195 /* if (g_random_int_range(0, 100) < 5) abort(); */
1198 * In order to have the -X opts assigned before the wslua machine starts
1199 * we need to call getopt_long before epan_init() gets called.
1201 * In order to handle, for example, -o options, we also need to call it
1202 * *after* epan_init() gets called, so that the dissectors have had a
1203 * chance to register their preferences.
1205 * Spawning a bunch of extcap processes can delay program startup,
1206 * particularly on Windows. Check to see if we have any options that
1207 * might require extcap and set has_extcap_options = true if that's
1208 * the case.
1210 * XXX - can we do this all with one getopt_long() call, saving the
1211 * arguments we can't handle until after initializing libwireshark,
1212 * and then process them after initializing libwireshark?
1214 * We set ws_opterr to 0 so that ws_getopt_long doesn't print error
1215 * messages for bad long options. We'll do that once, in the final
1216 * call where all the error handling happens.
1218 ws_opterr = 0;
1220 /* We should check at first if we should use a global profile before
1221 parsing the profile name
1222 XXX - We could check this in the next ws_getopt_long, and save the
1223 profile name and only apply it after finishing the loop. */
1224 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
1225 switch (opt) {
1226 case LONGOPT_GLOBAL_PROFILE:
1227 set_persconffile_dir(get_datafile_dir());
1228 break;
1229 default:
1230 break;
1235 * Reset the options parser, set ws_optreset to 1 and set ws_optind to 1.
1236 * We still don't want to print error messages, though.
1238 ws_optreset = 1;
1239 ws_optind = 1;
1241 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
1242 switch (opt) {
1243 case 'C': /* Configuration Profile */
1244 if (profile_exists (ws_optarg, false)) {
1245 set_profile_name (ws_optarg);
1246 } else if (profile_exists (ws_optarg, true)) {
1247 char *pf_dir_path, *pf_dir_path2, *pf_filename;
1248 /* Copy from global profile */
1249 if (create_persconffile_profile(ws_optarg, &pf_dir_path) == -1) {
1250 cmdarg_err("Can't create directory\n\"%s\":\n%s.",
1251 pf_dir_path, g_strerror(errno));
1253 g_free(pf_dir_path);
1254 exit_status = WS_EXIT_INVALID_FILE;
1255 goto clean_exit;
1257 if (copy_persconffile_profile(ws_optarg, ws_optarg, true, &pf_filename,
1258 &pf_dir_path, &pf_dir_path2) == -1) {
1259 cmdarg_err("Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
1260 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
1262 g_free(pf_filename);
1263 g_free(pf_dir_path);
1264 g_free(pf_dir_path2);
1265 exit_status = WS_EXIT_INVALID_FILE;
1266 goto clean_exit;
1268 set_profile_name (ws_optarg);
1269 } else {
1270 cmdarg_err("Configuration Profile \"%s\" does not exist", ws_optarg);
1271 exit_status = WS_EXIT_INVALID_OPTION;
1272 goto clean_exit;
1274 break;
1275 case 'G':
1276 if (glossary != NULL) {
1277 /* Multiple glossaries are difficult especially due to defaultprefs */
1278 cmdarg_err("Multiple glossary reports (-G) are unsupported");
1279 exit_status = WS_EXIT_INVALID_OPTION;
1280 goto clean_exit;
1281 } else {
1282 glossary = ws_optarg;
1284 if (g_str_has_suffix(ws_optarg, "prefs")) {
1285 has_extcap_options = true;
1287 is_capturing = false;
1288 break;
1289 case 'i':
1290 has_extcap_options = true;
1291 break;
1292 case 'o':
1293 if (g_str_has_prefix(ws_optarg, "extcap.")) {
1294 has_extcap_options = true;
1296 break;
1297 case 'P': /* Print packet summary info even when writing to a file */
1298 print_packet_info = true;
1299 print_summary = true;
1300 break;
1301 case 'r': /* Read capture file x */
1302 cf_name = g_strdup(ws_optarg);
1303 is_capturing = false;
1304 break;
1305 case 'O': /* Only output these protocols */
1306 output_only = g_strdup(ws_optarg);
1307 /* FALLTHROUGH */
1308 case 'V': /* Verbose */
1309 print_details = true;
1310 print_packet_info = true;
1311 break;
1312 case 'x': /* Print packet data in hex (and ASCII) */
1313 print_hex = true;
1314 /* The user asked for hex output, so let's ensure they get it,
1315 * even if they're writing to a file.
1317 print_packet_info = true;
1318 break;
1319 case 'X':
1320 ex_opt_add(ws_optarg);
1321 break;
1322 case 'h':
1323 case 'v':
1324 is_capturing = false;
1325 break;
1326 default:
1327 break;
1331 #ifndef HAVE_LUA
1332 if (ex_opt_count("lua_script") > 0) {
1333 cmdarg_err("This version of TShark was not built with support for Lua scripting.");
1334 exit_status = WS_EXIT_INIT_FAILED;
1335 goto clean_exit;
1337 #endif /* HAVE_LUA */
1339 init_report_failure_message("TShark");
1341 #ifdef HAVE_LIBPCAP
1342 capture_opts_init(&global_capture_opts, capture_opts_get_interface_list);
1343 capture_session_init(&global_capture_session, &cfile,
1344 capture_input_new_file, capture_input_new_packets,
1345 capture_input_drops, capture_input_error,
1346 capture_input_cfilter_error, capture_input_closed);
1347 #endif
1349 timestamp_set_type(TS_RELATIVE);
1350 timestamp_set_precision(TS_PREC_AUTO);
1351 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
1354 * Libwiretap must be initialized before libwireshark is, so that
1355 * dissection-time handlers for file-type-dependent blocks can
1356 * register using the file type/subtype value for the file type.
1358 wtap_init(true);
1360 /* Register all dissectors; we must do this before checking for the
1361 "-G" flag, as the "-G" flag dumps information registered by the
1362 dissectors, and we must do it before we read the preferences, in
1363 case any dissectors register preferences. */
1364 if (!epan_init(NULL, NULL, true)) {
1365 exit_status = WS_EXIT_INIT_FAILED;
1366 goto clean_exit;
1369 /* Register all tap listeners; we do this before we parse the arguments,
1370 as the "-z" argument can specify a registered tap. */
1372 register_all_tap_listeners(tap_reg_listener);
1374 /* Register extcap preferences only when needed. */
1375 if (has_extcap_options || is_capturing) {
1377 * XXX - We don't properly handle the capture_no_extcap preference.
1378 * To make it work, before registering the extcap preferences we'd
1379 * have to read at least that preference for the chosen profile, and
1380 * also check to make sure an "-o" option didn't override it.
1381 * Then, after registering the extcap preferences, we'd have to
1382 * set the extcap preferences from the preferences file and "-o"
1383 * options on the command line.
1385 extcap_register_preferences();
1388 conversation_table_set_gui_info(init_iousers);
1389 endpoint_table_set_gui_info(init_endpoints);
1390 srt_table_iterate_tables(register_srt_tables, NULL);
1391 rtd_table_iterate_tables(register_rtd_tables, NULL);
1392 stat_tap_iterate_tables(register_simple_stat_tables, NULL);
1394 ws_debug("tshark reading settings");
1396 /* Load libwireshark settings from the current profile. */
1397 prefs_p = epan_load_settings();
1398 prefs_loaded = true;
1400 cap_file_init(&cfile);
1402 /* Print format defaults to this. */
1403 print_format = PR_FMT_TEXT;
1404 delimiter_char = " ";
1406 output_fields = output_fields_new();
1409 * To reset the options parser, set ws_optreset to 1 and set ws_optind to 1.
1411 * Also reset ws_opterr to 1, so that error messages are printed by
1412 * getopt_long().
1414 ws_optreset = 1;
1415 ws_optind = 1;
1416 ws_opterr = 1;
1418 /* Now get our args */
1419 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
1420 switch (opt) {
1421 case '2': /* Perform two-pass analysis */
1422 if(epan_auto_reset){
1423 cmdarg_err("-2 does not support auto session reset.");
1424 arg_error=true;
1426 perform_two_pass_analysis = true;
1427 break;
1428 case 'M':
1429 if(perform_two_pass_analysis){
1430 cmdarg_err("-M does not support two-pass analysis.");
1431 arg_error=true;
1433 epan_auto_reset_count = get_positive_int(ws_optarg, "epan reset count");
1434 epan_auto_reset = true;
1435 break;
1436 case 'a': /* autostop criteria */
1437 case 'b': /* Ringbuffer option */
1438 case 'f': /* capture filter */
1439 case 'g': /* enable group read access on file(s) */
1440 case 'i': /* Use interface x */
1441 case LONGOPT_SET_TSTAMP_TYPE: /* Set capture timestamp type */
1442 case 'p': /* Don't capture in promiscuous mode */
1443 #ifdef HAVE_PCAP_REMOTE
1444 case 'A': /* Authentication */
1445 #endif
1446 #ifdef HAVE_PCAP_CREATE
1447 case 'I': /* Capture in monitor mode, if available */
1448 #endif
1449 case 's': /* Set the snapshot (capture) length */
1450 case 'y': /* Set the pcap data link type */
1451 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
1452 case 'B': /* Buffer size */
1453 #endif
1454 case LONGOPT_COMPRESS_TYPE: /* compress type */
1455 case LONGOPT_CAPTURE_TMPDIR: /* capture temp directory */
1456 case LONGOPT_UPDATE_INTERVAL: /* sync pipe update interval */
1457 /* These are options only for packet capture. */
1458 #ifdef HAVE_LIBPCAP
1459 exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
1460 if (exit_status != 0) {
1461 goto clean_exit;
1463 #else
1464 capture_option_specified = true;
1465 arg_error = true;
1466 #endif
1467 break;
1468 case 'c': /* Stop after x packets */
1469 #ifdef HAVE_LIBPCAP
1470 exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
1471 if (exit_status != 0) {
1472 goto clean_exit;
1474 #else
1475 max_packet_count = get_positive_int(ws_optarg, "packet count");
1476 #endif
1477 break;
1478 case 'w': /* Write to file x */
1479 output_file_name = g_strdup(ws_optarg);
1480 #ifdef HAVE_LIBPCAP
1481 exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
1482 if (exit_status != 0) {
1483 goto clean_exit;
1485 #endif
1486 break;
1487 case 'C':
1488 /* already processed; just ignore it now */
1489 break;
1490 case 'D': /* Print a list of capture devices and exit */
1491 #ifdef HAVE_LIBPCAP
1492 exit_status = EXIT_SUCCESS;
1493 if_list = capture_interface_list(&err, &err_str,NULL);
1494 if (err != 0) {
1496 * An error occurred when fetching the local
1497 * interfaces. Report it.
1499 cmdarg_err("%s", err_str);
1500 g_free(err_str);
1501 exit_status = WS_EXIT_PCAP_ERROR;
1503 if (if_list == NULL) {
1505 * No interfaces were found. If that's not the
1506 * result of an error when fetching the local
1507 * interfaces, let the user know.
1509 if (err == 0) {
1510 cmdarg_err("There are no interfaces on which a capture can be done");
1511 exit_status = WS_EXIT_NO_INTERFACES;
1513 goto clean_exit;
1515 capture_opts_print_interfaces(if_list);
1516 free_interface_list(if_list);
1517 goto clean_exit;
1518 #else
1519 capture_option_specified = true;
1520 arg_error = true;
1521 #endif
1522 break;
1523 case 'e':
1524 /* Field entry */
1526 const char* col_field = try_convert_to_column_field(ws_optarg);
1527 if (col_field) {
1528 output_fields_add(output_fields, col_field);
1529 } else {
1530 header_field_info *hfi = proto_registrar_get_byalias(ws_optarg);
1531 if (hfi)
1532 output_fields_add(output_fields, hfi->abbrev);
1533 else
1534 output_fields_add(output_fields, ws_optarg);
1537 break;
1538 case 'E':
1539 /* Field option */
1540 if (!output_fields_set_option(output_fields, ws_optarg)) {
1541 cmdarg_err("\"%s\" is not a valid field output option=value pair.", ws_optarg);
1542 output_fields_list_options(stderr);
1543 exit_status = WS_EXIT_INVALID_OPTION;
1544 goto clean_exit;
1546 break;
1547 case 'F':
1548 out_file_type = wtap_name_to_file_type_subtype(ws_optarg);
1549 if (out_file_type < 0) {
1550 cmdarg_err("\"%s\" isn't a valid capture file type", ws_optarg);
1551 list_capture_types();
1552 exit_status = WS_EXIT_INVALID_OPTION;
1553 goto clean_exit;
1555 break;
1556 case 'G':
1557 /* already processed; just ignore it now */
1558 break;
1559 case 'j':
1560 if (!protocolfilter_add_opt(ws_optarg, PF_NONE)) {
1561 exit_status = WS_EXIT_INVALID_OPTION;
1562 goto clean_exit;
1564 break;
1565 case 'J':
1566 if (!protocolfilter_add_opt(ws_optarg, PF_INCLUDE_CHILDREN)) {
1567 exit_status = WS_EXIT_INVALID_OPTION;
1568 goto clean_exit;
1570 break;
1571 case 'W': /* Select extra information to save in our capture file */
1572 /* This is patterned after the -N flag which may not be the best idea. */
1573 if (strchr(ws_optarg, 'n')) {
1574 out_file_name_res = true;
1575 } else {
1576 cmdarg_err("Invalid -W argument \"%s\"; it must be one of:", ws_optarg);
1577 cmdarg_err_cont("\t'n' write network address resolution information (pcapng only)");
1578 exit_status = WS_EXIT_INVALID_OPTION;
1579 goto clean_exit;
1581 break;
1582 case 'H': /* Read address to name mappings from a hosts file */
1583 if (! add_hosts_file(ws_optarg))
1585 cmdarg_err("Can't read host entries from \"%s\"", ws_optarg);
1586 exit_status = WS_EXIT_INVALID_OPTION;
1587 goto clean_exit;
1589 out_file_name_res = true;
1590 break;
1592 case 'h': /* Print help and exit */
1593 show_help_header("Dump and analyze network traffic.");
1594 print_usage(stdout);
1595 exit_status = EXIT_SUCCESS;
1596 goto clean_exit;
1597 break;
1598 case 'l': /* "Line-buffer" standard output */
1599 /* The ANSI C standard does not appear to *require* that a line-buffered
1600 stream be flushed to the host environment whenever a newline is
1601 written, it just says that, on such a stream, characters "are
1602 intended to be transmitted to or from the host environment as a
1603 block when a new-line character is encountered".
1605 The Visual C++ 6.0 C implementation doesn't do what is intended;
1606 even if you set a stream to be line-buffered, it still doesn't
1607 flush the buffer at the end of every line.
1609 The whole reason for the "-l" flag in either tcpdump or TShark
1610 is to allow the output of a live capture to be piped to a program
1611 or script and to have that script see the information for the
1612 packet as soon as it's printed, rather than having to wait until
1613 a standard I/O buffer fills up.
1615 So, if the "-l" flag is specified, we flush the standard output
1616 at the end of a packet. This will do the right thing if we're
1617 printing packet summary lines, and, as we print the entire protocol
1618 tree for a single packet without waiting for anything to happen,
1619 it should be as good as line-buffered mode if we're printing
1620 protocol trees - arguably even better, as it may do fewer
1621 writes. */
1622 line_buffered = true;
1623 #ifdef HAVE_LIBPCAP
1624 /* Set the update-interval to 0 so that dumpcap reports packets
1625 * as soon as available instead of buffering them.
1627 exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
1628 if (exit_status != 0) {
1629 goto clean_exit;
1631 #endif
1632 break;
1633 case 'L': /* Print list of link-layer types and exit */
1634 #ifdef HAVE_LIBPCAP
1635 caps_queries |= CAPS_QUERY_LINK_TYPES;
1636 #else
1637 capture_option_specified = true;
1638 arg_error = true;
1639 #endif
1640 break;
1641 case LONGOPT_LIST_TSTAMP_TYPES: /* List possible timestamp types */
1642 #ifdef HAVE_LIBPCAP
1643 caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES;
1644 #else
1645 capture_option_specified = true;
1646 arg_error = true;
1647 #endif
1648 break;
1649 case 'o': /* Override preference from command line */
1651 char *errmsg = NULL;
1653 switch (prefs_set_pref(ws_optarg, &errmsg)) {
1655 case PREFS_SET_OK:
1656 break;
1658 case PREFS_SET_SYNTAX_ERR:
1659 cmdarg_err("Invalid -o flag \"%s\"%s%s", ws_optarg,
1660 errmsg ? ": " : "", errmsg ? errmsg : "");
1661 g_free(errmsg);
1662 exit_status = WS_EXIT_INVALID_OPTION;
1663 goto clean_exit;
1664 break;
1666 case PREFS_SET_NO_SUCH_PREF:
1667 cmdarg_err("-o flag \"%s\" specifies unknown preference", ws_optarg);
1668 exit_status = WS_EXIT_INVALID_OPTION;
1669 goto clean_exit;
1670 break;
1672 case PREFS_SET_OBSOLETE:
1673 cmdarg_err("-o flag \"%s\" specifies obsolete preference", ws_optarg);
1674 exit_status = WS_EXIT_INVALID_OPTION;
1675 goto clean_exit;
1676 break;
1678 break;
1680 case 'q': /* Quiet */
1681 quiet = true;
1682 break;
1683 case 'Q': /* Really quiet */
1684 quiet = true;
1685 really_quiet = true;
1686 break;
1687 case 'r':
1688 /* already processed; just ignore it now */
1689 break;
1690 case 'R': /* Read file filter */
1691 rfilter = ws_optarg;
1692 break;
1693 case 'P':
1694 /* already processed; just ignore it now */
1695 break;
1696 case 'S': /* Set the line Separator to be printed between packets */
1697 separator = ws_optarg;
1698 break;
1699 case 'T': /* printing Type */
1700 /* output_action has been already set. It means multiple -T. */
1701 if (output_action > WRITE_NONE) {
1702 cmdarg_err("Multiple -T parameters are unsupported");
1703 exit_status = WS_EXIT_INVALID_OPTION;
1704 goto clean_exit;
1706 print_packet_info = true;
1707 if (strcmp(ws_optarg, "text") == 0) {
1708 output_action = WRITE_TEXT;
1709 print_format = PR_FMT_TEXT;
1710 } else if (strcmp(ws_optarg, "tabs") == 0) {
1711 output_action = WRITE_TEXT;
1712 print_format = PR_FMT_TEXT;
1713 delimiter_char = "\t";
1714 } else if (strcmp(ws_optarg, "ps") == 0) {
1715 output_action = WRITE_TEXT;
1716 print_format = PR_FMT_PS;
1717 } else if (strcmp(ws_optarg, "pdml") == 0) {
1718 output_action = WRITE_XML;
1719 print_details = true; /* Need details */
1720 print_summary = false; /* Don't allow summary */
1721 } else if (strcmp(ws_optarg, "psml") == 0) {
1722 output_action = WRITE_XML;
1723 print_details = false; /* Don't allow details */
1724 print_summary = true; /* Need summary */
1725 } else if (strcmp(ws_optarg, "fields") == 0) {
1726 output_action = WRITE_FIELDS;
1727 print_details = true; /* Need full tree info */
1728 print_summary = false; /* Don't allow summary */
1729 } else if (strcmp(ws_optarg, "json") == 0) {
1730 output_action = WRITE_JSON;
1731 print_details = true; /* Need details */
1732 print_summary = false; /* Don't allow summary */
1733 } else if (strcmp(ws_optarg, "ek") == 0) {
1734 output_action = WRITE_EK;
1735 if (!print_summary)
1736 print_details = true;
1737 } else if (strcmp(ws_optarg, "jsonraw") == 0) {
1738 output_action = WRITE_JSON_RAW;
1739 print_details = true; /* Need details */
1740 print_summary = false; /* Don't allow summary */
1742 else {
1743 cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", ws_optarg); /* x */
1744 cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
1745 "\t specified by the -E option.\n"
1746 "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
1747 "\t details of a decoded packet. This information is equivalent to\n"
1748 "\t the packet details printed with the -V flag.\n"
1749 "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
1750 "\t the packets, or a multi-line view of the details of each of\n"
1751 "\t the packets, depending on whether the -V flag was specified.\n"
1752 "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
1753 "\t summary information of a decoded packet. This information is\n"
1754 "\t equivalent to the information shown in the one-line summary\n"
1755 "\t printed by default.\n"
1756 "\t\"json\" Packet Summary, an JSON-based format for the details\n"
1757 "\t summary information of a decoded packet. This information is \n"
1758 "\t equivalent to the packet details printed with the -V flag.\n"
1759 "\t\"jsonraw\" Packet Details, a JSON-based format for machine parsing\n"
1760 "\t including only raw hex decoded fields (same as -T json -x but\n"
1761 "\t without text decoding, only raw fields included). \n"
1762 "\t\"ek\" Packet Details, an EK JSON-based format for the bulk insert \n"
1763 "\t into elastic search cluster. This information is \n"
1764 "\t equivalent to the packet details printed with the -V flag.\n"
1765 "\t\"text\" Text of a human-readable one-line summary of each of the\n"
1766 "\t packets, or a multi-line view of the details of each of the\n"
1767 "\t packets, depending on whether the -V flag was specified.\n"
1768 "\t This is the default.\n"
1769 "\t\"tabs\" Similar to the text report except that each column of the\n"
1770 "\t human-readable one-line summary is delimited with an ASCII\n"
1771 "\t horizontal tab character.");
1772 exit_status = WS_EXIT_INVALID_OPTION;
1773 goto clean_exit;
1775 break;
1776 case 'U': /* Export PDUs to file */
1777 if (strcmp(ws_optarg, "") == 0 || strcmp(ws_optarg, "?") == 0) {
1778 list_export_pdu_taps();
1779 exit_status = WS_EXIT_INVALID_OPTION;
1780 goto clean_exit;
1782 pdu_export_arg = g_strdup(ws_optarg);
1783 break;
1784 case 'v': /* Show version and exit */
1785 show_version();
1786 /* We don't really have to cleanup here, but it's a convenient way to test
1787 * start-up and shut-down of the epan library without any UI-specific
1788 * cruft getting in the way. Makes the results of running
1789 * $ ./tools/valgrind-wireshark -n
1790 * much more useful. */
1791 epan_cleanup();
1792 extcap_cleanup();
1793 exit_status = EXIT_SUCCESS;
1794 goto clean_exit;
1795 case 'O': /* Only output these protocols */
1796 /* already processed; just ignore it now */
1797 break;
1798 case 'V': /* Verbose */
1799 /* already processed; just ignore it now */
1800 break;
1801 case 'x': /* Print packet data in hex (and ASCII) */
1802 /* already processed; just ignore it now */
1803 break;
1804 case 'X':
1805 /* already processed; just ignore it now */
1806 break;
1807 case 'Y':
1808 dfilter = g_strdup(ws_optarg);
1809 break;
1810 case 'z':
1811 /* We won't call the init function for the stat this soon
1812 as it would disallow MATE's fields (which are registered
1813 by the preferences set callback) from being used as
1814 part of a tap filter. Instead, we just add the argument
1815 to a list of stat arguments. */
1816 if (strcmp("help", ws_optarg) == 0) {
1817 fprintf(stderr, "tshark: The available statistics for the \"-z\" option are:\n");
1818 list_stat_cmd_args();
1819 exit_status = EXIT_SUCCESS;
1820 goto clean_exit;
1822 if (!process_stat_cmd_arg(ws_optarg)) {
1823 cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", ws_optarg);
1824 list_stat_cmd_args();
1825 exit_status = WS_EXIT_INVALID_OPTION;
1826 goto clean_exit;
1828 break;
1829 case 'd': /* Decode as rule */
1830 case 'K': /* Kerberos keytab file */
1831 case 'n': /* No name resolution */
1832 case 'N': /* Select what types of addresses/port #s to resolve */
1833 case 't': /* Time stamp type */
1834 case 'u': /* Seconds type */
1835 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
1836 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
1837 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
1838 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
1839 case LONGOPT_ONLY_PROTOCOLS: /* enable dissection of only this comma separated list of protocols */
1840 case LONGOPT_DISABLE_ALL_PROTOCOLS: /* enable dissection of protocol (that is disabled by default) */
1841 if (!dissect_opts_handle_opt(opt, ws_optarg)) {
1842 exit_status = WS_EXIT_INVALID_OPTION;
1843 goto clean_exit;
1845 break;
1846 case LONGOPT_EXPORT_OBJECTS: /* --export-objects */
1847 if (strcmp("help", ws_optarg) == 0) {
1848 fprintf(stderr, "tshark: The available export object types for the \"--export-objects\" option are:\n");
1849 eo_list_object_types();
1850 exit_status = EXIT_SUCCESS;
1851 goto clean_exit;
1853 if (!eo_tap_opt_add(ws_optarg)) {
1854 exit_status = WS_EXIT_INVALID_OPTION;
1855 goto clean_exit;
1857 break;
1858 case LONGOPT_EXPORT_TLS_SESSION_KEYS: /* --export-tls-session-keys */
1859 tls_session_keys_file = ws_optarg;
1860 break;
1861 case LONGOPT_COLOR: /* print in color where appropriate */
1862 dissect_color = true;
1863 /* This has no effect if we don't print packet info or filter
1864 (we can filter on the coloring rules). Should we warn or
1865 error later if so, instead of silently ignoring it? */
1866 break;
1867 case LONGOPT_NO_DUPLICATE_KEYS:
1868 no_duplicate_keys = true;
1869 node_children_grouper = proto_node_group_children_by_json_key;
1870 break;
1871 case LONGOPT_ELASTIC_MAPPING_FILTER:
1873 * XXX - A long option that exists to alter one other option
1874 * (-G elastic-mapping) and for no other reason seems verbose.
1875 * Deprecate in favor of -G elastic-mapping,<filter> ?
1877 elastic_mapping_filter = ws_optarg;
1878 break;
1879 case LONGOPT_CAPTURE_COMMENT: /* capture comment */
1880 if (capture_comments == NULL) {
1881 capture_comments = g_ptr_array_new_with_free_func(g_free);
1883 g_ptr_array_add(capture_comments, g_strdup(ws_optarg));
1884 break;
1885 case LONGOPT_HEXDUMP:
1886 print_hex = true;
1887 print_packet_info = true;
1888 if (strcmp(ws_optarg, "all") == 0)
1889 hexdump_source_option = HEXDUMP_SOURCE_MULTI;
1890 else if (strcmp(ws_optarg, "frames") == 0)
1891 hexdump_source_option = HEXDUMP_SOURCE_PRIMARY;
1892 else if (strcmp(ws_optarg, "ascii") == 0)
1893 hexdump_ascii_option = HEXDUMP_ASCII_INCLUDE;
1894 else if (strcmp(ws_optarg, "delimit") == 0)
1895 hexdump_ascii_option = HEXDUMP_ASCII_DELIMIT;
1896 else if (strcmp(ws_optarg, "noascii") == 0)
1897 hexdump_ascii_option = HEXDUMP_ASCII_EXCLUDE;
1898 else if (strcmp("help", ws_optarg) == 0) {
1899 hexdump_option_help(stdout);
1900 exit_status = EXIT_SUCCESS;
1901 goto clean_exit;
1902 } else {
1903 fprintf(stderr, "tshark: \"%s\" is an invalid value for --hexdump <hexoption>\n", ws_optarg);
1904 fprintf(stderr, "For valid <hexoption> values enter: tshark --hexdump help\n");
1905 exit_status = WS_EXIT_INVALID_OPTION;
1906 goto clean_exit;
1908 break;
1909 case LONGOPT_SELECTED_FRAME:
1910 /* Hidden option to mark a frame as "selected". Used for testing and debugging.
1911 * Only active in two-pass mode. */
1912 if (!ws_strtou32(ws_optarg, NULL, &selected_frame_number)) {
1913 fprintf(stderr, "tshark: \"%s\" is not a valid frame number\n", ws_optarg);
1914 exit_status = WS_EXIT_INVALID_OPTION;
1915 goto clean_exit;
1917 break;
1918 case LONGOPT_PRINT_TIMERS:
1919 opt_print_timers = true;
1920 break;
1921 case LONGOPT_GLOBAL_PROFILE:
1922 /* already processed; just ignore it now */
1923 break;
1924 case LONGOPT_COMPRESS: /* compress type */
1925 compression_type = wtap_name_to_compression_type(ws_optarg);
1926 if (compression_type == WTAP_UNKNOWN_COMPRESSION) {
1927 cmdarg_err("\"%s\" isn't a valid output compression mode",
1928 ws_optarg);
1929 list_output_compression_types();
1930 goto clean_exit;
1932 break;
1933 default:
1934 case '?': /* Bad flag - print usage message */
1935 switch(ws_optopt) {
1936 case 'F':
1937 list_capture_types();
1938 break;
1939 case LONGOPT_COMPRESS:
1940 list_output_compression_types();
1941 break;
1942 default:
1943 print_usage(stderr);
1945 exit_status = WS_EXIT_INVALID_OPTION;
1946 goto clean_exit;
1947 break;
1951 /* set the default output action to TEXT */
1952 if (output_action == WRITE_NONE)
1953 output_action = WRITE_TEXT;
1955 /* set the default file type to pcapng */
1956 if (out_file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
1957 out_file_type = wtap_pcapng_file_type_subtype();
1960 * Print packet summary information is the default if neither -V or -x
1961 * were specified. Note that this is new behavior, which allows for the
1962 * possibility of printing only hex/ascii output without necessarily
1963 * requiring that either the summary or details be printed too.
1965 if (!print_summary && !print_details && !print_hex)
1966 print_summary = true;
1968 if (no_duplicate_keys && output_action != WRITE_JSON && output_action != WRITE_JSON_RAW) {
1969 cmdarg_err("--no-duplicate-keys can only be used with \"-T json\" and \"-T jsonraw\"");
1970 exit_status = WS_EXIT_INVALID_OPTION;
1971 goto clean_exit;
1974 /* If we specified output fields, but not the output field type... */
1975 /* XXX: If we specfied both output fields with -e *and* protocol filters
1976 * with -j/-J, only the former are used. Should we warn or abort?
1977 * This also doesn't distinguish PDML from PSML, but shouldn't allow the
1978 * latter.
1980 if ((WRITE_FIELDS != output_action && WRITE_XML != output_action && WRITE_JSON != output_action && WRITE_EK != output_action) && 0 != output_fields_num_fields(output_fields)) {
1981 cmdarg_err("Output fields were specified with \"-e\", "
1982 "but \"-Tek, -Tfields, -Tjson or -Tpdml\" was not specified.");
1983 exit_status = WS_EXIT_INVALID_OPTION;
1984 goto clean_exit;
1985 } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
1986 cmdarg_err("\"-Tfields\" was specified, but no fields were "
1987 "specified with \"-e\".");
1989 exit_status = WS_EXIT_INVALID_OPTION;
1990 goto clean_exit;
1993 if (dissect_color) {
1994 if (!color_filters_init(&err_msg, NULL)) {
1995 fprintf(stderr, "%s\n", err_msg);
1996 g_free(err_msg);
2000 /* If no capture filter or display filter has been specified, and there are
2001 still command-line arguments, treat them as the tokens of a capture
2002 filter (if no "-r" flag was specified) or a display filter (if a "-r"
2003 flag was specified. */
2004 if (ws_optind < argc) {
2005 if (cf_name != NULL) {
2006 if (dfilter != NULL) {
2007 cmdarg_err("Display filters were specified both with \"-Y\" "
2008 "and with additional command-line arguments.");
2009 exit_status = WS_EXIT_INVALID_OPTION;
2010 goto clean_exit;
2012 dfilter = get_args_as_string(argc, argv, ws_optind);
2013 } else {
2014 #ifdef HAVE_LIBPCAP
2015 unsigned i;
2017 if (global_capture_opts.default_options.cfilter) {
2018 cmdarg_err("A default capture filter was specified both with \"-f\""
2019 " and with additional command-line arguments.");
2020 exit_status = WS_EXIT_INVALID_OPTION;
2021 goto clean_exit;
2023 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2024 interface_options *interface_opts;
2025 interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
2026 if (interface_opts->cfilter == NULL) {
2027 interface_opts->cfilter = get_args_as_string(argc, argv, ws_optind);
2028 } else {
2029 cmdarg_err("A capture filter was specified both with \"-f\""
2030 " and with additional command-line arguments.");
2031 exit_status = WS_EXIT_INVALID_OPTION;
2032 goto clean_exit;
2035 global_capture_opts.default_options.cfilter = get_args_as_string(argc, argv, ws_optind);
2036 #else
2037 capture_option_specified = true;
2038 #endif
2042 if (!output_file_name) {
2043 /* We're not saving the capture to a file; if "-q" wasn't specified,
2044 we should print packet information */
2045 if (!quiet)
2046 print_packet_info = true;
2047 } else {
2048 const char *save_file = output_file_name;
2049 /* We're saving to a file; if we're writing to the standard output.
2050 and we'll also be writing dissected packets to the standard
2051 output, reject the request. At best, we could redirect that
2052 to the standard error; we *can't* write both to the standard
2053 output and have either of them be useful. */
2054 if (strcmp(save_file, "-") == 0 && print_packet_info) {
2055 cmdarg_err("You can't write both raw packet data and dissected packets"
2056 " to the standard output.");
2057 exit_status = WS_EXIT_INVALID_OPTION;
2058 goto clean_exit;
2060 if (compression_type == WTAP_UNKNOWN_COMPRESSION) {
2061 /* An explicitly specified compression type overrides filename
2062 * magic. (Should we allow a way to specify "no" compression
2063 * with, e.g. a ".gz" extension?) */
2064 const char *sfx = strrchr(save_file, '.');
2065 if (sfx) {
2066 compression_type = wtap_extension_to_compression_type(sfx + 1);
2071 if (compression_type == WTAP_UNKNOWN_COMPRESSION) {
2072 compression_type = WTAP_UNCOMPRESSED;
2075 if (!wtap_can_write_compression_type(compression_type)) {
2076 cmdarg_err("Output files can't be written as %s",
2077 wtap_compression_type_description(compression_type));
2078 exit_status = WS_EXIT_INVALID_OPTION;
2079 goto clean_exit;
2082 if (compression_type != WTAP_UNCOMPRESSED && !wtap_dump_can_compress(out_file_type)) {
2083 cmdarg_err("The file format %s can't be written to output compressed format",
2084 wtap_file_type_subtype_name(out_file_type));
2085 exit_status = WS_EXIT_INVALID_OPTION;
2086 goto clean_exit;
2089 if (compression_type != WTAP_UNCOMPRESSED && is_capturing) {
2090 cmdarg_err("Writing to compressed output is not supported for live captures");
2091 exit_status = WS_EXIT_INVALID_OPTION;
2092 goto clean_exit;
2095 #ifndef HAVE_LIBPCAP
2096 if (capture_option_specified)
2097 cmdarg_err("This version of TShark was not built with support for capturing packets.");
2098 #endif
2099 if (arg_error) {
2100 print_usage(stderr);
2101 exit_status = WS_EXIT_INVALID_OPTION;
2102 goto clean_exit;
2105 if (print_hex) {
2106 if (output_action != WRITE_TEXT && output_action != WRITE_JSON && output_action != WRITE_JSON_RAW && output_action != WRITE_EK) {
2107 cmdarg_err("Raw packet hex data can only be printed as text, PostScript, JSON, JSONRAW or EK JSON");
2108 exit_status = WS_EXIT_INVALID_OPTION;
2109 goto clean_exit;
2113 if (output_only != NULL) {
2114 char *ps;
2116 if (!print_details) {
2117 cmdarg_err("-O requires -V");
2118 exit_status = WS_EXIT_INVALID_OPTION;
2119 goto clean_exit;
2122 output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
2123 for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
2124 const char *name = ps;
2125 header_field_info *hfi = proto_registrar_get_byalias(name);
2126 if (hfi) {
2127 name = hfi->abbrev;
2129 g_hash_table_insert(output_only_tables, (void *)name, (void *)name);
2133 if (rfilter != NULL && !perform_two_pass_analysis) {
2134 cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
2135 exit_status = WS_EXIT_INVALID_OPTION;
2136 goto clean_exit;
2139 #ifdef HAVE_LIBPCAP
2140 if (caps_queries) {
2141 /* We're supposed to list the link-layer/timestamp types for an interface;
2142 did the user also specify a capture file to be read? */
2143 if (cf_name) {
2144 /* Yes - that's bogus. */
2145 cmdarg_err("You can't specify %s and a capture file to be read.",
2146 caps_queries & CAPS_QUERY_LINK_TYPES ? "-L" : "--list-time-stamp-types");
2147 exit_status = WS_EXIT_INVALID_OPTION;
2148 goto clean_exit;
2150 /* No - did they specify a ring buffer option? */
2151 if (global_capture_opts.multi_files_on) {
2152 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2153 exit_status = WS_EXIT_INVALID_OPTION;
2154 goto clean_exit;
2156 } else {
2157 if (cf_name) {
2159 * "-r" was specified, so we're reading a capture file.
2160 * Capture options don't apply here.
2163 /* We don't support capture filters when reading from a capture file
2164 (the BPF compiler doesn't support all link-layer types that we
2165 support in capture files we read). */
2166 if (global_capture_opts.default_options.cfilter) {
2167 cmdarg_err("Only read filters, not capture filters, "
2168 "can be specified when reading a capture file.");
2169 exit_status = WS_EXIT_INVALID_OPTION;
2170 goto clean_exit;
2172 if (global_capture_opts.multi_files_on) {
2173 cmdarg_err("Multiple capture files requested, but "
2174 "a capture isn't being done.");
2175 exit_status = WS_EXIT_INVALID_OPTION;
2176 goto clean_exit;
2178 if (global_capture_opts.has_file_duration) {
2179 cmdarg_err("Switching capture files after a time period was specified, but "
2180 "a capture isn't being done.");
2181 exit_status = WS_EXIT_INVALID_OPTION;
2182 goto clean_exit;
2184 if (global_capture_opts.has_file_interval) {
2185 cmdarg_err("Switching capture files after a time interval was specified, but "
2186 "a capture isn't being done.");
2187 exit_status = WS_EXIT_INVALID_OPTION;
2188 goto clean_exit;
2190 if (global_capture_opts.has_ring_num_files) {
2191 cmdarg_err("A ring buffer of capture files was specified, but "
2192 "a capture isn't being done.");
2193 exit_status = WS_EXIT_INVALID_OPTION;
2194 goto clean_exit;
2196 if (global_capture_opts.has_autostop_files) {
2197 cmdarg_err("A maximum number of capture files was specified, but "
2198 "a capture isn't being done.");
2199 exit_status = WS_EXIT_INVALID_OPTION;
2200 goto clean_exit;
2203 /* Note: TShark now allows the restriction of a _read_ file by packet count
2204 * and byte count as well as a write file. Other autostop options remain valid
2205 * only for a write file.
2207 if (global_capture_opts.has_autostop_duration) {
2208 cmdarg_err("A maximum capture time was specified, but "
2209 "a capture isn't being done.");
2210 exit_status = WS_EXIT_INVALID_OPTION;
2211 goto clean_exit;
2213 } else {
2215 * "-r" wasn't specified, so we're doing a live capture.
2217 bool use_pcapng = true;
2219 if (perform_two_pass_analysis) {
2220 /* Two-pass analysis doesn't work with live capture since it requires us
2221 * to buffer packets until we've read all of them, but a live capture
2222 * has no useful/meaningful definition of "all" */
2223 cmdarg_err("Live captures do not support two-pass analysis.");
2224 exit_status = WS_EXIT_INVALID_OPTION;
2225 goto clean_exit;
2228 if (global_capture_opts.saving_to_file) {
2229 /* They specified a "-w" flag, so we'll be saving to a capture file. */
2231 /* When capturing, we only support writing pcap or pcapng format. */
2232 if (out_file_type == wtap_pcapng_file_type_subtype()) {
2233 use_pcapng = true;
2234 } else if (out_file_type == wtap_pcap_file_type_subtype()) {
2235 use_pcapng = false;
2236 } else if (out_file_type == wtap_pcap_nsec_file_type_subtype()) {
2237 /* XXX - We request nanosecond time resolution regardless.
2238 * In the future wiretap might treat the two pcap subtypes
2239 * the same.
2241 use_pcapng = false;
2242 } else {
2243 cmdarg_err("Live captures can only be saved in pcap or pcapng format.");
2244 capture_opts_list_file_types();
2245 exit_status = WS_EXIT_INVALID_OPTION;
2246 goto clean_exit;
2248 if (capture_comments != NULL && !use_pcapng) {
2249 cmdarg_err("Capture comments can only be written to a pcapng file.");
2250 exit_status = WS_EXIT_INVALID_OPTION;
2251 goto clean_exit;
2253 if (global_capture_opts.multi_files_on) {
2254 /* Multiple-file mode doesn't work under certain conditions:
2255 a) it doesn't work if you're writing to the standard output;
2256 b) it doesn't work if you're writing to a pipe;
2258 if (strcmp(global_capture_opts.save_file, "-") == 0) {
2259 cmdarg_err("Multiple capture files requested, but "
2260 "the capture is being written to the standard output.");
2261 exit_status = WS_EXIT_INVALID_OPTION;
2262 goto clean_exit;
2264 if (global_capture_opts.output_to_pipe) {
2265 cmdarg_err("Multiple capture files requested, but "
2266 "the capture file is a pipe.");
2267 exit_status = WS_EXIT_INVALID_OPTION;
2268 goto clean_exit;
2270 if (!global_capture_opts.has_autostop_filesize &&
2271 !global_capture_opts.has_file_duration &&
2272 !global_capture_opts.has_file_interval &&
2273 !global_capture_opts.has_file_packets) {
2274 cmdarg_err("Multiple capture files requested, but "
2275 "no maximum capture file size, duration, interval or packets were specified.");
2276 exit_status = WS_EXIT_INVALID_OPTION;
2277 goto clean_exit;
2280 /* Currently, we don't support read or display filters when capturing
2281 and saving the packets. */
2282 if (rfilter != NULL) {
2283 cmdarg_err("Read filters aren't supported when capturing and saving the captured packets.");
2284 exit_status = WS_EXIT_INVALID_OPTION;
2285 goto clean_exit;
2287 if (dfilter != NULL) {
2288 cmdarg_err("Display filters aren't supported when capturing and saving the captured packets.");
2289 exit_status = WS_EXIT_INVALID_OPTION;
2290 goto clean_exit;
2292 global_capture_opts.use_pcapng = use_pcapng;
2293 } else {
2294 /* They didn't specify a "-w" flag, so we won't be saving to a
2295 capture file. Check for options that only make sense if
2296 we're saving to a file. */
2297 if (global_capture_opts.has_autostop_filesize) {
2298 cmdarg_err("Maximum capture file size specified, but "
2299 "capture isn't being saved to a file.");
2300 exit_status = WS_EXIT_INVALID_OPTION;
2301 goto clean_exit;
2303 if (global_capture_opts.multi_files_on) {
2304 cmdarg_err("Multiple capture files requested, but "
2305 "the capture isn't being saved to a file.");
2306 exit_status = WS_EXIT_INVALID_OPTION;
2307 goto clean_exit;
2309 if (capture_comments != NULL) {
2310 cmdarg_err("Capture comments were specified, but "
2311 "the capture isn't being saved to a file.");
2312 exit_status = WS_EXIT_INVALID_OPTION;
2313 goto clean_exit;
2318 #endif
2321 * If capture comments were specified, -w also has to have been specified.
2323 if (capture_comments != NULL) {
2324 if (output_file_name) {
2325 /* They specified a "-w" flag, so we'll be saving to a capture file.
2326 * This is fine if they're writing in a format that supports
2327 * section block comments.
2329 if (wtap_file_type_subtype_supports_option(out_file_type,
2330 WTAP_BLOCK_SECTION,
2331 OPT_COMMENT) == OPTION_NOT_SUPPORTED) {
2332 GArray *writable_type_subtypes;
2334 cmdarg_err("Capture comments can only be written to files of the following types:");
2335 writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME);
2336 for (unsigned i = 0; i < writable_type_subtypes->len; i++) {
2337 int ft = g_array_index(writable_type_subtypes, int, i);
2339 if (wtap_file_type_subtype_supports_option(ft, WTAP_BLOCK_SECTION,
2340 OPT_COMMENT) != OPTION_NOT_SUPPORTED)
2341 cmdarg_err_cont(" %s - %s", wtap_file_type_subtype_name(ft),
2342 wtap_file_type_subtype_description(ft));
2344 exit_status = WS_EXIT_INVALID_OPTION;
2345 goto clean_exit;
2348 else {
2349 cmdarg_err("Capture comments were specified, but you aren't writing a capture file.");
2350 exit_status = WS_EXIT_INVALID_OPTION;
2351 goto clean_exit;
2355 err_msg = ws_init_sockets();
2356 if (err_msg != NULL)
2358 cmdarg_err("%s", err_msg);
2359 g_free(err_msg);
2360 cmdarg_err_cont("%s", please_report_bug());
2361 exit_status = WS_EXIT_INIT_FAILED;
2362 goto clean_exit;
2365 /* Notify all registered modules that have had any of their preferences
2366 changed either from one of the preferences file or from the command
2367 line that their preferences have changed. */
2368 prefs_apply_all();
2370 /* We can also enable specified taps for export object */
2371 start_exportobjects();
2373 /* At this point MATE will have registered its field array so we can
2374 check if the fields specified by the user are all good.
2377 GSList* it = NULL;
2378 GSList *invalid_fields = output_fields_valid(output_fields);
2379 if (invalid_fields != NULL) {
2381 cmdarg_err("Some fields aren't valid:");
2382 for (it=invalid_fields; it != NULL; it = g_slist_next(it)) {
2383 cmdarg_err_cont("\t%s", (char *)it->data);
2385 g_slist_free(invalid_fields);
2386 exit_status = WS_EXIT_INVALID_OPTION;
2387 goto clean_exit;
2391 if (ex_opt_count("read_format") > 0) {
2392 const char* name = ex_opt_get_next("read_format");
2393 in_file_type = open_info_name_to_type(name);
2394 if (in_file_type == WTAP_TYPE_AUTO) {
2395 cmdarg_err("\"%s\" isn't a valid read file format type", name? name : "");
2396 list_read_capture_types();
2397 exit_status = WS_EXIT_INVALID_OPTION;
2398 goto clean_exit;
2402 if (global_dissect_options.time_format != TS_NOT_SET)
2403 timestamp_set_type(global_dissect_options.time_format);
2404 if (global_dissect_options.time_precision != TS_PREC_NOT_SET)
2405 timestamp_set_precision(global_dissect_options.time_precision);
2408 * Enabled and disabled protocols and heuristic dissectors as per
2409 * command-line options.
2411 if (!setup_enabled_and_disabled_protocols()) {
2412 exit_status = WS_EXIT_INVALID_OPTION;
2413 goto clean_exit;
2416 /* Build the column format array */
2417 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, true);
2419 /* Everything is setup, dump glossaries now if that's what we're doing.
2420 * We want to do this after protocols and heuristic dissectors are
2421 * enabled and disabled. Doing it after building the column format
2422 * array might make it easier to add a report that describes the
2423 * current list of columns and how to add a new one (#17332).
2425 if (glossary != NULL) {
2426 exit_status = dump_glossary(glossary, elastic_mapping_filter);
2427 goto clean_exit;
2430 #ifdef HAVE_LIBPCAP
2431 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2432 capture_opts_trim_ring_num_files(&global_capture_opts);
2433 #endif
2435 if (rfilter != NULL) {
2436 ws_debug("Compiling read filter: '%s'", rfilter);
2437 if (!compile_dfilter(rfilter, &rfcode)) {
2438 epan_cleanup();
2439 extcap_cleanup();
2441 #ifdef HAVE_LIBPCAP
2442 warn_about_capture_filter(rfilter);
2443 #endif
2445 exit_status = WS_EXIT_INVALID_INTERFACE;
2446 goto clean_exit;
2449 cfile.rfcode = rfcode;
2451 if (dfilter != NULL) {
2452 ws_debug("Compiling display filter: '%s'", dfilter);
2453 if (!compile_dfilter(dfilter, &dfcode)) {
2454 epan_cleanup();
2455 extcap_cleanup();
2457 #ifdef HAVE_LIBPCAP
2458 warn_about_capture_filter(dfilter);
2459 #endif
2461 exit_status = WS_EXIT_INVALID_FILTER;
2462 goto clean_exit;
2465 cfile.dfcode = dfcode;
2467 if (print_packet_info) {
2468 /* If we're printing as text or PostScript, we have
2469 to create a print stream. */
2470 if (output_action == WRITE_TEXT) {
2471 switch (print_format) {
2473 case PR_FMT_TEXT:
2474 print_stream = print_stream_text_stdio_new(stdout);
2475 break;
2477 case PR_FMT_PS:
2478 print_stream = print_stream_ps_stdio_new(stdout);
2479 break;
2481 default:
2482 ws_assert_not_reached();
2487 /* PDU export requested. Take the ownership of the '-w' file, apply tap
2488 * filters and start tapping. */
2489 if (pdu_export_arg) {
2490 const char *exp_pdu_tap_name = pdu_export_arg;
2491 const char *exp_pdu_filter = dfilter; /* may be NULL to disable filter */
2492 char *exp_pdu_error;
2493 int exp_fd;
2494 char *comment;
2496 if (!cf_name) {
2497 cmdarg_err("PDUs export requires a capture file (specify with -r).");
2498 exit_status = WS_EXIT_INVALID_OPTION;
2499 goto clean_exit;
2501 /* Take ownership of the '-w' output file. */
2502 exp_pdu_filename = output_file_name;
2503 output_file_name = NULL;
2504 #ifdef HAVE_LIBPCAP
2505 global_capture_opts.save_file = NULL;
2506 #endif
2507 if (exp_pdu_filename == NULL) {
2508 cmdarg_err("PDUs export requires an output file (-w).");
2509 exit_status = WS_EXIT_INVALID_OPTION;
2510 goto clean_exit;
2513 exp_pdu_error = exp_pdu_pre_open(exp_pdu_tap_name, exp_pdu_filter,
2514 &exp_pdu_tap_data);
2515 if (exp_pdu_error) {
2516 cmdarg_err("Cannot register tap: %s", exp_pdu_error);
2517 g_free(exp_pdu_error);
2518 list_export_pdu_taps();
2519 exit_status = INVALID_TAP;
2520 goto clean_exit;
2523 if (strcmp(exp_pdu_filename, "-") == 0) {
2524 /* Write to the standard output. */
2525 exp_fd = 1;
2526 } else {
2527 exp_fd = ws_open(exp_pdu_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
2528 if (exp_fd == -1) {
2529 cmdarg_err("%s: %s", exp_pdu_filename, file_open_error_message(errno, true));
2530 exit_status = WS_EXIT_INVALID_FILE;
2531 goto clean_exit;
2535 /* Activate the export PDU tap */
2536 /* Write to our output file with this comment (if the type supports it,
2537 * otherwise exp_pdu_open() will ignore the comment) */
2538 comment = ws_strdup_printf("Dump of PDUs from %s", cf_name);
2539 exp_pdu_status = exp_pdu_open(&exp_pdu_tap_data, exp_pdu_filename,
2540 out_file_type, exp_fd, comment,
2541 &err, &err_info);
2542 g_free(comment);
2543 if (!exp_pdu_status) {
2544 cfile_dump_open_failure_message(exp_pdu_filename, err, err_info,
2545 out_file_type);
2546 exit_status = INVALID_EXPORT;
2547 goto clean_exit;
2551 if (cf_name) {
2552 ws_debug("tshark: Opening capture file: %s", cf_name);
2554 * We're reading a capture file.
2556 if (cf_open(&cfile, cf_name, in_file_type, false, &err) != CF_OK) {
2557 epan_cleanup();
2558 extcap_cleanup();
2559 exit_status = WS_EXIT_INVALID_FILE;
2560 goto clean_exit;
2563 /* Start statistics taps; we do so after successfully opening the
2564 capture file, so we know we have something to compute stats
2565 on, and after registering all dissectors, so that MATE will
2566 have registered its field array so we can have a tap filter
2567 with one of MATE's late-registered fields as part of the
2568 filter. */
2569 start_requested_stats();
2571 /* Do we need to do dissection of packets? That depends on, among
2572 other things, what taps are listening, so determine that after
2573 starting the statistics taps. */
2574 do_dissection = must_do_dissection(rfcode, dfcode, pdu_export_arg);
2575 ws_debug("tshark: do_dissection = %s", do_dissection ? "TRUE" : "FALSE");
2577 /* Process the packets in the file */
2578 ws_debug("tshark: invoking process_cap_file() to process the packets");
2579 TRY {
2580 status = process_cap_file(&cfile, output_file_name, out_file_type, out_file_name_res,
2581 #ifdef HAVE_LIBPCAP
2582 global_capture_opts.has_autostop_packets ? global_capture_opts.autostop_packets : 0,
2583 global_capture_opts.has_autostop_filesize ? global_capture_opts.autostop_filesize : 0,
2584 global_capture_opts.has_autostop_written_packets ? global_capture_opts.autostop_written_packets : 0,
2585 compression_type);
2586 #else
2587 max_packet_count,
2590 WTAP_UNCOMPRESSED);
2591 #endif
2593 CATCH(OutOfMemoryError) {
2594 fprintf(stderr,
2595 "Out Of Memory.\n"
2596 "\n"
2597 "Sorry, but TShark has to terminate now.\n"
2598 "\n"
2599 "More information and workarounds can be found at\n"
2600 WS_WIKI_URL("KnownBugs/OutOfMemory") "\n");
2601 status = PROCESS_FILE_ERROR;
2603 ENDTRY;
2605 switch (status) {
2607 case PROCESS_FILE_SUCCEEDED:
2608 /* Everything worked OK; draw the taps. */
2609 draw_taps = true;
2610 break;
2612 case PROCESS_FILE_NO_FILE_PROCESSED:
2613 /* We never got to try to read the file, so there are no tap
2614 results to dump. Exit with an error status. */
2615 exit_status = 2;
2616 break;
2618 case PROCESS_FILE_ERROR:
2619 /* We still dump out the results of taps, etc., as we might have
2620 read some packets; however, we exit with an error status. */
2621 draw_taps = true;
2622 exit_status = 2;
2623 break;
2625 case PROCESS_FILE_INTERRUPTED:
2626 /* The user interrupted the read process; Don't dump out the
2627 result of taps, etc., and exit with an error status. */
2628 exit_status = 2;
2629 break;
2632 if (pdu_export_arg) {
2633 if (!exp_pdu_close(&exp_pdu_tap_data, &err, &err_info)) {
2634 cfile_close_failure_message(exp_pdu_filename, err, err_info);
2635 exit_status = 2;
2637 g_free(pdu_export_arg);
2638 g_free(exp_pdu_filename);
2640 } else {
2641 ws_debug("tshark: no capture file specified");
2642 /* No capture file specified, so we're supposed to do a live capture
2643 or get a list of link-layer types for a live capture device;
2644 do we have support for live captures? */
2645 #ifdef HAVE_LIBPCAP
2646 #ifdef _WIN32
2647 /* Warn the user if npf.sys isn't loaded. */
2648 if (!npf_sys_is_running()) {
2649 fprintf(stderr, "The NPF driver isn't running. You may have trouble "
2650 "capturing or\nlisting interfaces.\n");
2652 #endif /* _WIN32 */
2654 /* if no interface was specified, pick a default */
2655 exit_status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2656 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2657 if (exit_status != 0) {
2658 goto clean_exit;
2662 * If requested, list the link layer types and/or time stamp types
2663 * and exit.
2665 if (caps_queries) {
2666 unsigned i;
2668 /* Get the list of link-layer types for the capture devices. */
2669 exit_status = EXIT_SUCCESS;
2670 GList *if_cap_queries = NULL;
2671 if_cap_query_t *if_cap_query;
2672 GHashTable *capability_hash;
2673 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2674 interface_options *interface_opts;
2675 interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
2676 if_cap_query = g_new(if_cap_query_t, 1);
2677 if_cap_query->name = interface_opts->name;
2678 if_cap_query->monitor_mode = interface_opts->monitor_mode;
2679 if_cap_query->auth_username = NULL;
2680 if_cap_query->auth_password = NULL;
2681 #ifdef HAVE_PCAP_REMOTE
2682 if (interface_opts->auth_type == CAPTURE_AUTH_PWD) {
2683 if_cap_query->auth_username = interface_opts->auth_username;
2684 if_cap_query->auth_password = interface_opts->auth_password;
2686 #endif
2687 if_cap_queries = g_list_prepend(if_cap_queries, if_cap_query);
2689 if_cap_queries = g_list_reverse(if_cap_queries);
2690 capability_hash = capture_get_if_list_capabilities(if_cap_queries, &err_str, &err_str_secondary, NULL);
2691 g_list_free_full(if_cap_queries, g_free);
2692 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2693 interface_options *interface_opts;
2694 interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
2695 if_capabilities_t *caps;
2696 caps = g_hash_table_lookup(capability_hash, interface_opts->name);
2697 if (caps == NULL) {
2698 cmdarg_err("%s%s%s", err_str, err_str_secondary ? "\n" : "", err_str_secondary ? err_str_secondary : "");
2699 g_free(err_str);
2700 g_free(err_str_secondary);
2701 exit_status = WS_EXIT_INVALID_CAPABILITY;
2702 break;
2704 exit_status = capture_opts_print_if_capabilities(caps, interface_opts,
2705 caps_queries);
2706 if (exit_status != EXIT_SUCCESS) {
2707 break;
2710 g_hash_table_destroy(capability_hash);
2711 goto clean_exit;
2715 * If the standard error isn't a terminal, don't print packet counts,
2716 * as they won't show up on the user's terminal and they'll get in
2717 * the way of error messages in the file (to which we assume the
2718 * standard error was redirected; if it's redirected to the null
2719 * device, there's no point in printing packet counts anyway).
2721 * Otherwise, if we're printing packet information and the standard
2722 * output is a terminal (which we assume means the standard output and
2723 * error are going to the same terminal), don't print packet counts,
2724 * as they'll get in the way of the packet information.
2726 * Otherwise, if the user specified -q, don't print packet counts.
2728 * Otherwise, print packet counts.
2730 * XXX - what if the user wants to do a live capture, doesn't want
2731 * to save it to a file, doesn't want information printed for each
2732 * packet, does want some "-z" statistic, and wants packet counts
2733 * so they know whether they're seeing any packets? -q will
2734 * suppress the information printed for each packet, but it'll
2735 * also suppress the packet counts.
2737 if (!ws_isatty(ws_fileno(stderr)))
2738 print_packet_counts = false;
2739 else if (print_packet_info && ws_isatty(ws_fileno(stdout)))
2740 print_packet_counts = false;
2741 else if (quiet)
2742 print_packet_counts = false;
2743 else
2744 print_packet_counts = true;
2746 ws_debug("tshark: performing live capture");
2748 /* Start statistics taps; we should only do so after the capture
2749 started successfully, so we know we have something to compute
2750 stats, but we currently don't check for that - see below.
2752 We do so after registering all dissectors, so that MATE will
2753 have registered its field array so we can have a tap filter
2754 with one of MATE's late-registered fields as part of the
2755 filter. */
2756 start_requested_stats();
2758 /* Do we need to do dissection of packets? That depends on, among
2759 other things, what taps are listening, so determine that after
2760 starting the statistics taps. */
2761 do_dissection = must_do_dissection(rfcode, dfcode, pdu_export_arg);
2762 ws_debug("tshark: do_dissection = %s", do_dissection ? "TRUE" : "FALSE");
2764 /* We're doing live capture; if the capture child is writing to a pipe,
2765 we can't do dissection, because that would mean two readers for
2766 the pipe, tshark and whatever else. */
2767 if (do_dissection && global_capture_opts.output_to_pipe) {
2768 if (tap_listeners_require_dissection()) {
2769 cmdarg_err("Taps aren't supported when capturing and saving to a pipe.");
2770 exit_status = WS_EXIT_INVALID_OPTION;
2771 goto clean_exit;
2773 if (print_packet_info) {
2774 cmdarg_err("Printing dissected packets isn't supported when capturing and saving to a pipe.");
2775 exit_status = WS_EXIT_INVALID_OPTION;
2776 goto clean_exit;
2778 /* We already checked the next three reasons for supersets of
2779 capturing and saving to a pipe, but this doesn't hurt. */
2780 if (pdu_export_arg) {
2781 cmdarg_err("PDUs export isn't supported when capturing and saving to a pipe.");
2782 exit_status = WS_EXIT_INVALID_OPTION;
2783 goto clean_exit;
2785 if (rfcode != NULL) {
2786 cmdarg_err("Read filters aren't supported when capturing and saving to a pipe.");
2787 exit_status = WS_EXIT_INVALID_OPTION;
2788 goto clean_exit;
2790 if (dfcode != NULL) {
2791 cmdarg_err("Display filters aren't supported when capturing and saving to a pipe.");
2792 exit_status = WS_EXIT_INVALID_OPTION;
2793 goto clean_exit;
2795 /* There's some other reason we're dissecting. */
2796 cmdarg_err("Dissection isn't supported when capturing and saving to a pipe.");
2797 exit_status = WS_EXIT_INVALID_OPTION;
2798 goto clean_exit;
2801 /* Write a preamble if we're printing one. Do this after all checking
2802 * for invalid options, so we don't print just a preamble and quit. */
2803 if (print_packet_info) {
2804 if (!write_preamble(&cfile)) {
2805 show_print_file_io_error();
2806 exit_status = WS_EXIT_INVALID_FILE;
2807 goto clean_exit;
2812 * XXX - this returns false if an error occurred, but it also
2813 * returns false if the capture stops because a time limit
2814 * was reached (and possibly other limits), so we can't assume
2815 * it means an error.
2817 * The capture code is a bit twisty, so it doesn't appear to
2818 * be an easy fix. We just ignore the return value for now.
2819 * Instead, pass on the exit status from the capture child.
2821 capture();
2822 exit_status = global_capture_session.fork_child_status;
2824 if (print_packet_info) {
2825 if (!write_finale()) {
2826 show_print_file_io_error();
2831 * If we never got a capture file, don't draw the taps; we not only
2832 * didn't capture any packets, we never even did any capturing.
2834 if (cfile.filename != NULL)
2835 draw_taps = true;
2836 #else
2837 /* No - complain. */
2838 cmdarg_err("This version of TShark was not built with support for capturing packets.");
2839 exit_status = INVALID_CAPTURE;
2840 goto clean_exit;
2841 #endif
2844 if (cfile.provider.frames != NULL) {
2845 free_frame_data_sequence(cfile.provider.frames);
2846 cfile.provider.frames = NULL;
2849 if (draw_taps)
2850 draw_tap_listeners(true);
2852 if (tls_session_keys_file) {
2853 size_t keylist_length;
2854 char *keylist = ssl_export_sessions(&keylist_length);
2855 write_file_binary_mode(tls_session_keys_file, keylist, keylist_length);
2856 g_free(keylist);
2859 if (opt_print_timers) {
2860 if (cf_name == NULL) {
2861 /* We're doind a live capture. That isn't currently supported
2862 * with timers. */
2863 ws_message("Ignoring option --print-timers because we are doing a live capture");
2865 else {
2866 print_elapsed_json(cf_name, dfilter);
2870 /* Memory cleanup */
2871 reset_tap_listeners();
2872 funnel_dump_all_text_windows();
2873 epan_free(cfile.epan);
2874 epan_cleanup();
2875 extcap_cleanup();
2877 output_fields_free(output_fields);
2878 output_fields = NULL;
2880 clean_exit:
2881 cf_close(&cfile);
2882 g_free(cf_name);
2883 destroy_print_stream(print_stream);
2884 g_free(output_file_name);
2885 #ifdef HAVE_LIBPCAP
2886 capture_opts_cleanup(&global_capture_opts);
2887 if (cached_if_list) {
2888 free_interface_list(cached_if_list);
2890 #endif
2891 col_cleanup(&cfile.cinfo);
2892 wtap_cleanup();
2893 free_progdirs();
2894 dfilter_free(dfcode);
2895 g_free(dfilter);
2896 return exit_status;
2899 bool loop_running;
2900 uint32_t packet_count;
2902 static epan_t *
2903 tshark_epan_new(capture_file *cf)
2905 static const struct packet_provider_funcs funcs = {
2906 cap_file_provider_get_frame_ts,
2907 cap_file_provider_get_interface_name,
2908 cap_file_provider_get_interface_description,
2909 NULL,
2912 return epan_new(&cf->provider, &funcs);
2915 #ifdef HAVE_LIBPCAP
2916 static bool
2917 capture(void)
2919 volatile bool ret = true;
2920 GString *str;
2921 GMainContext *ctx;
2922 #ifndef _WIN32
2923 struct sigaction action, oldaction;
2924 #endif
2926 /* Create new dissection section. */
2927 epan_free(cfile.epan);
2928 cfile.epan = tshark_epan_new(&cfile);
2930 #ifdef _WIN32
2931 /* Catch a CTRL+C event and, if we get it, clean up and exit. */
2932 SetConsoleCtrlHandler(capture_cleanup, true);
2933 #else /* _WIN32 */
2934 /* Catch SIGINT and SIGTERM and, if we get either of them,
2935 clean up and exit. If SIGHUP isn't being ignored, catch
2936 it too and, if we get it, clean up and exit.
2938 We restart any read that was in progress, so that it doesn't
2939 disrupt reading from the sync pipe. The signal handler tells
2940 the capture child to finish; it will report that it finished,
2941 or will exit abnormally, so we'll stop reading from the sync
2942 pipe, pick up the exit status, and quit. */
2943 memset(&action, 0, sizeof(action));
2944 action.sa_handler = capture_cleanup;
2945 action.sa_flags = SA_RESTART;
2946 sigemptyset(&action.sa_mask);
2947 sigaction(SIGTERM, &action, NULL);
2948 sigaction(SIGINT, &action, NULL);
2949 sigaction(SIGHUP, NULL, &oldaction);
2950 if (oldaction.sa_handler == SIG_DFL)
2951 sigaction(SIGHUP, &action, NULL);
2953 #ifdef SIGINFO
2954 /* Catch SIGINFO and, if we get it and we're capturing to a file in
2955 quiet mode, report the number of packets we've captured.
2957 Again, restart any read that was in progress, so that it doesn't
2958 disrupt reading from the sync pipe. */
2959 action.sa_handler = report_counts_siginfo;
2960 action.sa_flags = SA_RESTART;
2961 sigemptyset(&action.sa_mask);
2962 sigaction(SIGINFO, &action, NULL);
2963 #endif /* SIGINFO */
2964 #endif /* _WIN32 */
2966 global_capture_session.state = CAPTURE_PREPARING;
2968 /* Let the user know which interfaces were chosen. */
2969 str = get_iface_list_string(&global_capture_opts, IFLIST_QUOTE_IF_DESCRIPTION);
2970 if (really_quiet == false)
2971 fprintf(stderr, "Capturing on %s\n", str->str);
2972 fflush(stderr);
2973 g_string_free(str, TRUE);
2975 ret = sync_pipe_start(&global_capture_opts, capture_comments,
2976 &global_capture_session, &global_info_data, NULL);
2978 if (!ret)
2979 return false;
2982 * Force synchronous resolution of IP addresses; we're doing only
2983 * one pass, so we can't do it in the background and fix up past
2984 * dissections.
2986 set_resolution_synchrony(true);
2988 /* the actual capture loop */
2989 ctx = g_main_context_default();
2990 loop_running = true;
2994 while (loop_running)
2996 g_main_context_iteration(ctx, true);
2999 CATCH(OutOfMemoryError) {
3000 fprintf(stderr,
3001 "Out Of Memory.\n"
3002 "\n"
3003 "Sorry, but TShark has to terminate now.\n"
3004 "\n"
3005 "More information and workarounds can be found at\n"
3006 WS_WIKI_URL("KnownBugs/OutOfMemory") "\n");
3007 abort();
3009 ENDTRY;
3010 return ret;
3013 /* capture child detected an error */
3014 static void
3015 capture_input_error(capture_session *cap_session _U_, char *error_msg, char *secondary_error_msg)
3017 /* The primary message might be an empty string, e.g. when the error was
3018 * from extcap. (The extcap stderr is gathered when the session closes
3019 * and printed in capture_input_closed below.) */
3020 if (*error_msg != '\0') {
3021 cmdarg_err("%s", error_msg);
3022 if (secondary_error_msg != NULL && *secondary_error_msg != '\0') {
3023 /* We have both primary and secondary messages. */
3024 cmdarg_err_cont("%s", secondary_error_msg);
3030 /* capture child detected an capture filter related error */
3031 static void
3032 capture_input_cfilter_error(capture_session *cap_session, unsigned i, const char *error_message)
3034 capture_options *capture_opts = cap_session->capture_opts;
3035 dfilter_t *rfcode = NULL;
3036 interface_options *interface_opts;
3038 ws_assert(i < capture_opts->ifaces->len);
3039 interface_opts = &g_array_index(capture_opts->ifaces, interface_options, i);
3041 if (dfilter_compile(interface_opts->cfilter, &rfcode, NULL) && rfcode != NULL) {
3042 cmdarg_err(
3043 "Invalid capture filter \"%s\" for interface '%s'.\n"
3044 "\n"
3045 "That string looks like a valid display filter; however, it isn't a valid\n"
3046 "capture filter (%s).\n"
3047 "\n"
3048 "Note that display filters and capture filters don't have the same syntax,\n"
3049 "so you can't use most display filter expressions as capture filters.\n"
3050 "\n"
3051 "See the User's Guide for a description of the capture filter syntax.",
3052 interface_opts->cfilter, interface_opts->descr, error_message);
3053 dfilter_free(rfcode);
3054 } else {
3055 cmdarg_err(
3056 "Invalid capture filter \"%s\" for interface '%s'.\n"
3057 "\n"
3058 "That string isn't a valid capture filter (%s).\n"
3059 "See the User's Guide for a description of the capture filter syntax.",
3060 interface_opts->cfilter, interface_opts->descr, error_message);
3065 /* capture child tells us we have a new (or the first) capture file */
3066 static bool
3067 capture_input_new_file(capture_session *cap_session, char *new_file)
3069 capture_options *capture_opts = cap_session->capture_opts;
3070 capture_file *cf = cap_session->cf;
3071 bool is_tempfile;
3072 int err;
3074 if (really_quiet == false) {
3075 if (cap_session->state == CAPTURE_PREPARING) {
3076 ws_info("Capture started.");
3078 ws_info("File: \"%s\"", new_file);
3081 ws_assert(cap_session->state == CAPTURE_PREPARING || cap_session->state == CAPTURE_RUNNING);
3083 /* free the old filename */
3084 if (capture_opts->save_file != NULL) {
3086 /* we start a new capture file, close the old one (if we had one before) */
3087 if (cf->state != FILE_CLOSED) {
3088 cf_close(cf);
3091 g_free(capture_opts->save_file);
3092 is_tempfile = false;
3094 epan_free(cf->epan);
3095 cf->epan = tshark_epan_new(cf);
3096 } else {
3097 /* we didn't had a save_file before, must be a tempfile */
3098 is_tempfile = true;
3101 /* save the new filename */
3102 capture_opts->save_file = g_strdup(new_file);
3104 /* if we are in real-time mode, open the new file now */
3105 if (do_dissection) {
3106 /* this is probably unnecessary, but better safe than sorry */
3107 cap_session->cf->open_type = WTAP_TYPE_AUTO;
3108 /* Attempt to open the capture file and set up to read from it. */
3109 switch(cf_open(cap_session->cf, capture_opts->save_file, WTAP_TYPE_AUTO, is_tempfile, &err)) {
3110 case CF_OK:
3111 break;
3112 case CF_ERROR:
3113 /* Don't unlink (delete) the save file - leave it around,
3114 for debugging purposes. */
3115 g_free(capture_opts->save_file);
3116 capture_opts->save_file = NULL;
3117 return false;
3119 } else if (quiet && is_tempfile) {
3120 cf->state = FILE_READ_ABORTED;
3121 cf->filename = g_strdup(new_file);
3122 cf->is_tempfile = is_tempfile;
3125 cap_session->state = CAPTURE_RUNNING;
3127 return true;
3131 /* capture child tells us we have new packets to read */
3132 static void
3133 capture_input_new_packets(capture_session *cap_session, int to_read)
3135 bool ret;
3136 int err;
3137 char *err_info;
3138 int64_t data_offset;
3139 capture_file *cf = cap_session->cf;
3140 bool filtering_tap_listeners;
3141 unsigned tap_flags;
3143 #ifdef SIGINFO
3145 * Prevent a SIGINFO handler from writing to the standard error while
3146 * we're doing so or writing to the standard output; instead, have it
3147 * just set a flag telling us to print that information when we're done.
3149 infodelay = true;
3150 #endif /* SIGINFO */
3152 /* Do we have any tap listeners with filters? */
3153 filtering_tap_listeners = have_filtering_tap_listeners();
3155 /* Get the union of the flags for all tap listeners. */
3156 tap_flags = union_of_tap_listener_flags();
3158 if (do_dissection) {
3159 bool create_proto_tree;
3160 epan_dissect_t *edt;
3161 wtap_rec rec;
3162 Buffer buf;
3165 * Determine whether we need to create a protocol tree.
3166 * We do if:
3168 * we're going to apply a read filter;
3170 * we're going to apply a display filter;
3172 * we're going to print the protocol tree;
3174 * one of the tap listeners is going to apply a filter;
3176 * one of the tap listeners requires a protocol tree;
3178 * a postdissector wants field values or protocols
3179 * on the first pass;
3181 * we have custom columns (which require field values, which
3182 * currently requires that we build a protocol tree).
3184 create_proto_tree =
3185 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
3186 (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
3187 have_custom_cols(&cf->cinfo) || dissect_color);
3189 /* The protocol tree will be "visible", i.e., nothing faked, only if
3190 we're printing packet details, which is true if we're printing stuff
3191 ("print_packet_info" is true) and we're in verbose mode
3192 ("packet_details" is true). But if we specified certain fields with
3193 "-e", we'll prime those directly later. */
3194 bool visible = print_packet_info && print_details && output_fields_num_fields(output_fields) == 0;
3195 edt = epan_dissect_new(cf->epan, create_proto_tree, visible);
3197 wtap_rec_init(&rec);
3198 ws_buffer_init(&buf, 1514);
3200 while (to_read-- && cf->provider.wth) {
3201 wtap_cleareof(cf->provider.wth);
3202 ret = wtap_read(cf->provider.wth, &rec, &buf, &err, &err_info, &data_offset);
3203 reset_epan_mem(cf, edt, create_proto_tree, print_packet_info && print_details);
3204 if (ret == false) {
3205 /* read from file failed, tell the capture child to stop */
3206 sync_pipe_stop(cap_session);
3207 wtap_close(cf->provider.wth);
3208 cf->provider.wth = NULL;
3209 } else {
3210 ret = process_packet_single_pass(cf, edt, data_offset, &rec, &buf,
3211 tap_flags);
3213 if (ret != false) {
3214 /* packet successfully read and gone through the "Read Filter" */
3215 packet_count++;
3217 wtap_rec_reset(&rec);
3220 epan_dissect_free(edt);
3222 wtap_rec_cleanup(&rec);
3223 ws_buffer_free(&buf);
3225 } else {
3227 * Dumpcap's doing all the work; we're not doing any dissection.
3228 * Count all the packets it wrote.
3230 packet_count += to_read;
3233 if (print_packet_counts) {
3234 /* We're printing packet counts. */
3235 if (packet_count != 0) {
3236 fprintf(stderr, "\r%u ", packet_count);
3237 /* stderr could be line buffered */
3238 fflush(stderr);
3242 #ifdef SIGINFO
3244 * Allow SIGINFO handlers to write.
3246 infodelay = false;
3249 * If a SIGINFO handler asked us to write out capture counts, do so.
3251 if (infoprint)
3252 report_counts();
3253 #endif /* SIGINFO */
3256 static void
3257 report_counts(void)
3259 if ((print_packet_counts == false) && (really_quiet == false)) {
3260 /* Report the count only if we aren't printing a packet count
3261 as packets arrive. */
3262 fprintf(stderr, "%u packet%s captured\n", packet_count,
3263 plurality(packet_count, "", "s"));
3265 #ifdef SIGINFO
3266 infoprint = false; /* we just reported it */
3267 #endif /* SIGINFO */
3270 #ifdef SIGINFO
3271 static void
3272 report_counts_siginfo(int signum _U_)
3274 int sav_errno = errno;
3275 /* If we've been told to delay printing, just set a flag asking
3276 that we print counts (if we're supposed to), otherwise print
3277 the count of packets captured (if we're supposed to). */
3278 if (infodelay)
3279 infoprint = true;
3280 else
3281 report_counts();
3282 errno = sav_errno;
3284 #endif /* SIGINFO */
3287 /* capture child detected any packet drops? */
3288 static void
3289 capture_input_drops(capture_session *cap_session _U_, uint32_t dropped, const char* interface_name)
3291 if (print_packet_counts) {
3292 /* We're printing packet counts to stderr.
3293 Send a newline so that we move to the line after the packet count. */
3294 fprintf(stderr, "\n");
3297 if (dropped != 0) {
3298 /* We're printing packet counts to stderr.
3299 Send a newline so that we move to the line after the packet count. */
3300 if (interface_name != NULL) {
3301 fprintf(stderr, "%u packet%s dropped from %s\n", dropped, plurality(dropped, "", "s"), interface_name);
3302 } else {
3303 fprintf(stderr, "%u packet%s dropped\n", dropped, plurality(dropped, "", "s"));
3310 * Capture child closed its side of the pipe, report any error and
3311 * do the required cleanup.
3313 static void
3314 capture_input_closed(capture_session *cap_session _U_, char *msg)
3316 if (msg != NULL && *msg != '\0')
3317 fprintf(stderr, "tshark: %s\n", msg);
3319 report_counts();
3321 loop_running = false;
3324 #ifdef _WIN32
3325 static BOOL WINAPI
3326 capture_cleanup(DWORD ctrltype _U_)
3328 /* CTRL_C_EVENT is sort of like SIGINT, CTRL_BREAK_EVENT is unique to
3329 Windows, CTRL_CLOSE_EVENT is sort of like SIGHUP, CTRL_LOGOFF_EVENT
3330 is also sort of like SIGHUP, and CTRL_SHUTDOWN_EVENT is sort of
3331 like SIGTERM at least when the machine's shutting down.
3333 For now, we handle them all as indications that we should clean up
3334 and quit, just as we handle SIGINT, SIGHUP, and SIGTERM in that
3335 way on UNIX.
3337 We must return true so that no other handler - such as one that would
3338 terminate the process - gets called.
3340 XXX - for some reason, typing ^C to TShark, if you run this in
3341 a Cygwin console window in at least some versions of Cygwin,
3342 causes TShark to terminate immediately; this routine gets
3343 called, but the main loop doesn't get a chance to run and
3344 exit cleanly, at least if this is compiled with Microsoft Visual
3345 C++ (i.e., it's a property of the Cygwin console window or Bash;
3346 it happens if TShark is not built with Cygwin - for all I know,
3347 building it with Cygwin may make the problem go away). */
3349 /* tell the capture child to stop */
3350 sync_pipe_stop(&global_capture_session);
3352 /* don't stop our own loop already here, otherwise status messages and
3353 * cleanup wouldn't be done properly. The child will indicate the stop of
3354 * everything by calling capture_input_closed() later */
3356 return true;
3358 #else
3359 static void
3360 capture_cleanup(int signum _U_)
3362 /* tell the capture child to stop */
3363 sync_pipe_stop(&global_capture_session);
3365 /* don't stop our own loop already here, otherwise status messages and
3366 * cleanup wouldn't be done properly. The child will indicate the stop of
3367 * everything by calling capture_input_closed() later */
3369 #endif /* _WIN32 */
3370 #endif /* HAVE_LIBPCAP */
3372 static bool
3373 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
3374 int64_t offset, wtap_rec *rec, Buffer *buf)
3376 frame_data fdlocal;
3377 uint32_t framenum;
3378 bool passed;
3379 int64_t elapsed_start;
3381 /* The frame number of this packet is one more than the count of
3382 frames in this packet. */
3383 framenum = cf->count + 1;
3385 /* If we're not running a display filter and we're not printing any
3386 packet information, we don't need to do a dissection. This means
3387 that all packets can be marked as 'passed'. */
3388 passed = true;
3390 frame_data_init(&fdlocal, framenum, rec, offset, cum_bytes);
3392 /* If we're going to run a read filter or a display filter, set up to
3393 do a dissection and do so. (This is the first pass of two passes
3394 over the packets, so we will not be printing any information
3395 from the dissection or running taps on the packet; if we're doing
3396 any of that, we'll do it in the second pass.) */
3397 if (edt) {
3398 if (gbl_resolv_flags.network_name || gbl_resolv_flags.maxmind_geoip) {
3399 /* If we're doing async lookups, send any that are queued and
3400 * retrieve results.
3402 * Ideally we'd force any lookups that need to happen on the second pass
3403 * to be sent asynchronously on this pass so the results would be ready.
3404 * That will happen if they're involved in a filter (because we prime the
3405 * tree below), but not currently for taps, if we're printing packet
3406 * summaries or details, etc.
3408 * XXX - If we're running a read filter that depends on a resolved
3409 * name, we should be doing synchronous lookups in that case. Also
3410 * marking the dependent frames below might not work with a display
3411 * filter that depends on a resolved name.
3413 host_name_lookup_process();
3416 column_info *cinfo = NULL;
3418 /* If we're running a read filter, prime the epan_dissect_t with that
3419 filter. */
3420 if (cf->rfcode)
3421 epan_dissect_prime_with_dfilter(edt, cf->rfcode);
3423 if (cf->dfcode)
3424 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
3426 /* This is the first pass, so prime the epan_dissect_t with the
3427 hfids postdissectors want on the first pass. */
3428 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
3430 frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
3431 &cf->provider.ref, cf->provider.prev_dis);
3432 if (cf->provider.ref == &fdlocal) {
3433 ref_frame = fdlocal;
3434 cf->provider.ref = &ref_frame;
3437 /* If we're applying a filter that needs the columns, construct them. */
3438 if (dfilter_requires_columns(cf->rfcode) || dfilter_requires_columns(cf->dfcode)) {
3439 cinfo = &cf->cinfo;
3442 elapsed_start = g_get_monotonic_time();
3443 epan_dissect_run(edt, cf->cd_t, rec,
3444 ws_buffer_start_ptr(buf),
3445 &fdlocal, cinfo);
3446 tshark_elapsed.first_pass.dissect += g_get_monotonic_time() - elapsed_start;
3448 /* Run the read filter if we have one. */
3449 if (cf->rfcode) {
3450 elapsed_start = g_get_monotonic_time();
3451 passed = dfilter_apply_edt(cf->rfcode, edt);
3452 tshark_elapsed.first_pass.dfilter_read += g_get_monotonic_time() - elapsed_start;
3456 if (passed) {
3457 frame_data_set_after_dissect(&fdlocal, &cum_bytes);
3458 cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
3460 /* If we're not doing dissection then there won't be any dependent frames.
3461 * More importantly, edt.pi.fd.dependent_frames won't be initialized because
3462 * epan hasn't been initialized.
3463 * if we *are* doing dissection, then mark the dependent frames, but only
3464 * if a display filter was given and it matches this packet.
3466 if (edt && cf->dfcode) {
3467 elapsed_start = g_get_monotonic_time();
3468 if (dfilter_apply_edt(cf->dfcode, edt) && edt->pi.fd->dependent_frames) {
3469 g_hash_table_foreach(edt->pi.fd->dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
3472 if (selected_frame_number != 0 && selected_frame_number == cf->count + 1) {
3473 /* If we are doing dissection and we have a "selected frame"
3474 * then load that frame's references (if any) onto the compiled
3475 * display filter. Selected frame number is ordinal, count is cardinal. */
3476 dfilter_load_field_references(cf->dfcode, edt->tree);
3478 tshark_elapsed.first_pass.dfilter_filter += g_get_monotonic_time() - elapsed_start;
3481 cf->count++;
3482 } else {
3483 /* if we don't add it to the frame_data_sequence, clean it up right now
3484 * to avoid leaks */
3485 frame_data_destroy(&fdlocal);
3488 if (edt)
3489 epan_dissect_reset(edt);
3491 return passed;
3495 * Set if reading a file was interrupted by a CTRL_ event on Windows or
3496 * a signal on UN*X.
3498 static bool read_interrupted;
3500 #ifdef _WIN32
3501 static BOOL WINAPI
3502 read_cleanup(DWORD ctrltype _U_)
3504 /* CTRL_C_EVENT is sort of like SIGINT, CTRL_BREAK_EVENT is unique to
3505 Windows, CTRL_CLOSE_EVENT is sort of like SIGHUP, CTRL_LOGOFF_EVENT
3506 is also sort of like SIGHUP, and CTRL_SHUTDOWN_EVENT is sort of
3507 like SIGTERM at least when the machine's shutting down.
3509 For now, we handle them all as indications that we should clean up
3510 and quit, just as we handle SIGINT, SIGHUP, and SIGTERM in that
3511 way on UNIX.
3513 We must return true so that no other handler - such as one that would
3514 terminate the process - gets called.
3516 XXX - for some reason, typing ^C to TShark, if you run this in
3517 a Cygwin console window in at least some versions of Cygwin,
3518 causes TShark to terminate immediately; this routine gets
3519 called, but the main loop doesn't get a chance to run and
3520 exit cleanly, at least if this is compiled with Microsoft Visual
3521 C++ (i.e., it's a property of the Cygwin console window or Bash;
3522 it happens if TShark is not built with Cygwin - for all I know,
3523 building it with Cygwin may make the problem go away). */
3525 /* tell the read to stop */
3526 read_interrupted = true;
3528 return true;
3530 #else
3531 static void
3532 read_cleanup(int signum _U_)
3534 /* tell the read to stop */
3535 read_interrupted = true;
3537 #endif /* _WIN32 */
3539 typedef enum {
3540 PASS_SUCCEEDED,
3541 PASS_READ_ERROR,
3542 PASS_WRITE_ERROR,
3543 PASS_INTERRUPTED
3544 } pass_status_t;
3546 static pass_status_t
3547 process_cap_file_first_pass(capture_file *cf, int max_packet_count,
3548 int64_t max_byte_count, int *err, char **err_info)
3550 wtap_rec rec;
3551 Buffer buf;
3552 epan_dissect_t *edt = NULL;
3553 int64_t data_offset;
3554 pass_status_t status = PASS_SUCCEEDED;
3555 int framenum = 0;
3557 wtap_rec_init(&rec);
3558 ws_buffer_init(&buf, 1514);
3560 /* Allocate a frame_data_sequence for all the frames. */
3561 cf->provider.frames = new_frame_data_sequence();
3563 if (do_dissection) {
3564 bool create_proto_tree;
3567 * Determine whether we need to create a protocol tree.
3568 * We do if:
3570 * we're going to apply a read filter;
3572 * we're going to apply a display filter;
3574 * a postdissector wants field values or protocols
3575 * on the first pass.
3577 create_proto_tree =
3578 (cf->rfcode != NULL || cf->dfcode != NULL || postdissectors_want_hfids() || dissect_color);
3580 ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
3582 /* We're not going to display the protocol tree on this pass,
3583 so it's not going to be "visible". */
3584 edt = epan_dissect_new(cf->epan, create_proto_tree, false);
3587 ws_debug("tshark: reading records for first pass");
3588 *err = 0;
3589 while (wtap_read(cf->provider.wth, &rec, &buf, err, err_info, &data_offset)) {
3590 if (read_interrupted) {
3591 status = PASS_INTERRUPTED;
3592 break;
3594 framenum++;
3596 if (process_packet_first_pass(cf, edt, data_offset, &rec, &buf)) {
3597 /* Stop reading if we hit a stop condition */
3598 if (max_packet_count > 0 && framenum >= max_packet_count) {
3599 ws_debug("tshark: max_packet_count (%d) reached", max_packet_count);
3600 *err = 0; /* This is not an error */
3601 break;
3603 if (max_byte_count != 0 && data_offset >= max_byte_count) {
3604 ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached",
3605 data_offset, max_byte_count);
3606 *err = 0; /* This is not an error */
3607 break;
3610 wtap_rec_reset(&rec);
3612 if (*err != 0)
3613 status = PASS_READ_ERROR;
3615 if (edt)
3616 epan_dissect_free(edt);
3618 /* Close the sequential I/O side, to free up memory it requires. */
3619 wtap_sequential_close(cf->provider.wth);
3621 /* Allow the protocol dissectors to free up memory that they
3622 * don't need after the sequential run-through of the packets. */
3623 postseq_cleanup_all_protocols();
3625 cf->provider.prev_dis = NULL;
3626 cf->provider.prev_cap = NULL;
3628 ws_buffer_free(&buf);
3629 wtap_rec_cleanup(&rec);
3631 return status;
3634 static bool
3635 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
3636 frame_data *fdata, wtap_rec *rec,
3637 Buffer *buf, unsigned tap_flags _U_)
3639 column_info *cinfo;
3640 bool passed;
3641 wtap_block_t block = NULL;
3642 int64_t elapsed_start;
3644 /* If we're not running a display filter and we're not printing any
3645 packet information, we don't need to do a dissection. This means
3646 that all packets can be marked as 'passed'. */
3647 passed = true;
3649 /* If we're going to print packet information, or we're going to
3650 run a read filter, or we're going to process taps, set up to
3651 do a dissection and do so. (This is the second pass of two
3652 passes over the packets; that's the pass where we print
3653 packet information or run taps.) */
3654 if (edt) {
3655 /* If we're running a display filter, prime the epan_dissect_t with that
3656 filter. */
3657 if (cf->dfcode)
3658 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
3660 col_custom_prime_edt(edt, &cf->cinfo);
3662 output_fields_prime_edt(edt, output_fields);
3663 /* The PDML spec requires a 'geninfo' pseudo-protocol that needs
3664 * information from our 'frame' protocol.
3666 if (output_fields_num_fields(output_fields) != 0 &&
3667 output_action == WRITE_XML) {
3668 epan_dissect_prime_with_hfid(edt, proto_registrar_get_id_byname("frame"));
3671 /* We only need the columns if either
3672 1) some tap or filter needs the columns
3674 2) we're printing packet info but we're *not* verbose; in verbose
3675 mode, we print the protocol tree, not the protocol summary.
3677 3) there is a column mapped to an individual field
3679 if ((tap_listeners_require_columns()) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields) || dfilter_requires_columns(cf->dfcode))
3680 cinfo = &cf->cinfo;
3681 else
3682 cinfo = NULL;
3684 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
3685 &cf->provider.ref, cf->provider.prev_dis);
3686 if (cf->provider.ref == fdata) {
3687 ref_frame = *fdata;
3688 cf->provider.ref = &ref_frame;
3691 if (dissect_color) {
3692 color_filters_prime_edt(edt);
3693 fdata->need_colorize = 1;
3696 /* epan_dissect_run (and epan_dissect_reset) unref the block.
3697 * We need it later, e.g. in order to copy the options. */
3698 block = wtap_block_ref(rec->block);
3699 elapsed_start = g_get_monotonic_time();
3700 epan_dissect_run_with_taps(edt, cf->cd_t, rec,
3701 ws_buffer_start_ptr(buf),
3702 fdata, cinfo);
3703 tshark_elapsed.second_pass.dissect += g_get_monotonic_time() - elapsed_start;
3705 /* Run the display filter if we have one. */
3706 if (cf->dfcode) {
3707 elapsed_start = g_get_monotonic_time();
3708 passed = dfilter_apply_edt(cf->dfcode, edt);
3709 tshark_elapsed.second_pass.dfilter_filter += g_get_monotonic_time() - elapsed_start;
3713 if (passed) {
3714 frame_data_set_after_dissect(fdata, &cum_bytes);
3715 /* Process this packet. */
3716 if (print_packet_info) {
3717 /* We're printing packet information; print the information for
3718 this packet. */
3719 print_packet(cf, edt);
3721 /* If we're doing "line-buffering", flush the standard output
3722 after every packet. See the comment above, for the "-l"
3723 option, for an explanation of why we do that. */
3724 if (line_buffered)
3725 fflush(stdout);
3727 if (ferror(stdout)) {
3728 show_print_file_io_error();
3729 exit(2);
3732 cf->provider.prev_dis = fdata;
3734 cf->provider.prev_cap = fdata;
3736 if (edt) {
3737 epan_dissect_reset(edt);
3738 rec->block = block;
3740 return passed || fdata->dependent_of_displayed;
3743 static bool
3744 process_new_idbs(wtap *wth, wtap_dumper *pdh, int *err, char **err_info)
3746 wtap_block_t if_data;
3748 while ((if_data = wtap_get_next_interface_description(wth)) != NULL) {
3750 * Only add interface blocks if the output file supports (meaning
3751 * *requires*) them.
3753 * That mean that the abstract interface provided by libwiretap
3754 * involves WTAP_BLOCK_IF_ID_AND_INFO blocks.
3756 if (pdh != NULL) {
3757 if (wtap_file_type_subtype_supports_block(wtap_dump_file_type_subtype(pdh), WTAP_BLOCK_IF_ID_AND_INFO) != BLOCK_NOT_SUPPORTED) {
3758 if (!wtap_dump_add_idb(pdh, if_data, err, err_info))
3759 return false;
3763 return true;
3766 static pass_status_t
3767 process_cap_file_second_pass(capture_file *cf, wtap_dumper *pdh,
3768 int *err, char **err_info,
3769 volatile uint32_t *err_framenum,
3770 int max_write_packet_count)
3772 wtap_rec rec;
3773 Buffer buf;
3774 int framenum = 0;
3775 int write_framenum = 0;
3776 frame_data *fdata;
3777 bool filtering_tap_listeners;
3778 unsigned tap_flags;
3779 epan_dissect_t *edt = NULL;
3780 pass_status_t status = PASS_SUCCEEDED;
3783 * Process whatever IDBs we haven't seen yet. This will be all
3784 * the IDBs in the file, as we've finished reading it; they'll
3785 * all be at the beginning of the output file.
3787 if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
3788 *err_framenum = 0;
3789 return PASS_WRITE_ERROR;
3792 wtap_rec_init(&rec);
3793 ws_buffer_init(&buf, 1514);
3795 /* Do we have any tap listeners with filters? */
3796 filtering_tap_listeners = have_filtering_tap_listeners();
3798 /* Get the union of the flags for all tap listeners. */
3799 tap_flags = union_of_tap_listener_flags();
3801 if (do_dissection) {
3802 bool create_proto_tree;
3805 * Determine whether we need to create a protocol tree.
3806 * We do if:
3808 * we're going to apply a display filter;
3810 * we're going to print the protocol tree;
3812 * one of the tap listeners requires a protocol tree;
3814 * we have custom columns (which require field values, which
3815 * currently requires that we build a protocol tree).
3817 create_proto_tree =
3818 (cf->dfcode || print_details || filtering_tap_listeners ||
3819 (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo) || dissect_color);
3821 ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
3823 /* The protocol tree will be "visible", i.e., nothing faked, only if
3824 we're printing packet details, which is true if we're printing stuff
3825 ("print_packet_info" is true) and we're in verbose mode
3826 ("packet_details" is true). But if we specified certain fields with
3827 "-e", we'll prime those directly later. */
3828 bool visible = print_packet_info && print_details && output_fields_num_fields(output_fields) == 0;
3829 edt = epan_dissect_new(cf->epan, create_proto_tree, visible);
3833 * Force synchronous resolution of IP addresses; in this pass, we
3834 * can't do it in the background and fix up past dissections.
3836 set_resolution_synchrony(true);
3838 for (framenum = 1; framenum <= (int)cf->count; framenum++) {
3839 if (read_interrupted) {
3840 status = PASS_INTERRUPTED;
3841 break;
3843 fdata = frame_data_sequence_find(cf->provider.frames, framenum);
3844 if (!wtap_seek_read(cf->provider.wth, fdata->file_off, &rec, &buf, err,
3845 err_info)) {
3846 /* Error reading from the input file. */
3847 status = PASS_READ_ERROR;
3848 break;
3850 ws_debug("tshark: invoking process_packet_second_pass() for frame #%d", framenum);
3851 if (process_packet_second_pass(cf, edt, fdata, &rec, &buf, tap_flags)) {
3852 /* Either there's no read filtering or this packet passed the
3853 filter, so, if we're writing to a capture file, write
3854 this packet out. */
3855 write_framenum++;
3856 if (pdh != NULL) {
3857 ws_debug("tshark: writing packet #%d to outfile packet #%d", framenum, write_framenum);
3858 if (!wtap_dump(pdh, &rec, ws_buffer_start_ptr(&buf), err, err_info)) {
3859 /* Error writing to the output file. */
3860 ws_debug("tshark: error writing to a capture file (%d)", *err);
3861 *err_framenum = framenum;
3862 status = PASS_WRITE_ERROR;
3863 break;
3865 /* Stop reading if we hit a stop condition */
3866 if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) {
3867 ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count);
3868 *err = 0; /* This is not an error */
3869 break;
3873 wtap_rec_reset(&rec);
3876 if (edt)
3877 epan_dissect_free(edt);
3879 ws_buffer_free(&buf);
3880 wtap_rec_cleanup(&rec);
3882 return status;
3885 static pass_status_t
3886 process_cap_file_single_pass(capture_file *cf, wtap_dumper *pdh,
3887 int max_packet_count, int64_t max_byte_count,
3888 int max_write_packet_count,
3889 int *err, char **err_info,
3890 volatile uint32_t *err_framenum)
3892 wtap_rec rec;
3893 Buffer buf;
3894 bool create_proto_tree = false;
3895 bool filtering_tap_listeners;
3896 unsigned tap_flags;
3897 int framenum = 0;
3898 int write_framenum = 0;
3899 epan_dissect_t *edt = NULL;
3900 int64_t data_offset;
3901 pass_status_t status = PASS_SUCCEEDED;
3903 wtap_rec_init(&rec);
3904 ws_buffer_init(&buf, 1514);
3906 /* Do we have any tap listeners with filters? */
3907 filtering_tap_listeners = have_filtering_tap_listeners();
3909 /* Get the union of the flags for all tap listeners. */
3910 tap_flags = union_of_tap_listener_flags();
3912 if (do_dissection) {
3914 * Determine whether we need to create a protocol tree.
3915 * We do if:
3917 * we're going to apply a read filter;
3919 * we're going to apply a display filter;
3921 * we're going to print the protocol tree;
3923 * one of the tap listeners is going to apply a filter;
3925 * one of the tap listeners requires a protocol tree;
3927 * a postdissector wants field values or protocols
3928 * on the first pass;
3930 * we have custom columns (which require field values, which
3931 * currently requires that we build a protocol tree).
3933 create_proto_tree =
3934 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
3935 (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
3936 have_custom_cols(&cf->cinfo) || dissect_color);
3938 ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
3940 /* The protocol tree will be "visible", i.e., nothing faked, only if
3941 we're printing packet details, which is true if we're printing stuff
3942 ("print_packet_info" is true) and we're in verbose mode
3943 ("packet_details" is true). But if we specified certain fields with
3944 "-e", we'll prime those directly later. */
3945 bool visible = print_packet_info && print_details && output_fields_num_fields(output_fields) == 0;
3946 edt = epan_dissect_new(cf->epan, create_proto_tree, visible);
3950 * Force synchronous resolution of IP addresses; we're doing only
3951 * one pass, so we can't do it in the background and fix up past
3952 * dissections.
3954 set_resolution_synchrony(true);
3956 *err = 0;
3957 while (wtap_read(cf->provider.wth, &rec, &buf, err, err_info, &data_offset)) {
3958 if (read_interrupted) {
3959 status = PASS_INTERRUPTED;
3960 break;
3962 framenum++;
3965 * Process whatever IDBs we haven't seen yet.
3967 if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
3968 *err_framenum = framenum;
3969 status = PASS_WRITE_ERROR;
3970 break;
3973 ws_debug("tshark: processing packet #%d", framenum);
3975 reset_epan_mem(cf, edt, create_proto_tree, print_packet_info && print_details);
3977 if (process_packet_single_pass(cf, edt, data_offset, &rec, &buf, tap_flags)) {
3978 /* Either there's no read filtering or this packet passed the
3979 filter, so, if we're writing to a capture file, write
3980 this packet out. */
3981 write_framenum++;
3982 if (pdh != NULL) {
3983 ws_debug("tshark: writing packet #%d to outfile as #%d",
3984 framenum, write_framenum);
3985 if (!wtap_dump(pdh, &rec, ws_buffer_start_ptr(&buf), err, err_info)) {
3986 /* Error writing to the output file. */
3987 ws_debug("tshark: error writing to a capture file (%d)", *err);
3988 *err_framenum = framenum;
3989 status = PASS_WRITE_ERROR;
3990 break;
3994 /* Stop reading if we hit a stop condition */
3995 if (max_packet_count > 0 && framenum >= max_packet_count) {
3996 ws_debug("tshark: max_packet_count (%d) reached", max_packet_count);
3997 *err = 0; /* This is not an error */
3998 break;
4000 if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) {
4001 ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count);
4002 *err = 0; /* This is not an error */
4003 break;
4005 if (max_byte_count != 0 && data_offset >= max_byte_count) {
4006 ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached",
4007 data_offset, max_byte_count);
4008 *err = 0; /* This is not an error */
4009 break;
4011 wtap_rec_reset(&rec);
4013 if (status == PASS_SUCCEEDED) {
4014 if (*err != 0) {
4015 /* Error reading from the input file. */
4016 status = PASS_READ_ERROR;
4017 } else {
4019 * Process whatever IDBs we haven't seen yet.
4021 if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
4022 *err_framenum = framenum;
4023 status = PASS_WRITE_ERROR;
4028 if (edt)
4029 epan_dissect_free(edt);
4031 ws_buffer_free(&buf);
4032 wtap_rec_cleanup(&rec);
4034 return status;
4037 static process_file_status_t
4038 process_cap_file(capture_file *cf, char *save_file, int out_file_type,
4039 bool out_file_name_res, int max_packet_count, int64_t max_byte_count,
4040 int max_write_packet_count, wtap_compression_type compression_type)
4042 process_file_status_t status = PROCESS_FILE_SUCCEEDED;
4043 wtap_dumper *pdh;
4044 #ifndef _WIN32
4045 struct sigaction action, oldaction;
4046 #endif
4047 int err = 0, err_pass1 = 0;
4048 char *err_info = NULL, *err_info_pass1 = NULL;
4049 volatile uint32_t err_framenum;
4050 wtap_dump_params params = WTAP_DUMP_PARAMS_INIT;
4051 char *shb_user_appl;
4052 pass_status_t first_pass_status, second_pass_status;
4053 int64_t elapsed_start;
4055 if (save_file != NULL) {
4056 /* Set up to write to the capture file. */
4057 wtap_dump_params_init_no_idbs(&params, cf->provider.wth);
4059 /* If we don't have an application name add TShark */
4060 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) {
4061 /* this is free'd by wtap_block_unref() later */
4062 wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, "%s", get_appname_and_version());
4064 if (capture_comments != NULL) {
4065 for (unsigned i = 0; i < capture_comments->len; i++) {
4066 wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0),
4067 OPT_COMMENT, "%s",
4068 (char *)g_ptr_array_index(capture_comments, i));
4072 ws_debug("tshark: writing format type %d, to %s", out_file_type, save_file);
4073 if (strcmp(save_file, "-") == 0) {
4074 /* Write to the standard output. */
4075 pdh = wtap_dump_open_stdout(out_file_type, compression_type, &params,
4076 &err, &err_info);
4077 } else {
4078 pdh = wtap_dump_open(save_file, out_file_type, compression_type, &params,
4079 &err, &err_info);
4082 g_free(params.idb_inf);
4083 params.idb_inf = NULL;
4085 if (pdh == NULL) {
4086 /* We couldn't set up to write to the capture file. */
4087 cfile_dump_open_failure_message(save_file, err, err_info,
4088 out_file_type);
4089 status = PROCESS_FILE_NO_FILE_PROCESSED;
4090 goto out;
4092 } else {
4093 /* Set up to print packet information. */
4094 if (print_packet_info) {
4095 if (!write_preamble(cf)) {
4096 show_print_file_io_error();
4097 status = PROCESS_FILE_NO_FILE_PROCESSED;
4098 goto out;
4101 pdh = NULL;
4104 #ifdef _WIN32
4105 /* Catch a CTRL+C event and, if we get it, clean up and exit. */
4106 SetConsoleCtrlHandler(read_cleanup, true);
4107 #else /* _WIN32 */
4108 /* Catch SIGINT and SIGTERM and, if we get either of them,
4109 clean up and exit. If SIGHUP isn't being ignored, catch
4110 it too and, if we get it, clean up and exit.
4112 We restart any read that was in progress, so that it doesn't
4113 disrupt reading from the sync pipe. The signal handler tells
4114 the capture child to finish; it will report that it finished,
4115 or will exit abnormally, so we'll stop reading from the sync
4116 pipe, pick up the exit status, and quit. */
4117 memset(&action, 0, sizeof(action));
4118 action.sa_handler = read_cleanup;
4119 action.sa_flags = SA_RESTART;
4120 sigemptyset(&action.sa_mask);
4121 sigaction(SIGTERM, &action, NULL);
4122 sigaction(SIGINT, &action, NULL);
4123 sigaction(SIGHUP, NULL, &oldaction);
4124 if (oldaction.sa_handler == SIG_DFL)
4125 sigaction(SIGHUP, &action, NULL);
4126 #endif /* _WIN32 */
4128 if (perform_two_pass_analysis) {
4129 ws_debug("tshark: perform_two_pass_analysis, do_dissection=%s", do_dissection ? "TRUE" : "FALSE");
4131 elapsed_start = g_get_monotonic_time();
4132 first_pass_status = process_cap_file_first_pass(cf, max_packet_count,
4133 max_byte_count,
4134 &err_pass1,
4135 &err_info_pass1);
4136 tshark_elapsed.elapsed_first_pass = g_get_monotonic_time() - elapsed_start;
4138 ws_debug("tshark: done with first pass");
4140 if (first_pass_status == PASS_INTERRUPTED) {
4141 /* The first pass was interrupted; skip the second pass.
4142 It won't be run, so it won't get an error. */
4143 second_pass_status = PASS_SUCCEEDED;
4144 } else {
4146 * If we got a read error on the first pass, we still do the second
4147 * pass, so we can at least process the packets we read, and then
4148 * report the first-pass error after the second pass (and before
4149 * we report any second-pass errors), so all the errors show up
4150 * at the end.
4152 elapsed_start = g_get_monotonic_time();
4153 second_pass_status = process_cap_file_second_pass(cf, pdh, &err, &err_info,
4154 &err_framenum,
4155 max_write_packet_count);
4156 tshark_elapsed.elapsed_second_pass = g_get_monotonic_time() - elapsed_start;
4158 ws_debug("tshark: done with second pass");
4161 else {
4162 /* !perform_two_pass_analysis */
4163 ws_debug("tshark: perform one pass analysis, do_dissection=%s", do_dissection ? "TRUE" : "FALSE");
4165 first_pass_status = PASS_SUCCEEDED; /* There is no first pass */
4167 elapsed_start = g_get_monotonic_time();
4168 second_pass_status = process_cap_file_single_pass(cf, pdh,
4169 max_packet_count,
4170 max_byte_count,
4171 max_write_packet_count,
4172 &err, &err_info,
4173 &err_framenum);
4174 tshark_elapsed.elapsed_first_pass = g_get_monotonic_time() - elapsed_start;
4176 ws_debug("tshark: done with single pass");
4179 if (first_pass_status != PASS_SUCCEEDED ||
4180 second_pass_status != PASS_SUCCEEDED) {
4182 * At least one of the passes didn't succeed; either it got a failure
4183 * or it was interrupted.
4185 if (first_pass_status != PASS_INTERRUPTED ||
4186 second_pass_status != PASS_INTERRUPTED) {
4187 /* At least one of the passes got an error. */
4188 ws_debug("tshark: something failed along the line (%d)", err);
4190 * If we're printing packet data, and the standard output and error
4191 * are going to the same place, flush the standard output, so everything
4192 * buffered up is written, and then print a newline to the standard
4193 * error before printing the error message, to separate it from the
4194 * packet data. (Alas, that only works on UN*X; st_dev is meaningless,
4195 * and the _fstat() documentation at Microsoft doesn't indicate whether
4196 * st_ino is even supported.)
4198 #ifndef _WIN32
4199 if (print_packet_info) {
4200 ws_statb64 stat_stdout, stat_stderr;
4202 if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
4203 if (stat_stdout.st_dev == stat_stderr.st_dev &&
4204 stat_stdout.st_ino == stat_stderr.st_ino) {
4205 fflush(stdout);
4206 fprintf(stderr, "\n");
4210 #endif
4212 /* Report status of pass 1 of two-pass processing. */
4213 switch (first_pass_status) {
4215 case PASS_SUCCEEDED:
4216 /* No problem. */
4217 break;
4219 case PASS_READ_ERROR:
4220 /* Read error. */
4221 cfile_read_failure_message(cf->filename, err_pass1, err_info_pass1);
4222 status = PROCESS_FILE_ERROR;
4223 break;
4225 case PASS_WRITE_ERROR:
4226 /* Won't happen on the first pass. */
4227 break;
4229 case PASS_INTERRUPTED:
4230 /* Not an error, so nothing to report. */
4231 status = PROCESS_FILE_INTERRUPTED;
4232 break;
4235 /* Report status of pass 2 of two-pass processing or the only pass
4236 of one-pass processing. */
4237 switch (second_pass_status) {
4239 case PASS_SUCCEEDED:
4240 /* No problem. */
4241 break;
4243 case PASS_READ_ERROR:
4244 /* Read error. */
4245 cfile_read_failure_message(cf->filename, err, err_info);
4246 status = PROCESS_FILE_ERROR;
4247 break;
4249 case PASS_WRITE_ERROR:
4250 /* Write error.
4251 XXX - framenum is not necessarily the frame number in
4252 the input file if there was a read filter. */
4253 cfile_write_failure_message(cf->filename, save_file, err, err_info,
4254 err_framenum, out_file_type);
4255 status = PROCESS_FILE_ERROR;
4256 break;
4258 case PASS_INTERRUPTED:
4259 /* Not an error, so nothing to report. */
4260 status = PROCESS_FILE_INTERRUPTED;
4261 break;
4264 if (save_file != NULL) {
4265 if (second_pass_status != PASS_WRITE_ERROR) {
4266 if (pdh && out_file_name_res) {
4267 /* XXX: This doesn't work as expected. First, it should be
4268 * moved to between the first and second passes (if doing
4269 * two-pass mode), so that the new NRB appears before packets,
4270 * which is better for subsequent one-pass mode. It never works
4271 * well in one-pass mode.
4273 * Second, it only writes hosts that we've done lookups for,
4274 * which means unless packet details are printed (or there's
4275 * a display filter that matches something that will do a host
4276 * lookup, e.g. -Y "ip") it doesn't actually have anything
4277 * in the list to save. Notably, that includes the case of
4278 * "tshark [-2] -H hosts.txt -r <infile> -w <outfile>",
4279 * which a user would certainly expect to dissect packets,
4280 * lookup hostnames, and add them to an NRB for later use.
4281 * A workaround is if "-V > /dev/null" is added, but who
4282 * expects that?
4284 * A third issue is that name resolution blocks aren't
4285 * written for live captures.
4287 if (!wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list())) {
4288 cmdarg_err("The file format \"%s\" doesn't support name resolution information.",
4289 wtap_file_type_subtype_name(out_file_type));
4292 /* Now close the capture file. */
4293 if (!wtap_dump_close(pdh, NULL, &err, &err_info)) {
4294 cfile_close_failure_message(save_file, err, err_info);
4295 status = PROCESS_FILE_ERROR;
4297 } else {
4298 /* We got a write error; it was reported, so just close the dump file
4299 without bothering to check for further errors. */
4300 wtap_dump_close(pdh, NULL, &err, &err_info);
4301 g_free(err_info);
4302 status = PROCESS_FILE_ERROR;
4304 } else {
4305 if (print_packet_info) {
4306 if (!write_finale()) {
4307 show_print_file_io_error();
4308 status = PROCESS_FILE_ERROR;
4313 out:
4314 wtap_close(cf->provider.wth);
4315 cf->provider.wth = NULL;
4317 wtap_dump_params_cleanup(&params);
4319 return status;
4322 static bool
4323 process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, int64_t offset,
4324 wtap_rec *rec, Buffer *buf, unsigned tap_flags _U_)
4326 frame_data fdata;
4327 column_info *cinfo;
4328 bool passed;
4329 wtap_block_t block = NULL;
4330 int64_t elapsed_start;
4332 /* Count this packet. */
4333 cf->count++;
4335 /* If we're not running a display filter and we're not printing any
4336 packet information, we don't need to do a dissection. This means
4337 that all packets can be marked as 'passed'. */
4338 passed = true;
4340 frame_data_init(&fdata, cf->count, rec, offset, cum_bytes);
4342 /* If we're going to print packet information, or we're going to
4343 run a read filter, or we're going to process taps, set up to
4344 do a dissection and do so. (This is the one and only pass
4345 over the packets, so, if we'll be printing packet information
4346 or running taps, we'll be doing it here.) */
4347 if (edt) {
4348 /* If we're running a filter, prime the epan_dissect_t with that
4349 filter. */
4350 if (cf->dfcode)
4351 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
4353 /* This is the first and only pass, so prime the epan_dissect_t
4354 with the hfids postdissectors want on the first pass. */
4355 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
4357 col_custom_prime_edt(edt, &cf->cinfo);
4359 output_fields_prime_edt(edt, output_fields);
4360 /* The PDML spec requires a 'geninfo' pseudo-protocol that needs
4361 * information from our 'frame' protocol.
4363 if (output_fields_num_fields(output_fields) != 0 &&
4364 output_action == WRITE_XML) {
4365 epan_dissect_prime_with_hfid(edt, proto_registrar_get_id_byname("frame"));
4368 /* We only need the columns if either
4369 1) some tap or filter needs the columns
4371 2) we're printing packet info but we're *not* verbose; in verbose
4372 mode, we print the protocol tree, not the protocol summary.
4374 3) there is a column mapped as an individual field */
4375 if ((tap_listeners_require_columns()) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields) || dfilter_requires_columns(cf->dfcode))
4376 cinfo = &cf->cinfo;
4377 else
4378 cinfo = NULL;
4380 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
4381 &cf->provider.ref, cf->provider.prev_dis);
4382 if (cf->provider.ref == &fdata) {
4383 ref_frame = fdata;
4384 cf->provider.ref = &ref_frame;
4387 if (dissect_color) {
4388 color_filters_prime_edt(edt);
4389 fdata.need_colorize = 1;
4392 /* epan_dissect_run (and epan_dissect_reset) unref the block.
4393 * We need it later, e.g. in order to copy the options. */
4394 block = wtap_block_ref(rec->block);
4395 elapsed_start = g_get_monotonic_time();
4396 epan_dissect_run_with_taps(edt, cf->cd_t, rec,
4397 ws_buffer_start_ptr(buf),
4398 &fdata, cinfo);
4399 tshark_elapsed.first_pass.dissect += g_get_monotonic_time() - elapsed_start;
4401 /* Run the filter if we have it. */
4402 if (cf->dfcode) {
4403 elapsed_start = g_get_monotonic_time();
4404 passed = dfilter_apply_edt(cf->dfcode, edt);
4405 tshark_elapsed.first_pass.dfilter_filter += g_get_monotonic_time() - elapsed_start;
4409 if (passed) {
4410 frame_data_set_after_dissect(&fdata, &cum_bytes);
4412 /* Process this packet. */
4413 if (print_packet_info) {
4414 /* We're printing packet information; print the information for
4415 this packet. */
4416 ws_assert(edt);
4417 print_packet(cf, edt);
4419 /* If we're doing "line-buffering", flush the standard output
4420 after every packet. See the comment above, for the "-l"
4421 option, for an explanation of why we do that. */
4422 if (line_buffered)
4423 fflush(stdout);
4425 if (ferror(stdout)) {
4426 show_print_file_io_error();
4427 exit(2);
4431 /* this must be set after print_packet() [bug #8160] */
4432 prev_dis_frame = fdata;
4433 cf->provider.prev_dis = &prev_dis_frame;
4436 prev_cap_frame = fdata;
4437 cf->provider.prev_cap = &prev_cap_frame;
4439 if (edt) {
4440 epan_dissect_reset(edt);
4441 frame_data_destroy(&fdata);
4442 rec->block = block;
4444 return passed;
4447 static bool
4448 write_preamble(capture_file *cf)
4450 switch (output_action) {
4452 case WRITE_TEXT:
4453 return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
4455 case WRITE_XML:
4456 if (print_details)
4457 write_pdml_preamble(stdout, cf->filename);
4458 else
4459 write_psml_preamble(&cf->cinfo, stdout);
4460 return !ferror(stdout);
4462 case WRITE_FIELDS:
4463 write_fields_preamble(output_fields, stdout);
4464 return !ferror(stdout);
4466 case WRITE_JSON:
4467 case WRITE_JSON_RAW:
4468 jdumper = write_json_preamble(stdout);
4469 return !ferror(stdout);
4471 case WRITE_EK:
4472 return true;
4474 default:
4475 ws_assert_not_reached();
4476 return false;
4480 static char *
4481 get_line_buf(size_t len)
4483 static char *line_bufp = NULL;
4484 static size_t line_buf_len = 256;
4485 size_t new_line_buf_len;
4487 for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
4488 new_line_buf_len *= 2)
4490 if (line_bufp == NULL) {
4491 line_buf_len = new_line_buf_len;
4492 line_bufp = (char *)g_malloc(line_buf_len + 1);
4493 } else {
4494 if (new_line_buf_len > line_buf_len) {
4495 line_buf_len = new_line_buf_len;
4496 line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
4499 return line_bufp;
4502 static inline void
4503 put_string(char *dest, const char *str, size_t str_len)
4505 memcpy(dest, str, str_len);
4506 dest[str_len] = '\0';
4509 static inline void
4510 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
4512 size_t i;
4514 for (i = str_len; i < str_with_spaces; i++)
4515 *dest++ = ' ';
4517 put_string(dest, str, str_len);
4520 static inline void
4521 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
4523 size_t i;
4525 memcpy(dest, str, str_len);
4526 for (i = str_len; i < str_with_spaces; i++)
4527 dest[i] = ' ';
4529 dest[str_with_spaces] = '\0';
4532 static bool
4533 print_columns(capture_file *cf, const epan_dissect_t *edt)
4535 char *line_bufp;
4536 int i;
4537 size_t buf_offset;
4538 size_t column_len;
4539 size_t col_len;
4540 col_item_t* col_item;
4541 char str_format[11];
4542 const color_filter_t *color_filter = NULL;
4544 line_bufp = get_line_buf(256);
4545 buf_offset = 0;
4546 *line_bufp = '\0';
4548 if (dissect_color)
4549 color_filter = edt->pi.fd->color_filter;
4551 for (i = 0; i < cf->cinfo.num_cols; i++) {
4552 col_item = &cf->cinfo.columns[i];
4553 /* Skip columns not marked as visible. */
4554 if (!get_column_visible(i))
4555 continue;
4556 const char* col_text = get_column_text(&cf->cinfo, i);
4557 switch (col_item->col_fmt) {
4558 case COL_NUMBER:
4559 case COL_NUMBER_DIS:
4560 column_len = col_len = strlen(col_text);
4561 if (column_len < 5)
4562 column_len = 5;
4563 line_bufp = get_line_buf(buf_offset + column_len);
4564 put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
4565 break;
4567 case COL_CLS_TIME:
4568 case COL_REL_TIME:
4569 case COL_ABS_TIME:
4570 case COL_ABS_YMD_TIME: /* XXX - wider */
4571 case COL_ABS_YDOY_TIME: /* XXX - wider */
4572 case COL_UTC_TIME:
4573 case COL_UTC_YMD_TIME: /* XXX - wider */
4574 case COL_UTC_YDOY_TIME: /* XXX - wider */
4575 column_len = col_len = strlen(col_text);
4576 if (column_len < 10)
4577 column_len = 10;
4578 line_bufp = get_line_buf(buf_offset + column_len);
4579 put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
4580 break;
4582 case COL_DEF_SRC:
4583 case COL_RES_SRC:
4584 case COL_UNRES_SRC:
4585 case COL_DEF_DL_SRC:
4586 case COL_RES_DL_SRC:
4587 case COL_UNRES_DL_SRC:
4588 case COL_DEF_NET_SRC:
4589 case COL_RES_NET_SRC:
4590 case COL_UNRES_NET_SRC:
4591 column_len = col_len = strlen(col_text);
4592 if (column_len < 12)
4593 column_len = 12;
4594 line_bufp = get_line_buf(buf_offset + column_len);
4595 put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
4596 break;
4598 case COL_DEF_DST:
4599 case COL_RES_DST:
4600 case COL_UNRES_DST:
4601 case COL_DEF_DL_DST:
4602 case COL_RES_DL_DST:
4603 case COL_UNRES_DL_DST:
4604 case COL_DEF_NET_DST:
4605 case COL_RES_NET_DST:
4606 case COL_UNRES_NET_DST:
4607 column_len = col_len = strlen(col_text);
4608 if (column_len < 12)
4609 column_len = 12;
4610 line_bufp = get_line_buf(buf_offset + column_len);
4611 put_string_spaces(line_bufp + buf_offset, col_text, col_len, column_len);
4612 break;
4614 default:
4615 column_len = strlen(col_text);
4616 line_bufp = get_line_buf(buf_offset + column_len);
4617 put_string(line_bufp + buf_offset, col_text, column_len);
4618 break;
4620 buf_offset += column_len;
4621 if (i != cf->cinfo.num_cols - 1) {
4623 * This isn't the last column, so we need to print a
4624 * separator between this column and the next.
4626 * If we printed a network source and are printing a
4627 * network destination of the same type next, separate
4628 * them with a UTF-8 right arrow; if we printed a network
4629 * destination and are printing a network source of the same
4630 * type next, separate them with a UTF-8 left arrow;
4631 * otherwise separate them with a space.
4633 * We add enough space to the buffer for " \xe2\x86\x90 "
4634 * or " \xe2\x86\x92 ", even if we're only adding " ".
4636 line_bufp = get_line_buf(buf_offset + 5);
4637 switch (col_item->col_fmt) {
4639 case COL_DEF_SRC:
4640 case COL_RES_SRC:
4641 case COL_UNRES_SRC:
4642 switch (cf->cinfo.columns[i+1].col_fmt) {
4644 case COL_DEF_DST:
4645 case COL_RES_DST:
4646 case COL_UNRES_DST:
4647 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
4648 put_string(line_bufp + buf_offset, str_format, 5);
4649 buf_offset += 5;
4650 break;
4652 default:
4653 put_string(line_bufp + buf_offset, delimiter_char, 1);
4654 buf_offset += 1;
4655 break;
4657 break;
4659 case COL_DEF_DL_SRC:
4660 case COL_RES_DL_SRC:
4661 case COL_UNRES_DL_SRC:
4662 switch (cf->cinfo.columns[i+1].col_fmt) {
4664 case COL_DEF_DL_DST:
4665 case COL_RES_DL_DST:
4666 case COL_UNRES_DL_DST:
4667 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
4668 put_string(line_bufp + buf_offset, str_format, 5);
4669 buf_offset += 5;
4670 break;
4672 default:
4673 put_string(line_bufp + buf_offset, delimiter_char, 1);
4674 buf_offset += 1;
4675 break;
4677 break;
4679 case COL_DEF_NET_SRC:
4680 case COL_RES_NET_SRC:
4681 case COL_UNRES_NET_SRC:
4682 switch (cf->cinfo.columns[i+1].col_fmt) {
4684 case COL_DEF_NET_DST:
4685 case COL_RES_NET_DST:
4686 case COL_UNRES_NET_DST:
4687 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
4688 put_string(line_bufp + buf_offset, str_format, 5);
4689 buf_offset += 5;
4690 break;
4692 default:
4693 put_string(line_bufp + buf_offset, delimiter_char, 1);
4694 buf_offset += 1;
4695 break;
4697 break;
4699 case COL_DEF_DST:
4700 case COL_RES_DST:
4701 case COL_UNRES_DST:
4702 switch (cf->cinfo.columns[i+1].col_fmt) {
4704 case COL_DEF_SRC:
4705 case COL_RES_SRC:
4706 case COL_UNRES_SRC:
4707 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
4708 put_string(line_bufp + buf_offset, str_format, 5);
4709 buf_offset += 5;
4710 break;
4712 default:
4713 put_string(line_bufp + buf_offset, delimiter_char, 1);
4714 buf_offset += 1;
4715 break;
4717 break;
4719 case COL_DEF_DL_DST:
4720 case COL_RES_DL_DST:
4721 case COL_UNRES_DL_DST:
4722 switch (cf->cinfo.columns[i+1].col_fmt) {
4724 case COL_DEF_DL_SRC:
4725 case COL_RES_DL_SRC:
4726 case COL_UNRES_DL_SRC:
4727 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
4728 put_string(line_bufp + buf_offset, str_format, 5);
4729 buf_offset += 5;
4730 break;
4732 default:
4733 put_string(line_bufp + buf_offset, delimiter_char, 1);
4734 buf_offset += 1;
4735 break;
4737 break;
4739 case COL_DEF_NET_DST:
4740 case COL_RES_NET_DST:
4741 case COL_UNRES_NET_DST:
4742 switch (cf->cinfo.columns[i+1].col_fmt) {
4744 case COL_DEF_NET_SRC:
4745 case COL_RES_NET_SRC:
4746 case COL_UNRES_NET_SRC:
4747 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
4748 put_string(line_bufp + buf_offset, str_format, 5);
4749 buf_offset += 5;
4750 break;
4752 default:
4753 put_string(line_bufp + buf_offset, delimiter_char, 1);
4754 buf_offset += 1;
4755 break;
4757 break;
4759 default:
4760 put_string(line_bufp + buf_offset, delimiter_char, 1);
4761 buf_offset += 1;
4762 break;
4767 if (dissect_color && color_filter != NULL)
4768 return print_line_color(print_stream, 0, line_bufp, &color_filter->fg_color, &color_filter->bg_color);
4769 else
4770 return print_line(print_stream, 0, line_bufp);
4773 static bool
4774 print_packet(capture_file *cf, epan_dissect_t *edt)
4776 if (print_summary || output_fields_has_cols(output_fields))
4777 /* Just fill in the columns. */
4778 epan_dissect_fill_in_columns(edt, false, true);
4780 /* Print summary columns and/or protocol tree */
4781 switch (output_action) {
4783 case WRITE_TEXT:
4784 if (print_summary && !print_columns(cf, edt))
4785 return false;
4786 if (print_details) {
4787 if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
4788 print_hex, edt, output_only_tables, print_stream))
4789 return false;
4790 if (!print_hex) {
4791 if (!print_line(print_stream, 0, separator))
4792 return false;
4795 break;
4797 case WRITE_XML:
4798 if (print_summary) {
4799 write_psml_columns(edt, stdout, dissect_color);
4800 return !ferror(stdout);
4802 if (print_details) {
4803 write_pdml_proto_tree(output_fields, edt, &cf->cinfo, stdout, dissect_color);
4804 printf("\n");
4805 return !ferror(stdout);
4807 break;
4809 case WRITE_FIELDS:
4810 if (print_summary) {
4811 /*No non-verbose "fields" format */
4812 ws_assert_not_reached();
4814 if (print_details) {
4815 write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
4816 printf("\n");
4817 return !ferror(stdout);
4819 break;
4821 case WRITE_JSON:
4822 if (print_summary)
4823 ws_assert_not_reached();
4824 if (print_details) {
4825 write_json_proto_tree(output_fields, print_dissections_expanded,
4826 print_hex, edt, &cf->cinfo, node_children_grouper, &jdumper);
4827 return !ferror(stdout);
4829 break;
4831 case WRITE_JSON_RAW:
4832 if (print_summary)
4833 ws_assert_not_reached();
4834 if (print_details) {
4835 write_json_proto_tree(output_fields, print_dissections_none,
4836 true, edt, &cf->cinfo, node_children_grouper, &jdumper);
4837 return !ferror(stdout);
4839 break;
4841 case WRITE_EK:
4842 write_ek_proto_tree(output_fields, print_summary, print_hex,
4843 edt, &cf->cinfo, stdout);
4844 return !ferror(stdout);
4846 default:
4847 ws_assert_not_reached();
4850 if (print_hex) {
4851 if (print_summary || print_details) {
4852 if (!print_line(print_stream, 0, ""))
4853 return false;
4855 if (!print_hex_data(print_stream, edt, hexdump_source_option | hexdump_ascii_option))
4856 return false;
4857 if (!print_line(print_stream, 0, separator))
4858 return false;
4860 return true;
4863 static bool
4864 write_finale(void)
4866 switch (output_action) {
4868 case WRITE_TEXT:
4869 return print_finale(print_stream);
4871 case WRITE_XML:
4872 if (print_details)
4873 write_pdml_finale(stdout);
4874 else
4875 write_psml_finale(stdout);
4876 return !ferror(stdout);
4878 case WRITE_FIELDS:
4879 write_fields_finale(output_fields, stdout);
4880 return !ferror(stdout);
4882 case WRITE_JSON:
4883 case WRITE_JSON_RAW:
4884 write_json_finale(&jdumper);
4885 return !ferror(stdout);
4887 case WRITE_EK:
4888 return true;
4890 default:
4891 ws_assert_not_reached();
4892 return false;
4896 void
4897 cf_close(capture_file *cf)
4899 if (cf->state == FILE_CLOSED)
4900 return; /* Nothing to do */
4902 if (cf->provider.wth != NULL) {
4903 wtap_close(cf->provider.wth);
4904 cf->provider.wth = NULL;
4906 /* We have no file open... */
4907 if (cf->filename != NULL) {
4908 /* If it's a temporary file, remove it. */
4909 if (cf->is_tempfile)
4910 ws_unlink(cf->filename);
4911 g_free(cf->filename);
4912 cf->filename = NULL;
4915 /* We have no file open. */
4916 cf->state = FILE_CLOSED;
4919 cf_status_t
4920 cf_open(capture_file *cf, const char *fname, unsigned int type, bool is_tempfile, int *err)
4922 wtap *wth;
4923 char *err_info;
4925 wth = wtap_open_offline(fname, type, err, &err_info, perform_two_pass_analysis);
4926 if (wth == NULL)
4927 goto fail;
4929 /* The open succeeded. Fill in the information for this file. */
4931 cf->provider.wth = wth;
4932 cf->f_datalen = 0; /* not used, but set it anyway */
4934 /* Set the file name because we need it to set the follow stream filter.
4935 XXX - is that still true? We need it for other reasons, though,
4936 in any case. */
4937 cf->filename = g_strdup(fname);
4939 /* Indicate whether it's a permanent or temporary file. */
4940 cf->is_tempfile = is_tempfile;
4942 /* No user changes yet. */
4943 cf->unsaved_changes = false;
4945 cf->cd_t = wtap_file_type_subtype(cf->provider.wth);
4946 cf->open_type = type;
4947 cf->count = 0;
4948 cf->drops_known = false;
4949 cf->drops = 0;
4950 cf->snap = wtap_snapshot_length(cf->provider.wth);
4951 nstime_set_zero(&cf->elapsed_time);
4952 cf->provider.ref = NULL;
4953 cf->provider.prev_dis = NULL;
4954 cf->provider.prev_cap = NULL;
4956 cf->state = FILE_READ_IN_PROGRESS;
4958 /* Create new epan session for dissection. */
4959 epan_free(cf->epan);
4960 cf->epan = tshark_epan_new(cf);
4962 wtap_set_cb_new_ipv4(cf->provider.wth, add_ipv4_name);
4963 wtap_set_cb_new_ipv6(cf->provider.wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
4964 wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
4966 return CF_OK;
4968 fail:
4969 cfile_open_failure_message(fname, *err, err_info);
4970 return CF_ERROR;
4973 static void
4974 show_print_file_io_error(void)
4976 switch (errno) {
4978 case ENOSPC:
4979 cmdarg_err("Not all the packets could be printed because there is "
4980 "no space left on the file system.");
4981 break;
4983 #ifdef EDQUOT
4984 case EDQUOT:
4985 cmdarg_err("Not all the packets could be printed because you are "
4986 "too close to, or over your disk quota.");
4987 break;
4988 #endif
4990 case EPIPE:
4992 * This almost certainly means "the next program after us in
4993 * the pipeline exited before we were finished writing", so
4994 * this isn't a real error, it just means we're done. (We
4995 * don't get SIGPIPE because libwireshark ignores SIGPIPE
4996 * to avoid getting killed if writing to the MaxMind process
4997 * gets SIGPIPE because that process died.)
4999 * Presumably either that program exited deliberately (for
5000 * example, "head -N" read N lines and printed them), in
5001 * which case there's no error to report, or it terminated
5002 * due to an error or a signal, in which case *that's* the
5003 * error and that error has been reported.
5005 break;
5007 default:
5008 #ifdef _WIN32
5009 if (errno == EINVAL && _doserrno == ERROR_NO_DATA) {
5011 * XXX - on Windows, a write to a pipe where the read side
5012 * has been closed apparently may return the Windows error
5013 * ERROR_BROKEN_PIPE, which the Visual Studio C library maps
5014 * to EPIPE, or may return the Windows error ERROR_NO_DATA,
5015 * which the Visual Studio C library maps to EINVAL.
5017 * Either of those almost certainly means "the next program
5018 * after us in the pipeline exited before we were finished
5019 * writing", so, if _doserrno is ERROR_NO_DATA, this isn't
5020 * a real error, it just means we're done. (Windows doesn't
5021 * SIGPIPE.)
5023 * Presumably either that program exited deliberately (for
5024 * example, "head -N" read N lines and printed them), in
5025 * which case there's no error to report, or it terminated
5026 * due to an error or a signal, in which case *that's* the
5027 * error and that error has been reported.
5029 break;
5033 * It's a different error; report it, but with the error
5034 * message for _doserrno, which will give more detail
5035 * than just "Invalid argument".
5037 cmdarg_err("An error occurred while printing packets: %s.",
5038 win32strerror(_doserrno));
5039 #else
5040 cmdarg_err("An error occurred while printing packets: %s.",
5041 g_strerror(errno));
5042 #endif
5043 break;
5047 static void
5048 reset_epan_mem(capture_file *cf,epan_dissect_t *edt, bool tree, bool visual)
5050 if (!epan_auto_reset || (cf->count < epan_auto_reset_count))
5051 return;
5053 fprintf(stderr, "resetting session.\n");
5055 epan_dissect_cleanup(edt);
5056 epan_free(cf->epan);
5058 cf->epan = tshark_epan_new(cf);
5059 epan_dissect_init(edt, cf->epan, tree, visual);
5060 cf->count = 0;