dcerpc-netlogon: remove unused variable
[wireshark-sm.git] / tshark.c
blobc6d38995740b736683d870fc18a3108960fcc422
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 "frame_tvbuff.h"
64 #include <epan/disabled_protos.h>
65 #include <epan/prefs.h>
66 #include <epan/column.h>
67 #include <epan/decode_as.h>
68 #include <epan/print.h>
69 #include <epan/addr_resolv.h>
70 #include <epan/enterprises.h>
71 #include <epan/manuf.h>
72 #include <epan/services.h>
73 #ifdef HAVE_LIBPCAP
74 #include "ui/capture_ui_utils.h"
75 #endif
76 #include "ui/taps.h"
77 #include "ui/util.h"
78 #include "ui/ws_ui_util.h"
79 #include "ui/decode_as_utils.h"
80 #include "wsutil/filter_files.h"
81 #include "ui/cli/tshark-tap.h"
82 #include "ui/cli/tap-exportobject.h"
83 #include "ui/tap_export_pdu.h"
84 #include "ui/dissect_opts.h"
85 #include "ui/ssl_key_export.h"
86 #include "ui/failure_message.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_opts.h"
103 #include "capture/capture-pcap-util.h"
105 #ifdef HAVE_LIBPCAP
106 #include "capture/capture_ifinfo.h"
107 #ifdef _WIN32
108 #include "capture/capture-wpcap.h"
109 #endif /* _WIN32 */
110 #include <capture/capture_session.h>
111 #include <capture/capture_sync.h>
112 #include <ui/capture_info.h>
113 #endif /* HAVE_LIBPCAP */
114 #include <epan/funnel.h>
116 #include <wsutil/str_util.h>
117 #include <wsutil/utf8_entities.h>
118 #include <wsutil/json_dumper.h>
119 #include <wsutil/wslog.h>
120 #ifdef _WIN32
121 #include <wsutil/win32-utils.h>
122 #endif
124 #include "extcap.h"
126 #ifdef HAVE_PLUGINS
127 #include <wsutil/codecs.h>
128 #include <wsutil/plugins.h>
129 #endif
131 /* Additional exit codes */
132 #define INVALID_EXPORT 2
133 #define INVALID_TAP 2
134 #define INVALID_CAPTURE 2
136 #define LONGOPT_EXPORT_OBJECTS LONGOPT_BASE_APPLICATION+1
137 #define LONGOPT_COLOR LONGOPT_BASE_APPLICATION+2
138 #define LONGOPT_NO_DUPLICATE_KEYS LONGOPT_BASE_APPLICATION+3
139 #define LONGOPT_ELASTIC_MAPPING_FILTER LONGOPT_BASE_APPLICATION+4
140 #define LONGOPT_EXPORT_TLS_SESSION_KEYS LONGOPT_BASE_APPLICATION+5
141 #define LONGOPT_CAPTURE_COMMENT LONGOPT_BASE_APPLICATION+6
142 #define LONGOPT_HEXDUMP LONGOPT_BASE_APPLICATION+7
143 #define LONGOPT_SELECTED_FRAME LONGOPT_BASE_APPLICATION+8
144 #define LONGOPT_PRINT_TIMERS LONGOPT_BASE_APPLICATION+9
145 #define LONGOPT_GLOBAL_PROFILE LONGOPT_BASE_APPLICATION+10
146 #define LONGOPT_COMPRESS LONGOPT_BASE_APPLICATION+11
148 capture_file cfile;
150 static uint32_t cum_bytes;
151 static frame_data ref_frame;
152 static frame_data prev_dis_frame;
153 static frame_data prev_cap_frame;
155 static bool perform_two_pass_analysis;
156 static uint32_t epan_auto_reset_count;
157 static bool epan_auto_reset;
159 static uint32_t selected_frame_number;
162 * The way the packet decode is to be written.
164 typedef enum {
165 WRITE_NONE, /* dummy initial state */
166 WRITE_TEXT, /* summary or detail text */
167 WRITE_XML, /* PDML or PSML */
168 WRITE_FIELDS, /* User defined list of fields */
169 WRITE_JSON, /* JSON */
170 WRITE_JSON_RAW, /* JSON only raw hex */
171 WRITE_EK /* JSON bulk insert to Elasticsearch */
172 /* Add CSV and the like here */
173 } output_action_e;
175 static output_action_e output_action;
176 static bool do_dissection; /* true if we have to dissect each packet */
177 static bool print_packet_info; /* true if we're to print packet information */
178 static bool print_summary; /* true if we're to print packet summary information */
179 static bool print_details; /* true if we're to print packet details information */
180 static bool print_hex; /* true if we're to print hex/ascii information */
181 static bool line_buffered;
182 static bool quiet;
183 static bool really_quiet;
184 static char* delimiter_char = " ";
185 static bool dissect_color;
186 static unsigned hexdump_source_option = HEXDUMP_SOURCE_MULTI; /* Default - Enable legacy multi-source mode */
187 static unsigned hexdump_ascii_option = HEXDUMP_ASCII_INCLUDE; /* Default - Enable legacy undelimited ASCII dump */
189 static print_format_e print_format = PR_FMT_TEXT;
190 static print_stream_t *print_stream;
192 static char *output_file_name;
194 static output_fields_t* output_fields;
196 static bool no_duplicate_keys;
197 static proto_node_children_grouper_func node_children_grouper = proto_node_group_children_by_unique;
199 static json_dumper jdumper;
201 /* The line separator used between packets, changeable via the -S option */
202 static const char *separator = "";
204 /* Per-file comments to be added to the output file. */
205 static GPtrArray *capture_comments;
207 static bool prefs_loaded;
209 #ifdef HAVE_LIBPCAP
211 * true if we're to print packet counts to keep track of captured packets.
213 static bool print_packet_counts;
215 static capture_options global_capture_opts;
216 static capture_session global_capture_session;
217 static info_data_t global_info_data;
219 #ifdef SIGINFO
220 static bool infodelay; /* if true, don't print capture info in SIGINFO handler */
221 static bool infoprint; /* if true, print capture info after clearing infodelay */
222 #endif /* SIGINFO */
224 static bool capture(void);
225 static bool capture_input_new_file(capture_session *cap_session,
226 char *new_file);
227 static void capture_input_new_packets(capture_session *cap_session,
228 int to_read);
229 static void capture_input_drops(capture_session *cap_session, uint32_t dropped,
230 const char* interface_name);
231 static void capture_input_error(capture_session *cap_session,
232 char *error_msg, char *secondary_error_msg);
233 static void capture_input_cfilter_error(capture_session *cap_session,
234 unsigned i, const char *error_message);
235 static void capture_input_closed(capture_session *cap_session, char *msg);
237 static void report_counts(void);
238 #ifdef _WIN32
239 static BOOL WINAPI capture_cleanup(DWORD);
240 #else /* _WIN32 */
241 static void capture_cleanup(int);
242 #ifdef SIGINFO
243 static void report_counts_siginfo(int);
244 #endif /* SIGINFO */
245 #endif /* _WIN32 */
246 #endif /* HAVE_LIBPCAP */
248 static void reset_epan_mem(capture_file *cf, epan_dissect_t *edt, bool tree, bool visual);
250 typedef enum {
251 PROCESS_FILE_SUCCEEDED,
252 PROCESS_FILE_NO_FILE_PROCESSED,
253 PROCESS_FILE_ERROR,
254 PROCESS_FILE_INTERRUPTED
255 } process_file_status_t;
256 static process_file_status_t process_cap_file(capture_file *, char *, int, bool, int, int64_t, int, wtap_compression_type);
258 static bool process_packet_single_pass(capture_file *cf,
259 epan_dissect_t *edt, int64_t offset, wtap_rec *rec, Buffer *buf,
260 unsigned tap_flags);
261 static void show_print_file_io_error(void);
262 static bool write_preamble(capture_file *cf);
263 static bool print_packet(capture_file *cf, epan_dissect_t *edt);
264 static bool write_finale(void);
266 static void tshark_cmdarg_err(const char *msg_format, va_list ap);
267 static void tshark_cmdarg_err_cont(const char *msg_format, va_list ap);
269 static GHashTable *output_only_tables;
271 static bool opt_print_timers;
272 struct elapsed_pass_s {
273 int64_t dissect;
274 int64_t dfilter_read;
275 int64_t dfilter_filter;
277 static struct {
278 int64_t dfilter_expand;
279 int64_t dfilter_compile;
280 struct elapsed_pass_s first_pass;
281 int64_t elapsed_first_pass;
282 struct elapsed_pass_s second_pass;
283 int64_t elapsed_second_pass;
285 tshark_elapsed;
287 static void
288 print_elapsed_json(const char *cf_name, const char *dfilter)
290 json_dumper dumper = {
291 .output_file = stderr,
292 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT,
295 if (tshark_elapsed.elapsed_first_pass == 0) {
296 // Should not happen
297 ws_warning("Print timers requested but no timing info provided");
298 return;
301 #define DUMP(name, val) \
302 json_dumper_set_member_name(&dumper, name); \
303 json_dumper_value_anyf(&dumper, "%"PRId64, val)
305 json_dumper_begin_object(&dumper);
306 json_dumper_set_member_name(&dumper, "version");
307 json_dumper_value_string(&dumper, get_ws_vcs_version_info_short());
308 if (cf_name) {
309 json_dumper_set_member_name(&dumper, "path");
310 json_dumper_value_string(&dumper, cf_name);
312 if (dfilter) {
313 json_dumper_set_member_name(&dumper, "filter");
314 json_dumper_value_string(&dumper, dfilter);
316 json_dumper_set_member_name(&dumper, "time_unit");
317 json_dumper_value_string(&dumper, "microseconds");
318 DUMP("elapsed", tshark_elapsed.elapsed_first_pass +
319 tshark_elapsed.elapsed_second_pass);
320 DUMP("dfilter_expand", tshark_elapsed.dfilter_expand);
321 DUMP("dfilter_compile", tshark_elapsed.dfilter_compile);
322 json_dumper_begin_array(&dumper);
323 json_dumper_begin_object(&dumper);
324 DUMP("elapsed", tshark_elapsed.elapsed_first_pass);
325 DUMP("dissect", tshark_elapsed.first_pass.dissect);
326 DUMP("display_filter", tshark_elapsed.first_pass.dfilter_filter);
327 DUMP("read_filter", tshark_elapsed.first_pass.dfilter_read);
328 json_dumper_end_object(&dumper);
329 if (tshark_elapsed.elapsed_second_pass) {
330 json_dumper_begin_object(&dumper);
331 DUMP("elapsed", tshark_elapsed.elapsed_second_pass);
332 DUMP("dissect", tshark_elapsed.second_pass.dissect);
333 DUMP("display_filter", tshark_elapsed.second_pass.dfilter_filter);
334 DUMP("read_filter", tshark_elapsed.second_pass.dfilter_read);
335 json_dumper_end_object(&dumper);
337 json_dumper_end_array(&dumper);
338 json_dumper_end_object(&dumper);
339 json_dumper_finish(&dumper);
342 static void
343 list_capture_types(void)
345 GArray *writable_type_subtypes;
347 fprintf(stderr, "tshark: The available capture file types for the \"-F\" flag are:\n");
348 writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME);
349 for (unsigned i = 0; i < writable_type_subtypes->len; i++) {
350 int ft = g_array_index(writable_type_subtypes, int, i);
351 fprintf(stderr, " %s - %s\n", wtap_file_type_subtype_name(ft),
352 wtap_file_type_subtype_description(ft));
354 g_array_free(writable_type_subtypes, TRUE);
357 static void
358 list_output_compression_types(void) {
359 GSList *output_compression_types;
361 fprintf(stderr, "tshark: The available output compression type(s) for the \"--compress\" flag are:\n");
362 output_compression_types = wtap_get_all_output_compression_type_names_list();
363 for (GSList *compression_type = output_compression_types;
364 compression_type != NULL;
365 compression_type = g_slist_next(compression_type)) {
366 fprintf(stderr, " %s\n", (const char *)compression_type->data);
369 g_slist_free(output_compression_types);
372 struct string_elem {
373 const char *sstr; /* The short string */
374 const char *lstr; /* The long string */
377 static int
378 string_compare(const void *a, const void *b)
380 return strcmp(((const struct string_elem *)a)->sstr,
381 ((const struct string_elem *)b)->sstr);
384 static void
385 string_elem_print(void *data)
387 fprintf(stderr, " %s - %s\n",
388 ((struct string_elem *)data)->sstr,
389 ((struct string_elem *)data)->lstr);
392 static void
393 list_read_capture_types(void)
395 unsigned i;
396 size_t num_file_types;
397 struct string_elem *captypes;
398 GSList *list = NULL;
399 const char *magic = "Magic-value-based";
400 const char *heuristic = "Heuristics-based";
402 /* How many readable file types are there? */
403 num_file_types = 0;
404 for (i = 0; open_routines[i].name != NULL; i++)
405 num_file_types++;
406 captypes = g_new(struct string_elem, num_file_types);
408 fprintf(stderr, "tshark: The available read file types for the \"-X read_format:\" option are:\n");
409 for (i = 0; i < num_file_types && open_routines[i].name != NULL; i++) {
410 captypes[i].sstr = open_routines[i].name;
411 captypes[i].lstr = (open_routines[i].type == OPEN_INFO_MAGIC) ? magic : heuristic;
412 list = g_slist_insert_sorted(list, &captypes[i], string_compare);
414 g_slist_free_full(list, string_elem_print);
415 g_free(captypes);
418 static void
419 list_export_pdu_taps(void)
421 fprintf(stderr, "tshark: The available export tap names and the encapsulation types they produce for the \"-U tap_name\" option are:\n");
422 for (GSList *export_pdu_tap_name_list = get_export_pdu_tap_list();
423 export_pdu_tap_name_list != NULL;
424 export_pdu_tap_name_list = g_slist_next(export_pdu_tap_name_list)) {
425 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)));
429 static void
430 print_usage(FILE *output)
432 fprintf(output, "\n");
433 fprintf(output, "Usage: tshark [options] ...\n");
434 fprintf(output, "\n");
436 #ifdef HAVE_LIBPCAP
437 fprintf(output, "Capture interface:\n");
438 fprintf(output, " -i <interface>, --interface <interface>\n");
439 fprintf(output, " name or idx of interface (def: first non-loopback)\n");
440 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
441 fprintf(output, " -s <snaplen>, --snapshot-length <snaplen>\n");
442 #ifdef HAVE_PCAP_CREATE
443 fprintf(output, " packet snapshot length (def: appropriate maximum)\n");
444 #else
445 fprintf(output, " packet snapshot length (def: %u)\n", WTAP_MAX_PACKET_SIZE_STANDARD);
446 #endif
447 fprintf(output, " -p, --no-promiscuous-mode\n");
448 fprintf(output, " don't capture in promiscuous mode\n");
449 #ifdef HAVE_PCAP_CREATE
450 fprintf(output, " -I, --monitor-mode capture in monitor mode, if available\n");
451 #endif
452 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
453 fprintf(output, " -B <buffer size>, --buffer-size <buffer size>\n");
454 fprintf(output, " size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
455 #endif
456 fprintf(output, " -y <link type>, --linktype <link type>\n");
457 fprintf(output, " link layer type (def: first appropriate)\n");
458 fprintf(output, " --time-stamp-type <type> timestamp method for interface\n");
459 fprintf(output, " -D, --list-interfaces print list of interfaces and exit\n");
460 fprintf(output, " -L, --list-data-link-types\n");
461 fprintf(output, " print list of link-layer types of iface and exit\n");
462 fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n");
463 fprintf(output, " --update-interval interval between updates with new packets (def: %dms)\n", DEFAULT_UPDATE_INTERVAL);
464 fprintf(output, "\n");
465 fprintf(output, "Capture stop conditions:\n");
466 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
467 fprintf(output, " -a <autostop cond.> ..., --autostop <autostop cond.> ...\n");
468 fprintf(output, " duration:NUM - stop after NUM seconds\n");
469 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
470 fprintf(output, " files:NUM - stop after NUM files\n");
471 fprintf(output, " packets:NUM - stop after NUM packets\n");
472 /*fprintf(output, "\n");*/
473 fprintf(output, "Capture output:\n");
474 fprintf(output, " -b <ringbuffer opt.> ..., --ring-buffer <ringbuffer opt.>\n");
475 fprintf(output, " duration:NUM - switch to next file after NUM secs\n");
476 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
477 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
478 fprintf(output, " packets:NUM - switch to next file after NUM packets\n");
479 fprintf(output, " interval:NUM - switch to next file when the time is\n");
480 fprintf(output, " an exact multiple of NUM secs\n");
481 fprintf(output, " printname:FILE - print filename to FILE when written\n");
482 fprintf(output, " (can use 'stdout' or 'stderr')\n");
483 #endif /* HAVE_LIBPCAP */
484 #ifdef HAVE_PCAP_REMOTE
485 fprintf(output, "RPCAP options:\n");
486 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
487 #endif
488 /*fprintf(output, "\n");*/
489 fprintf(output, "Input file:\n");
490 fprintf(output, " -r <infile>, --read-file <infile>\n");
491 fprintf(output, " set the filename to read from (or '-' for stdin)\n");
493 fprintf(output, "\n");
494 fprintf(output, "Processing:\n");
495 fprintf(output, " -2 perform a two-pass analysis\n");
496 fprintf(output, " -M <packet count> perform session auto reset\n");
497 fprintf(output, " -R <read filter>, --read-filter <read filter>\n");
498 fprintf(output, " packet Read filter in Wireshark display filter syntax\n");
499 fprintf(output, " (requires -2)\n");
500 fprintf(output, " -Y <display filter>, --display-filter <display filter>\n");
501 fprintf(output, " packet displaY filter in Wireshark display filter\n");
502 fprintf(output, " syntax\n");
503 fprintf(output, " -n disable all name resolutions (def: \"mNd\" enabled, or\n");
504 fprintf(output, " as set in preferences)\n");
505 // 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
506 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mtndsNvg\"\n");
507 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
508 fprintf(output, " \"Decode As\", see the man page for details\n");
509 fprintf(output, " Example: tcp.port==8888,http\n");
510 fprintf(output, " -H <hosts file> read a list of entries from a hosts file, which will\n");
511 fprintf(output, " then be written to a capture file. (Implies -W n)\n");
512 fprintf(output, " --enable-protocol <proto_name>\n");
513 fprintf(output, " enable dissection of proto_name\n");
514 fprintf(output, " --disable-protocol <proto_name>\n");
515 fprintf(output, " disable dissection of proto_name\n");
516 fprintf(output, " --only-protocols <protocols>\n");
517 fprintf(output, " Only enable dissection of these protocols, comma\n");
518 fprintf(output, " separated. Disable everything else\n");
519 fprintf(output, " --disable-all-protocols\n");
520 fprintf(output, " Disable dissection of all protocols\n");
521 fprintf(output, " --enable-heuristic <short_name>\n");
522 fprintf(output, " enable dissection of heuristic protocol\n");
523 fprintf(output, " --disable-heuristic <short_name>\n");
524 fprintf(output, " disable dissection of heuristic protocol\n");
526 /*fprintf(output, "\n");*/
527 fprintf(output, "Output:\n");
528 fprintf(output, " -w <outfile|-> write packets to a pcapng-format file named \"outfile\"\n");
529 fprintf(output, " (or '-' for stdout). If the output filename has the\n");
530 fprintf(output, " .gz extension, it will be compressed to a gzip archive\n");
531 fprintf(output, " --capture-comment <comment>\n");
532 fprintf(output, " add a capture file comment, if supported\n");
533 fprintf(output, " -C <config profile> start with specified configuration profile\n");
534 fprintf(output, " --global-profile use the global profile instead of personal profile\n");
535 fprintf(output, " -F <output file type> set the output file type; default is pcapng.\n");
536 fprintf(output, " an empty \"-F\" option will list the file types\n");
537 fprintf(output, " -V add output of packet tree (Packet Details)\n");
538 fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
539 fprintf(output, " separated\n");
540 fprintf(output, " -P, --print print packet summary even when writing to a file\n");
541 fprintf(output, " -S <separator> the line separator to print between packets\n");
542 fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
543 fprintf(output, " --hexdump <hexoption> add hexdump, set options for data source and ASCII dump\n");
544 fprintf(output, " all dump all data sources (-x default)\n");
545 fprintf(output, " frames dump only frame data source\n");
546 fprintf(output, " ascii include ASCII dump text (-x default)\n");
547 fprintf(output, " delimit delimit ASCII dump text with '|' characters\n");
548 fprintf(output, " noascii exclude ASCII dump text\n");
549 fprintf(output, " help display help for --hexdump and exit\n");
550 fprintf(output, " -T pdml|ps|psml|json|jsonraw|ek|tabs|text|fields|?\n");
551 fprintf(output, " format of text output (def: text)\n");
552 fprintf(output, " -j <protocolfilter> protocols layers filter if -T ek|pdml|json selected\n");
553 fprintf(output, " (e.g. \"ip ip.flags text\", filter does not expand child\n");
554 fprintf(output, " nodes, unless child is specified also in the filter)\n");
555 fprintf(output, " -J <protocolfilter> top level protocol filter if -T ek|pdml|json selected\n");
556 fprintf(output, " (e.g. \"http tcp\", filter which expands all child nodes)\n");
557 fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
558 fprintf(output, " _ws.col.info)\n");
559 fprintf(output, " this option can be repeated to print multiple fields\n");
560 fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
561 fprintf(output, " bom=y|n print a UTF-8 BOM\n");
562 fprintf(output, " header=y|n switch headers on and off\n");
563 fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
564 fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
565 fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
566 fprintf(output, " aggregator\n");
567 fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
568 fprintf(output, " -t (a|ad|adoy|d|dd|e|r|u|ud|udoy)[.[N]]|.[N]\n");
569 fprintf(output, " output format of time stamps (def: r: rel. to first)\n");
570 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
571 fprintf(output, " -l flush standard output after each packet\n");
572 fprintf(output, " (implies --update-interval 0)\n");
573 fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
574 fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
575 fprintf(output, " -g enable group read access on the output file(s)\n");
576 fprintf(output, " -W n Save extra information in the file, if supported.\n");
577 fprintf(output, " n = write network address resolution information\n");
578 fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
579 fprintf(output, " -U tap_name PDUs export mode, see the man page for details\n");
580 fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
581 fprintf(output, " --export-objects <protocol>,<destdir>\n");
582 fprintf(output, " save exported objects for a protocol to a directory\n");
583 fprintf(output, " named \"destdir\"\n");
584 fprintf(output, " --export-tls-session-keys <keyfile>\n");
585 fprintf(output, " export TLS Session Keys to a file named \"keyfile\"\n");
586 fprintf(output, " --color color output text similarly to the Wireshark GUI,\n");
587 fprintf(output, " requires a terminal with 24-bit color support\n");
588 fprintf(output, " Also supplies color attributes to pdml and psml formats\n");
589 fprintf(output, " (Note that attributes are nonstandard)\n");
590 fprintf(output, " --no-duplicate-keys If -T json is specified, merge duplicate keys in an object\n");
591 fprintf(output, " into a single key with as value a json array containing all\n");
592 fprintf(output, " values\n");
593 fprintf(output, " --elastic-mapping-filter <protocols> If -G elastic-mapping is specified, put only the\n");
594 fprintf(output, " specified protocols within the mapping file\n");
595 fprintf(output, " --temp-dir <directory> write temporary files to this directory\n");
596 fprintf(output, " (default: %s)\n", g_get_tmp_dir());
597 fprintf(output, " --compress <type> compress the output file using the type compression format\n");
598 fprintf(output, "\n");
600 ws_log_print_usage(output);
601 fprintf(output, "\n");
603 fprintf(output, "Miscellaneous:\n");
604 fprintf(output, " -h, --help display this help and exit\n");
605 fprintf(output, " -v, --version display version info and exit\n");
606 fprintf(output, " -o <name>:<value> ... override preference setting\n");
607 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
608 fprintf(output, " -G [report] dump one of several available reports and exit\n");
609 fprintf(output, " default report=\"fields\"\n");
610 fprintf(output, " use \"-G help\" for more help\n");
611 #ifdef __linux__
612 fprintf(output, "\n");
613 fprintf(output, "Dumpcap can benefit from an enabled BPF JIT compiler if available.\n");
614 fprintf(output, "You might want to enable it by executing:\n");
615 fprintf(output, " \"echo 1 > /proc/sys/net/core/bpf_jit_enable\"\n");
616 fprintf(output, "Note that this can make your system less secure!\n");
617 #endif
621 static void
622 glossary_option_help(void)
624 FILE *output;
626 output = stdout;
628 fprintf(output, "%s\n", get_appname_and_version());
630 fprintf(output, "\n");
631 fprintf(output, "Usage: tshark -G [report]\n");
632 fprintf(output, "\n");
633 fprintf(output, "Glossary table reports:\n");
634 fprintf(output, " -G column-formats dump column format codes and exit\n");
635 fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
636 fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
637 fprintf(output, " -G dissectors dump registered dissector names\n");
638 fprintf(output, " -G elastic-mapping dump ElasticSearch mapping file\n");
639 fprintf(output, " -G enterprises dump IANA Private Enterprise Number (PEN) table\n");
640 fprintf(output, " -G fieldcount dump count of header fields and exit\n");
641 fprintf(output, " -G fields,[prefix] dump fields glossary and exit\n");
642 fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
643 fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
644 fprintf(output, " -G manuf dump ethernet manufacturer tables\n");
645 fprintf(output, " -G plugins dump installed plugins and exit\n");
646 fprintf(output, " -G protocols dump protocols in registration database and exit\n");
647 fprintf(output, " -G services dump transport service (port) names\n");
648 fprintf(output, " -G values dump value, range, true/false strings and exit\n");
649 fprintf(output, "\n");
650 fprintf(output, "Preference reports:\n");
651 fprintf(output, " -G currentprefs dump current preferences and exit\n");
652 fprintf(output, " -G defaultprefs dump default preferences and exit\n");
653 fprintf(output, " -G folders dump about:folders\n");
654 fprintf(output, "\n");
657 static void
658 hexdump_option_help(FILE *output)
660 fprintf(output, "%s\n", get_appname_and_version());
661 fprintf(output, "\n");
662 fprintf(output, "tshark: Valid --hexdump <hexoption> values include:\n");
663 fprintf(output, "\n");
664 fprintf(output, "Data source options:\n");
665 fprintf(output, " all add hexdump, dump all data sources (-x default)\n");
666 fprintf(output, " frames add hexdump, dump only frame data source\n");
667 fprintf(output, "\n");
668 fprintf(output, "ASCII options:\n");
669 fprintf(output, " ascii add hexdump, include ASCII dump text (-x default)\n");
670 fprintf(output, " delimit add hexdump, delimit ASCII dump text with '|' characters\n");
671 fprintf(output, " noascii add hexdump, exclude ASCII dump text\n");
672 fprintf(output, "\n");
673 fprintf(output, "Miscellaneous:\n");
674 fprintf(output, " help display this help and exit\n");
675 fprintf(output, "\n");
676 fprintf(output, "Example:\n");
677 fprintf(output, "\n");
678 fprintf(output, " $ tshark ... --hexdump frames --hexdump delimit ...\n");
679 fprintf(output, "\n");
682 static void
683 print_current_user(void)
685 char *cur_user, *cur_group;
687 if (started_with_special_privs()) {
688 cur_user = get_cur_username();
689 cur_group = get_cur_groupname();
690 fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
691 cur_user, cur_group);
692 g_free(cur_user);
693 g_free(cur_group);
694 if (running_with_special_privs()) {
695 fprintf(stderr, " This could be dangerous.");
697 fprintf(stderr, "\n");
701 static void
702 gather_tshark_compile_info(feature_list l)
704 /* Capture libraries */
705 gather_caplibs_compile_info(l);
706 epan_gather_compile_info(l);
709 static void
710 gather_tshark_runtime_info(feature_list l)
712 #ifdef HAVE_LIBPCAP
713 gather_caplibs_runtime_info(l);
714 #endif
716 /* stuff used by libwireshark */
717 epan_gather_runtime_info(l);
720 static bool
721 _compile_dfilter(const char *text, dfilter_t **dfp, const char *caller)
723 bool ok;
724 df_error_t *df_err;
725 char *err_off;
726 char *expanded;
727 int64_t elapsed_start;
729 elapsed_start = g_get_monotonic_time();
730 expanded = dfilter_expand(text, &df_err);
731 if (expanded == NULL) {
732 cmdarg_err("%s", df_err->msg);
733 df_error_free(&df_err);
734 return false;
736 tshark_elapsed.dfilter_expand = g_get_monotonic_time() - elapsed_start;
738 elapsed_start = g_get_monotonic_time();
739 ok = dfilter_compile_full(expanded, dfp, &df_err, DF_OPTIMIZE, caller);
740 if (!ok ) {
741 cmdarg_err("%s", df_err->msg);
743 if (df_err->loc.col_start >= 0) {
744 err_off = ws_strdup_underline(NULL, df_err->loc.col_start, df_err->loc.col_len);
745 cmdarg_err_cont(" %s", expanded);
746 cmdarg_err_cont(" %s", err_off);
747 g_free(err_off);
749 df_error_free(&df_err);
751 tshark_elapsed.dfilter_compile = g_get_monotonic_time() - elapsed_start;
753 g_free(expanded);
754 return ok;
757 #define compile_dfilter(text, dfp) _compile_dfilter(text, dfp, __func__)
759 static bool
760 protocolfilter_add_opt(const char* arg, pf_flags filter_flags)
762 char **newfilter = NULL;
763 for (newfilter = wmem_strsplit(wmem_epan_scope(), arg, " ", -1); *newfilter; newfilter++) {
764 if (strcmp(*newfilter, "") == 0) {
765 /* Don't treat the empty string as an intended field abbreviation
766 * to output, consecutive spaces on the command line probably
767 * aren't intentional.
769 continue;
771 if (!output_fields_add_protocolfilter(output_fields, *newfilter, filter_flags)) {
772 cmdarg_err("%s was already specified with different filter flags. Overwriting previous protocol filter.", *newfilter);
775 return true;
778 static void
779 about_folders(void)
781 const char *constpath;
782 char *path;
783 int i;
784 char **resultArray;
786 /* "file open" */
789 * Fetching the "File" dialogs folder not implemented.
790 * This is arguably just a pwd for a ui/cli .
793 /* temp */
794 constpath = g_get_tmp_dir();
795 #ifdef HAVE_LIBPCAP
796 /* global_capture_opts only exists in this case */
797 if (global_capture_opts.temp_dir)
798 constpath = global_capture_opts.temp_dir;
799 #endif
800 printf("%-21s\t%s\n", "Temp:", constpath);
802 /* pers conf */
803 path = get_persconffile_path("", false);
804 printf("%-21s\t%s\n", "Personal configuration:", path);
805 g_free(path);
807 /* global conf */
808 constpath = get_datafile_dir();
809 if (constpath != NULL) {
810 printf("%-21s\t%s\n", "Global configuration:", constpath);
813 /* system */
814 constpath = get_systemfile_dir();
815 printf("%-21s\t%s\n", "System:", constpath);
817 /* program */
818 constpath = get_progfile_dir();
819 printf("%-21s\t%s\n", "Program:", constpath);
821 #ifdef HAVE_PLUGINS
822 /* pers plugins */
823 printf("%-21s\t%s\n", "Personal Plugins:", get_plugins_pers_dir_with_version());
825 /* global plugins */
826 printf("%-21s\t%s\n", "Global Plugins:", get_plugins_dir_with_version());
827 #endif
829 #ifdef HAVE_LUA
830 /* pers lua plugins */
831 printf("%-21s\t%s\n", "Personal Lua Plugins:", get_plugins_pers_dir());
833 /* global lua plugins */
834 printf("%-21s\t%s\n", "Global Lua Plugins:", get_plugins_dir());
835 #endif
837 /* Personal Extcap */
838 constpath = get_extcap_pers_dir();
840 resultArray = g_strsplit(constpath, G_SEARCHPATH_SEPARATOR_S, 10);
841 for(i = 0; resultArray[i]; i++)
842 printf("%-21s\t%s\n", "Personal Extcap path:", g_strstrip(resultArray[i]));
844 g_strfreev(resultArray);
846 /* Global Extcap */
847 constpath = get_extcap_dir();
849 resultArray = g_strsplit(constpath, G_SEARCHPATH_SEPARATOR_S, 10);
850 for(i = 0; resultArray[i]; i++)
851 printf("%-21s\t%s\n", "Global Extcap path:", g_strstrip(resultArray[i]));
853 g_strfreev(resultArray);
855 /* MaxMindDB */
856 path = maxmind_db_get_paths();
858 resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 10);
860 for(i = 0; resultArray[i]; i++)
861 printf("%-21s\t%s\n", "MaxMind database path:", g_strstrip(resultArray[i]));
863 g_strfreev(resultArray);
864 g_free(path);
866 #ifdef HAVE_LIBSMI
867 /* SMI MIBs/PIBs */
868 path = oid_get_default_mib_path();
870 resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 20);
872 for(i = 0; resultArray[i]; i++)
873 printf("%-21s\t%s\n", "MIB/PIB path:", g_strstrip(resultArray[i]));
875 g_strfreev(resultArray);
876 g_free(path);
877 #endif
881 static int
882 dump_glossary(const char* glossary, const char* elastic_mapping_filter)
884 int exit_status = EXIT_SUCCESS;
885 /* If invoked with the "-G" flag, we dump out information based on
886 the argument to the "-G" flag.
889 /* This is now called after the preferences are loaded and all
890 * the command line options are handled, including -o, -d,
891 * --[enable|disable]-[protocol|heuristic].
892 * Some UATs can register new fields (e.g. HTTP/2), so for most
893 * cases load everything.
895 * prefs_reset() is used for defaultprefs to get the default values.
896 * Note that makes it difficult to use defaultprefs in concert with
897 * any other glossary (we could do it last.)
899 proto_initialize_all_prefixes();
901 if (strcmp(glossary, "column-formats") == 0)
902 column_dump_column_formats();
903 else if (strcmp(glossary, "currentprefs") == 0) {
904 write_prefs(NULL);
906 else if (strcmp(glossary, "decodes") == 0) {
907 dissector_dump_decodes();
908 } else if (strcmp(glossary, "defaultprefs") == 0) {
909 prefs_reset();
910 write_prefs(NULL);
911 } else if (strcmp(glossary, "dissector-tables") == 0)
912 dissector_dump_dissector_tables();
913 else if (strcmp(glossary, "dissectors") == 0)
914 dissector_dump_dissectors();
915 else if (strcmp(glossary, "elastic-mapping") == 0)
916 proto_registrar_dump_elastic(elastic_mapping_filter);
917 else if (strncmp(glossary, "elastic-mapping,", strlen("elastic-mapping,")) == 0) {
918 elastic_mapping_filter = glossary + strlen("elastic-mapping,");
919 proto_registrar_dump_elastic(elastic_mapping_filter);
921 else if (strcmp(glossary, "fieldcount") == 0) {
922 /* return value for the test suite */
923 exit_status = proto_registrar_dump_fieldcount();
925 else if (strcmp(glossary, "fields") == 0) {
926 proto_registrar_dump_fields();
928 else if (strncmp(glossary, "fields,", strlen("fields,")) == 0) {
929 const char* prefix = glossary + strlen("fields,");
930 bool matched = proto_registrar_dump_field_completions(prefix);
931 if (!matched) {
932 cmdarg_err("No field or protocol begins with \"%s\"", prefix);
933 exit_status = EXIT_FAILURE;
936 else if (strcmp(glossary, "folders") == 0) {
937 about_folders();
938 } else if (strcmp(glossary, "ftypes") == 0)
939 proto_registrar_dump_ftypes();
940 else if (strcmp(glossary, "heuristic-decodes") == 0) {
941 dissector_dump_heur_decodes();
942 } else if (strcmp(glossary, "manuf") == 0)
943 ws_manuf_dump(stdout);
944 else if (strcmp(glossary, "enterprises") == 0)
945 global_enterprises_dump(stdout);
946 else if (strcmp(glossary, "services") == 0)
947 global_services_dump(stdout);
948 else if (strcmp(glossary, "plugins") == 0) {
949 #ifdef HAVE_PLUGINS
950 codecs_init();
951 plugins_dump_all();
952 #endif
953 #ifdef HAVE_LUA
954 wslua_plugins_dump_all();
955 #endif
956 extcap_dump_all();
958 else if (strcmp(glossary, "protocols") == 0) {
959 proto_registrar_dump_protocols();
960 } else if (strcmp(glossary, "values") == 0)
961 proto_registrar_dump_values();
962 else if (strcmp(glossary, "help") == 0)
963 glossary_option_help();
964 /* These are supported only for backwards compatibility and may or may not work
965 * for a given user in a given directory on a given operating system with a given
966 * command-line interpreter.
968 else if (strcmp(glossary, "?") == 0)
969 glossary_option_help();
970 else if (strcmp(glossary, "-?") == 0)
971 glossary_option_help();
972 else {
973 cmdarg_err("Invalid \"%s\" option for -G flag, enter -G help for more help.", glossary);
974 exit_status = WS_EXIT_INVALID_OPTION;
977 return exit_status;
980 static bool
981 must_do_dissection(dfilter_t *rfcode, dfilter_t *dfcode,
982 char *volatile pdu_export_arg)
984 /* We have to dissect each packet if:
986 we're printing information about each packet;
988 we're using a read filter on the packets;
990 we're using a display filter on the packets;
992 we're exporting PDUs;
994 we're using any taps that need dissection. */
995 return print_packet_info || rfcode || dfcode || pdu_export_arg ||
996 tap_listeners_require_dissection();
999 #ifdef HAVE_LIBPCAP
1001 * Check whether a purported *shark packet-matching expression (display
1002 * or read filter) looks like a capture filter and, if so, print a
1003 * warning.
1005 * Used, for example, if the string in question isn't a valid packet-
1006 * matching expression.
1008 static void
1009 warn_about_capture_filter(const char *rfilter)
1011 struct bpf_program fcode;
1012 pcap_t *pc;
1014 pc = pcap_open_dead(DLT_EN10MB, MIN_PACKET_SIZE);
1015 if (pc != NULL) {
1016 if (pcap_compile(pc, &fcode, rfilter, 0, 0) != -1) {
1017 pcap_freecode(&fcode);
1018 cmdarg_err_cont(
1019 " Note: That read filter code looks like a valid capture filter;\n"
1020 " maybe you mixed them up?");
1022 pcap_close(pc);
1025 #endif
1027 #ifdef HAVE_LIBPCAP
1028 static GList *cached_if_list;
1030 static GList *
1031 capture_opts_get_interface_list(int *err, char **err_str)
1033 if (cached_if_list == NULL) {
1035 * This isn't a GUI tool, so no need for a callback.
1037 cached_if_list = capture_interface_list(err, err_str, NULL);
1040 * Routines expect to free the returned interface list, so return
1041 * a deep copy.
1043 return interface_list_copy(cached_if_list);
1045 #endif
1048 main(int argc, char *argv[])
1050 char *err_msg;
1051 int opt;
1052 static const struct ws_option long_options[] = {
1053 {"help", ws_no_argument, NULL, 'h'},
1054 {"version", ws_no_argument, NULL, 'v'},
1055 LONGOPT_CAPTURE_COMMON
1056 LONGOPT_DISSECT_COMMON
1057 LONGOPT_READ_CAPTURE_COMMON
1058 {"print", ws_no_argument, NULL, 'P'},
1059 {"export-objects", ws_required_argument, NULL, LONGOPT_EXPORT_OBJECTS},
1060 {"export-tls-session-keys", ws_required_argument, NULL, LONGOPT_EXPORT_TLS_SESSION_KEYS},
1061 {"color", ws_no_argument, NULL, LONGOPT_COLOR},
1062 {"no-duplicate-keys", ws_no_argument, NULL, LONGOPT_NO_DUPLICATE_KEYS},
1063 {"elastic-mapping-filter", ws_required_argument, NULL, LONGOPT_ELASTIC_MAPPING_FILTER},
1064 {"capture-comment", ws_required_argument, NULL, LONGOPT_CAPTURE_COMMENT},
1065 {"hexdump", ws_required_argument, NULL, LONGOPT_HEXDUMP},
1066 {"selected-frame", ws_required_argument, NULL, LONGOPT_SELECTED_FRAME},
1067 {"print-timers", ws_no_argument, NULL, LONGOPT_PRINT_TIMERS},
1068 {"global-profile", ws_no_argument, NULL, LONGOPT_GLOBAL_PROFILE},
1069 {"compress", ws_required_argument, NULL, LONGOPT_COMPRESS},
1070 {0, 0, 0, 0}
1072 bool arg_error = false;
1073 bool has_extcap_options = false;
1074 volatile bool is_capturing = true;
1076 int err;
1077 char *err_info;
1078 bool exp_pdu_status;
1079 volatile process_file_status_t status;
1080 volatile bool draw_taps = false;
1081 volatile int exit_status = EXIT_SUCCESS;
1082 #ifdef HAVE_LIBPCAP
1083 int caps_queries = 0;
1084 GList *if_list;
1085 char *err_str, *err_str_secondary;
1086 #else
1087 bool capture_option_specified = false;
1088 volatile int max_packet_count = 0;
1089 #endif
1090 volatile int out_file_type = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
1091 volatile bool out_file_name_res = false;
1092 volatile int in_file_type = WTAP_TYPE_AUTO;
1093 char *volatile cf_name = NULL;
1094 char *rfilter = NULL;
1095 char *volatile dfilter = NULL;
1096 dfilter_t *rfcode = NULL;
1097 dfilter_t *dfcode = NULL;
1098 e_prefs *prefs_p;
1099 char *output_only = NULL;
1100 char *volatile pdu_export_arg = NULL;
1101 char *volatile exp_pdu_filename = NULL;
1102 const char *volatile tls_session_keys_file = NULL;
1103 exp_pdu_t exp_pdu_tap_data;
1104 const char* glossary = NULL;
1105 const char* elastic_mapping_filter = NULL;
1106 wtap_compression_type volatile compression_type = WTAP_UNKNOWN_COMPRESSION;
1109 * The leading + ensures that getopt_long() does not permute the argv[]
1110 * entries.
1112 * We have to make sure that the first getopt_long() preserves the content
1113 * of argv[] for the subsequent getopt_long() call.
1115 * We use getopt_long() in both cases to ensure that we're using a routine
1116 * whose permutation behavior we can control in the same fashion on all
1117 * platforms, and so that, if we ever need to process a long argument before
1118 * doing further initialization, we can do so.
1120 * Glibc and Solaris libc document that a leading + disables permutation
1121 * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
1122 * and macOS don't document it, but do so anyway.
1124 * We do *not* use a leading - because the behavior of a leading - is
1125 * platform-dependent.
1127 #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:"
1129 static const char optstring[] = OPTSTRING;
1132 * Set the C-language locale to the native environment and set the
1133 * code page to UTF-8 on Windows.
1135 #ifdef _WIN32
1136 setlocale(LC_ALL, ".UTF-8");
1137 #else
1138 setlocale(LC_ALL, "");
1139 #endif
1141 ws_tzset();
1143 cmdarg_err_init(tshark_cmdarg_err, tshark_cmdarg_err_cont);
1145 /* Initialize log handler early so we can have proper logging during startup. */
1146 ws_log_init("tshark", vcmdarg_err);
1148 /* Early logging command-line initialization. */
1149 ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION);
1151 ws_noisy("Finished log init and parsing command line log arguments");
1152 ws_debug("tshark started with %d args", argc);
1154 #ifdef _WIN32
1155 create_app_running_mutex();
1156 #endif /* _WIN32 */
1159 * Get credential information for later use, and drop privileges
1160 * before doing anything else.
1161 * Let the user know if anything happened.
1163 init_process_policies();
1164 relinquish_special_privs_perm();
1165 print_current_user();
1168 * Attempt to get the pathname of the directory containing the
1169 * executable file.
1171 err_msg = configuration_init(argv[0], NULL);
1172 if (err_msg != NULL) {
1173 fprintf(stderr,
1174 "tshark: Can't get pathname of directory containing the tshark program: %s.\n"
1175 "It won't be possible to capture traffic.\n"
1176 "Report this to the Wireshark developers.",
1177 err_msg);
1178 g_free(err_msg);
1181 initialize_funnel_ops();
1183 #ifdef _WIN32
1184 ws_init_dll_search_path();
1185 #ifdef HAVE_LIBPCAP
1186 /* Load wpcap if possible. Do this before collecting the run-time version information */
1187 load_wpcap();
1188 #endif /* HAVE_LIBPCAP */
1189 #endif /* _WIN32 */
1191 /* Initialize the version information. */
1192 ws_init_version_info("TShark",
1193 gather_tshark_compile_info, gather_tshark_runtime_info);
1195 /* Fail sometimes. Useful for testing fuzz scripts. */
1196 /* if (g_random_int_range(0, 100) < 5) abort(); */
1199 * In order to have the -X opts assigned before the wslua machine starts
1200 * we need to call getopt_long before epan_init() gets called.
1202 * In order to handle, for example, -o options, we also need to call it
1203 * *after* epan_init() gets called, so that the dissectors have had a
1204 * chance to register their preferences.
1206 * Spawning a bunch of extcap processes can delay program startup,
1207 * particularly on Windows. Check to see if we have any options that
1208 * might require extcap and set has_extcap_options = true if that's
1209 * the case.
1211 * XXX - can we do this all with one getopt_long() call, saving the
1212 * arguments we can't handle until after initializing libwireshark,
1213 * and then process them after initializing libwireshark?
1215 * We set ws_opterr to 0 so that ws_getopt_long doesn't print error
1216 * messages for bad long options. We'll do that once, in the final
1217 * call where all the error handling happens.
1219 ws_opterr = 0;
1221 /* We should check at first if we should use a global profile before
1222 parsing the profile name
1223 XXX - We could check this in the next ws_getopt_long, and save the
1224 profile name and only apply it after finishing the loop. */
1225 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
1226 switch (opt) {
1227 case LONGOPT_GLOBAL_PROFILE:
1228 set_persconffile_dir(get_datafile_dir());
1229 break;
1230 default:
1231 break;
1236 * Reset the options parser, set ws_optreset to 1 and set ws_optind to 1.
1237 * We still don't want to print error messages, though.
1239 ws_optreset = 1;
1240 ws_optind = 1;
1242 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
1243 switch (opt) {
1244 case 'C': /* Configuration Profile */
1245 if (profile_exists (ws_optarg, false)) {
1246 set_profile_name (ws_optarg);
1247 } else if (profile_exists (ws_optarg, true)) {
1248 char *pf_dir_path, *pf_dir_path2, *pf_filename;
1249 /* Copy from global profile */
1250 if (create_persconffile_profile(ws_optarg, &pf_dir_path) == -1) {
1251 cmdarg_err("Can't create directory\n\"%s\":\n%s.",
1252 pf_dir_path, g_strerror(errno));
1254 g_free(pf_dir_path);
1255 exit_status = WS_EXIT_INVALID_FILE;
1256 goto clean_exit;
1258 if (copy_persconffile_profile(ws_optarg, ws_optarg, true, &pf_filename,
1259 &pf_dir_path, &pf_dir_path2) == -1) {
1260 cmdarg_err("Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
1261 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
1263 g_free(pf_filename);
1264 g_free(pf_dir_path);
1265 g_free(pf_dir_path2);
1266 exit_status = WS_EXIT_INVALID_FILE;
1267 goto clean_exit;
1269 set_profile_name (ws_optarg);
1270 } else {
1271 cmdarg_err("Configuration Profile \"%s\" does not exist", ws_optarg);
1272 exit_status = WS_EXIT_INVALID_OPTION;
1273 goto clean_exit;
1275 break;
1276 case 'G':
1277 if (glossary != NULL) {
1278 /* Multiple glossaries are difficult especially due to defaultprefs */
1279 cmdarg_err("Multiple glossary reports (-G) are unsupported");
1280 exit_status = WS_EXIT_INVALID_OPTION;
1281 goto clean_exit;
1282 } else {
1283 glossary = ws_optarg;
1285 if (g_str_has_suffix(ws_optarg, "prefs")) {
1286 has_extcap_options = true;
1288 is_capturing = false;
1289 break;
1290 case 'i':
1291 has_extcap_options = true;
1292 break;
1293 case 'o':
1294 if (g_str_has_prefix(ws_optarg, "extcap.")) {
1295 has_extcap_options = true;
1297 break;
1298 case 'P': /* Print packet summary info even when writing to a file */
1299 print_packet_info = true;
1300 print_summary = true;
1301 break;
1302 case 'r': /* Read capture file x */
1303 cf_name = g_strdup(ws_optarg);
1304 is_capturing = false;
1305 break;
1306 case 'O': /* Only output these protocols */
1307 output_only = g_strdup(ws_optarg);
1308 /* FALLTHROUGH */
1309 case 'V': /* Verbose */
1310 print_details = true;
1311 print_packet_info = true;
1312 break;
1313 case 'x': /* Print packet data in hex (and ASCII) */
1314 print_hex = true;
1315 /* The user asked for hex output, so let's ensure they get it,
1316 * even if they're writing to a file.
1318 print_packet_info = true;
1319 break;
1320 case 'X':
1321 ex_opt_add(ws_optarg);
1322 break;
1323 case 'h':
1324 case 'v':
1325 is_capturing = false;
1326 break;
1327 default:
1328 break;
1332 #ifndef HAVE_LUA
1333 if (ex_opt_count("lua_script") > 0) {
1334 cmdarg_err("This version of TShark was not built with support for Lua scripting.");
1335 exit_status = WS_EXIT_INIT_FAILED;
1336 goto clean_exit;
1338 #endif /* HAVE_LUA */
1340 init_report_failure_message("TShark");
1342 #ifdef HAVE_LIBPCAP
1343 capture_opts_init(&global_capture_opts, capture_opts_get_interface_list);
1344 capture_session_init(&global_capture_session, &cfile,
1345 capture_input_new_file, capture_input_new_packets,
1346 capture_input_drops, capture_input_error,
1347 capture_input_cfilter_error, capture_input_closed);
1348 #endif
1350 timestamp_set_type(TS_RELATIVE);
1351 timestamp_set_precision(TS_PREC_AUTO);
1352 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
1355 * Libwiretap must be initialized before libwireshark is, so that
1356 * dissection-time handlers for file-type-dependent blocks can
1357 * register using the file type/subtype value for the file type.
1359 wtap_init(true);
1361 /* Register all dissectors; we must do this before checking for the
1362 "-G" flag, as the "-G" flag dumps information registered by the
1363 dissectors, and we must do it before we read the preferences, in
1364 case any dissectors register preferences. */
1365 if (!epan_init(NULL, NULL, true)) {
1366 exit_status = WS_EXIT_INIT_FAILED;
1367 goto clean_exit;
1370 /* Register all tap listeners; we do this before we parse the arguments,
1371 as the "-z" argument can specify a registered tap. */
1373 register_all_tap_listeners(tap_reg_listener);
1375 /* Register extcap preferences only when needed. */
1376 if (has_extcap_options || is_capturing) {
1378 * XXX - We don't properly handle the capture_no_extcap preference.
1379 * To make it work, before registering the extcap preferences we'd
1380 * have to read at least that preference for the chosen profile, and
1381 * also check to make sure an "-o" option didn't override it.
1382 * Then, after registering the extcap preferences, we'd have to
1383 * set the extcap preferences from the preferences file and "-o"
1384 * options on the command line.
1386 extcap_register_preferences();
1389 conversation_table_set_gui_info(init_iousers);
1390 endpoint_table_set_gui_info(init_endpoints);
1391 srt_table_iterate_tables(register_srt_tables, NULL);
1392 rtd_table_iterate_tables(register_rtd_tables, NULL);
1393 stat_tap_iterate_tables(register_simple_stat_tables, NULL);
1395 ws_debug("tshark reading settings");
1397 /* Load libwireshark settings from the current profile. */
1398 prefs_p = epan_load_settings();
1399 prefs_loaded = true;
1401 cap_file_init(&cfile);
1403 /* Print format defaults to this. */
1404 print_format = PR_FMT_TEXT;
1405 delimiter_char = " ";
1407 output_fields = output_fields_new();
1410 * To reset the options parser, set ws_optreset to 1 and set ws_optind to 1.
1412 * Also reset ws_opterr to 1, so that error messages are printed by
1413 * getopt_long().
1415 ws_optreset = 1;
1416 ws_optind = 1;
1417 ws_opterr = 1;
1419 /* Now get our args */
1420 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
1421 switch (opt) {
1422 case '2': /* Perform two-pass analysis */
1423 if(epan_auto_reset){
1424 cmdarg_err("-2 does not support auto session reset.");
1425 arg_error=true;
1427 perform_two_pass_analysis = true;
1428 break;
1429 case 'M':
1430 if(perform_two_pass_analysis){
1431 cmdarg_err("-M does not support two-pass analysis.");
1432 arg_error=true;
1434 epan_auto_reset_count = get_positive_int(ws_optarg, "epan reset count");
1435 epan_auto_reset = true;
1436 break;
1437 case 'a': /* autostop criteria */
1438 case 'b': /* Ringbuffer option */
1439 case 'f': /* capture filter */
1440 case 'g': /* enable group read access on file(s) */
1441 case 'i': /* Use interface x */
1442 case LONGOPT_SET_TSTAMP_TYPE: /* Set capture timestamp type */
1443 case 'p': /* Don't capture in promiscuous mode */
1444 #ifdef HAVE_PCAP_REMOTE
1445 case 'A': /* Authentication */
1446 #endif
1447 #ifdef HAVE_PCAP_CREATE
1448 case 'I': /* Capture in monitor mode, if available */
1449 #endif
1450 case 's': /* Set the snapshot (capture) length */
1451 case 'y': /* Set the pcap data link type */
1452 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
1453 case 'B': /* Buffer size */
1454 #endif
1455 case LONGOPT_COMPRESS_TYPE: /* compress type */
1456 case LONGOPT_CAPTURE_TMPDIR: /* capture temp directory */
1457 case LONGOPT_UPDATE_INTERVAL: /* sync pipe update interval */
1458 /* These are options only for packet capture. */
1459 #ifdef HAVE_LIBPCAP
1460 exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
1461 if (exit_status != 0) {
1462 goto clean_exit;
1464 #else
1465 capture_option_specified = true;
1466 arg_error = true;
1467 #endif
1468 break;
1469 case 'c': /* Stop after x packets */
1470 #ifdef HAVE_LIBPCAP
1471 exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
1472 if (exit_status != 0) {
1473 goto clean_exit;
1475 #else
1476 max_packet_count = get_positive_int(ws_optarg, "packet count");
1477 #endif
1478 break;
1479 case 'w': /* Write to file x */
1480 output_file_name = g_strdup(ws_optarg);
1481 #ifdef HAVE_LIBPCAP
1482 exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
1483 if (exit_status != 0) {
1484 goto clean_exit;
1486 #endif
1487 break;
1488 case 'C':
1489 /* already processed; just ignore it now */
1490 break;
1491 case 'D': /* Print a list of capture devices and exit */
1492 #ifdef HAVE_LIBPCAP
1493 exit_status = EXIT_SUCCESS;
1494 if_list = capture_interface_list(&err, &err_str,NULL);
1495 if (err != 0) {
1497 * An error occurred when fetching the local
1498 * interfaces. Report it.
1500 cmdarg_err("%s", err_str);
1501 g_free(err_str);
1502 exit_status = WS_EXIT_PCAP_ERROR;
1504 if (if_list == NULL) {
1506 * No interfaces were found. If that's not the
1507 * result of an error when fetching the local
1508 * interfaces, let the user know.
1510 if (err == 0) {
1511 cmdarg_err("There are no interfaces on which a capture can be done");
1512 exit_status = WS_EXIT_NO_INTERFACES;
1514 goto clean_exit;
1516 capture_opts_print_interfaces(if_list);
1517 free_interface_list(if_list);
1518 goto clean_exit;
1519 #else
1520 capture_option_specified = true;
1521 arg_error = true;
1522 #endif
1523 break;
1524 case 'e':
1525 /* Field entry */
1527 const char* col_field = try_convert_to_column_field(ws_optarg);
1528 if (col_field) {
1529 output_fields_add(output_fields, col_field);
1530 } else {
1531 header_field_info *hfi = proto_registrar_get_byalias(ws_optarg);
1532 if (hfi)
1533 output_fields_add(output_fields, hfi->abbrev);
1534 else
1535 output_fields_add(output_fields, ws_optarg);
1538 break;
1539 case 'E':
1540 /* Field option */
1541 if (!output_fields_set_option(output_fields, ws_optarg)) {
1542 cmdarg_err("\"%s\" is not a valid field output option=value pair.", ws_optarg);
1543 output_fields_list_options(stderr);
1544 exit_status = WS_EXIT_INVALID_OPTION;
1545 goto clean_exit;
1547 break;
1548 case 'F':
1549 out_file_type = wtap_name_to_file_type_subtype(ws_optarg);
1550 if (out_file_type < 0) {
1551 cmdarg_err("\"%s\" isn't a valid capture file type", ws_optarg);
1552 list_capture_types();
1553 exit_status = WS_EXIT_INVALID_OPTION;
1554 goto clean_exit;
1556 break;
1557 case 'G':
1558 /* already processed; just ignore it now */
1559 break;
1560 case 'j':
1561 if (!protocolfilter_add_opt(ws_optarg, PF_NONE)) {
1562 exit_status = WS_EXIT_INVALID_OPTION;
1563 goto clean_exit;
1565 break;
1566 case 'J':
1567 if (!protocolfilter_add_opt(ws_optarg, PF_INCLUDE_CHILDREN)) {
1568 exit_status = WS_EXIT_INVALID_OPTION;
1569 goto clean_exit;
1571 break;
1572 case 'W': /* Select extra information to save in our capture file */
1573 /* This is patterned after the -N flag which may not be the best idea. */
1574 if (strchr(ws_optarg, 'n')) {
1575 out_file_name_res = true;
1576 } else {
1577 cmdarg_err("Invalid -W argument \"%s\"; it must be one of:", ws_optarg);
1578 cmdarg_err_cont("\t'n' write network address resolution information (pcapng only)");
1579 exit_status = WS_EXIT_INVALID_OPTION;
1580 goto clean_exit;
1582 break;
1583 case 'H': /* Read address to name mappings from a hosts file */
1584 if (! add_hosts_file(ws_optarg))
1586 cmdarg_err("Can't read host entries from \"%s\"", ws_optarg);
1587 exit_status = WS_EXIT_INVALID_OPTION;
1588 goto clean_exit;
1590 out_file_name_res = true;
1591 break;
1593 case 'h': /* Print help and exit */
1594 show_help_header("Dump and analyze network traffic.");
1595 print_usage(stdout);
1596 exit_status = EXIT_SUCCESS;
1597 goto clean_exit;
1598 break;
1599 case 'l': /* "Line-buffer" standard output */
1600 /* The ANSI C standard does not appear to *require* that a line-buffered
1601 stream be flushed to the host environment whenever a newline is
1602 written, it just says that, on such a stream, characters "are
1603 intended to be transmitted to or from the host environment as a
1604 block when a new-line character is encountered".
1606 The Visual C++ 6.0 C implementation doesn't do what is intended;
1607 even if you set a stream to be line-buffered, it still doesn't
1608 flush the buffer at the end of every line.
1610 The whole reason for the "-l" flag in either tcpdump or TShark
1611 is to allow the output of a live capture to be piped to a program
1612 or script and to have that script see the information for the
1613 packet as soon as it's printed, rather than having to wait until
1614 a standard I/O buffer fills up.
1616 So, if the "-l" flag is specified, we flush the standard output
1617 at the end of a packet. This will do the right thing if we're
1618 printing packet summary lines, and, as we print the entire protocol
1619 tree for a single packet without waiting for anything to happen,
1620 it should be as good as line-buffered mode if we're printing
1621 protocol trees - arguably even better, as it may do fewer
1622 writes. */
1623 line_buffered = true;
1624 #ifdef HAVE_LIBPCAP
1625 /* Set the update-interval to 0 so that dumpcap reports packets
1626 * as soon as available instead of buffering them.
1628 exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
1629 if (exit_status != 0) {
1630 goto clean_exit;
1632 #endif
1633 break;
1634 case 'L': /* Print list of link-layer types and exit */
1635 #ifdef HAVE_LIBPCAP
1636 caps_queries |= CAPS_QUERY_LINK_TYPES;
1637 #else
1638 capture_option_specified = true;
1639 arg_error = true;
1640 #endif
1641 break;
1642 case LONGOPT_LIST_TSTAMP_TYPES: /* List possible timestamp types */
1643 #ifdef HAVE_LIBPCAP
1644 caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES;
1645 #else
1646 capture_option_specified = true;
1647 arg_error = true;
1648 #endif
1649 break;
1650 case 'o': /* Override preference from command line */
1652 char *errmsg = NULL;
1654 switch (prefs_set_pref(ws_optarg, &errmsg)) {
1656 case PREFS_SET_OK:
1657 break;
1659 case PREFS_SET_SYNTAX_ERR:
1660 cmdarg_err("Invalid -o flag \"%s\"%s%s", ws_optarg,
1661 errmsg ? ": " : "", errmsg ? errmsg : "");
1662 g_free(errmsg);
1663 exit_status = WS_EXIT_INVALID_OPTION;
1664 goto clean_exit;
1665 break;
1667 case PREFS_SET_NO_SUCH_PREF:
1668 cmdarg_err("-o flag \"%s\" specifies unknown preference", ws_optarg);
1669 exit_status = WS_EXIT_INVALID_OPTION;
1670 goto clean_exit;
1671 break;
1673 case PREFS_SET_OBSOLETE:
1674 cmdarg_err("-o flag \"%s\" specifies obsolete preference", ws_optarg);
1675 exit_status = WS_EXIT_INVALID_OPTION;
1676 goto clean_exit;
1677 break;
1679 break;
1681 case 'q': /* Quiet */
1682 quiet = true;
1683 break;
1684 case 'Q': /* Really quiet */
1685 quiet = true;
1686 really_quiet = true;
1687 break;
1688 case 'r':
1689 /* already processed; just ignore it now */
1690 break;
1691 case 'R': /* Read file filter */
1692 rfilter = ws_optarg;
1693 break;
1694 case 'P':
1695 /* already processed; just ignore it now */
1696 break;
1697 case 'S': /* Set the line Separator to be printed between packets */
1698 separator = ws_optarg;
1699 break;
1700 case 'T': /* printing Type */
1701 /* output_action has been already set. It means multiple -T. */
1702 if (output_action > WRITE_NONE) {
1703 cmdarg_err("Multiple -T parameters are unsupported");
1704 exit_status = WS_EXIT_INVALID_OPTION;
1705 goto clean_exit;
1707 print_packet_info = true;
1708 if (strcmp(ws_optarg, "text") == 0) {
1709 output_action = WRITE_TEXT;
1710 print_format = PR_FMT_TEXT;
1711 } else if (strcmp(ws_optarg, "tabs") == 0) {
1712 output_action = WRITE_TEXT;
1713 print_format = PR_FMT_TEXT;
1714 delimiter_char = "\t";
1715 } else if (strcmp(ws_optarg, "ps") == 0) {
1716 output_action = WRITE_TEXT;
1717 print_format = PR_FMT_PS;
1718 } else if (strcmp(ws_optarg, "pdml") == 0) {
1719 output_action = WRITE_XML;
1720 print_details = true; /* Need details */
1721 print_summary = false; /* Don't allow summary */
1722 } else if (strcmp(ws_optarg, "psml") == 0) {
1723 output_action = WRITE_XML;
1724 print_details = false; /* Don't allow details */
1725 print_summary = true; /* Need summary */
1726 } else if (strcmp(ws_optarg, "fields") == 0) {
1727 output_action = WRITE_FIELDS;
1728 print_details = true; /* Need full tree info */
1729 print_summary = false; /* Don't allow summary */
1730 } else if (strcmp(ws_optarg, "json") == 0) {
1731 output_action = WRITE_JSON;
1732 print_details = true; /* Need details */
1733 print_summary = false; /* Don't allow summary */
1734 } else if (strcmp(ws_optarg, "ek") == 0) {
1735 output_action = WRITE_EK;
1736 if (!print_summary)
1737 print_details = true;
1738 } else if (strcmp(ws_optarg, "jsonraw") == 0) {
1739 output_action = WRITE_JSON_RAW;
1740 print_details = true; /* Need details */
1741 print_summary = false; /* Don't allow summary */
1743 else {
1744 cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", ws_optarg); /* x */
1745 cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
1746 "\t specified by the -E option.\n"
1747 "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
1748 "\t details of a decoded packet. This information is equivalent to\n"
1749 "\t the packet details printed with the -V flag.\n"
1750 "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
1751 "\t the packets, or a multi-line view of the details of each of\n"
1752 "\t the packets, depending on whether the -V flag was specified.\n"
1753 "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
1754 "\t summary information of a decoded packet. This information is\n"
1755 "\t equivalent to the information shown in the one-line summary\n"
1756 "\t printed by default.\n"
1757 "\t\"json\" Packet Summary, an JSON-based format for the details\n"
1758 "\t summary information of a decoded packet. This information is \n"
1759 "\t equivalent to the packet details printed with the -V flag.\n"
1760 "\t\"jsonraw\" Packet Details, a JSON-based format for machine parsing\n"
1761 "\t including only raw hex decoded fields (same as -T json -x but\n"
1762 "\t without text decoding, only raw fields included). \n"
1763 "\t\"ek\" Packet Details, an EK JSON-based format for the bulk insert \n"
1764 "\t into elastic search cluster. This information is \n"
1765 "\t equivalent to the packet details printed with the -V flag.\n"
1766 "\t\"text\" Text of a human-readable one-line summary of each of the\n"
1767 "\t packets, or a multi-line view of the details of each of the\n"
1768 "\t packets, depending on whether the -V flag was specified.\n"
1769 "\t This is the default.\n"
1770 "\t\"tabs\" Similar to the text report except that each column of the\n"
1771 "\t human-readable one-line summary is delimited with an ASCII\n"
1772 "\t horizontal tab character.");
1773 exit_status = WS_EXIT_INVALID_OPTION;
1774 goto clean_exit;
1776 break;
1777 case 'U': /* Export PDUs to file */
1778 if (strcmp(ws_optarg, "") == 0 || strcmp(ws_optarg, "?") == 0) {
1779 list_export_pdu_taps();
1780 exit_status = WS_EXIT_INVALID_OPTION;
1781 goto clean_exit;
1783 pdu_export_arg = g_strdup(ws_optarg);
1784 break;
1785 case 'v': /* Show version and exit */
1786 show_version();
1787 /* We don't really have to cleanup here, but it's a convenient way to test
1788 * start-up and shut-down of the epan library without any UI-specific
1789 * cruft getting in the way. Makes the results of running
1790 * $ ./tools/valgrind-wireshark -n
1791 * much more useful. */
1792 epan_cleanup();
1793 extcap_cleanup();
1794 exit_status = EXIT_SUCCESS;
1795 goto clean_exit;
1796 case 'O': /* Only output these protocols */
1797 /* already processed; just ignore it now */
1798 break;
1799 case 'V': /* Verbose */
1800 /* already processed; just ignore it now */
1801 break;
1802 case 'x': /* Print packet data in hex (and ASCII) */
1803 /* already processed; just ignore it now */
1804 break;
1805 case 'X':
1806 /* already processed; just ignore it now */
1807 break;
1808 case 'Y':
1809 dfilter = g_strdup(ws_optarg);
1810 break;
1811 case 'z':
1812 /* We won't call the init function for the stat this soon
1813 as it would disallow MATE's fields (which are registered
1814 by the preferences set callback) from being used as
1815 part of a tap filter. Instead, we just add the argument
1816 to a list of stat arguments. */
1817 if (strcmp("help", ws_optarg) == 0) {
1818 fprintf(stderr, "tshark: The available statistics for the \"-z\" option are:\n");
1819 list_stat_cmd_args();
1820 exit_status = EXIT_SUCCESS;
1821 goto clean_exit;
1823 if (!process_stat_cmd_arg(ws_optarg)) {
1824 cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", ws_optarg);
1825 list_stat_cmd_args();
1826 exit_status = WS_EXIT_INVALID_OPTION;
1827 goto clean_exit;
1829 break;
1830 case 'd': /* Decode as rule */
1831 case 'K': /* Kerberos keytab file */
1832 case 'n': /* No name resolution */
1833 case 'N': /* Select what types of addresses/port #s to resolve */
1834 case 't': /* Time stamp type */
1835 case 'u': /* Seconds type */
1836 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
1837 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
1838 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
1839 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
1840 case LONGOPT_ONLY_PROTOCOLS: /* enable dissection of only this comma separated list of protocols */
1841 case LONGOPT_DISABLE_ALL_PROTOCOLS: /* enable dissection of protocol (that is disabled by default) */
1842 if (!dissect_opts_handle_opt(opt, ws_optarg)) {
1843 exit_status = WS_EXIT_INVALID_OPTION;
1844 goto clean_exit;
1846 break;
1847 case LONGOPT_EXPORT_OBJECTS: /* --export-objects */
1848 if (strcmp("help", ws_optarg) == 0) {
1849 fprintf(stderr, "tshark: The available export object types for the \"--export-objects\" option are:\n");
1850 eo_list_object_types();
1851 exit_status = EXIT_SUCCESS;
1852 goto clean_exit;
1854 if (!eo_tap_opt_add(ws_optarg)) {
1855 exit_status = WS_EXIT_INVALID_OPTION;
1856 goto clean_exit;
1858 break;
1859 case LONGOPT_EXPORT_TLS_SESSION_KEYS: /* --export-tls-session-keys */
1860 tls_session_keys_file = ws_optarg;
1861 break;
1862 case LONGOPT_COLOR: /* print in color where appropriate */
1863 dissect_color = true;
1864 /* This has no effect if we don't print packet info or filter
1865 (we can filter on the coloring rules). Should we warn or
1866 error later if so, instead of silently ignoring it? */
1867 break;
1868 case LONGOPT_NO_DUPLICATE_KEYS:
1869 no_duplicate_keys = true;
1870 node_children_grouper = proto_node_group_children_by_json_key;
1871 break;
1872 case LONGOPT_ELASTIC_MAPPING_FILTER:
1874 * XXX - A long option that exists to alter one other option
1875 * (-G elastic-mapping) and for no other reason seems verbose.
1876 * Deprecate in favor of -G elastic-mapping,<filter> ?
1878 elastic_mapping_filter = ws_optarg;
1879 break;
1880 case LONGOPT_CAPTURE_COMMENT: /* capture comment */
1881 if (capture_comments == NULL) {
1882 capture_comments = g_ptr_array_new_with_free_func(g_free);
1884 g_ptr_array_add(capture_comments, g_strdup(ws_optarg));
1885 break;
1886 case LONGOPT_HEXDUMP:
1887 print_hex = true;
1888 print_packet_info = true;
1889 if (strcmp(ws_optarg, "all") == 0)
1890 hexdump_source_option = HEXDUMP_SOURCE_MULTI;
1891 else if (strcmp(ws_optarg, "frames") == 0)
1892 hexdump_source_option = HEXDUMP_SOURCE_PRIMARY;
1893 else if (strcmp(ws_optarg, "ascii") == 0)
1894 hexdump_ascii_option = HEXDUMP_ASCII_INCLUDE;
1895 else if (strcmp(ws_optarg, "delimit") == 0)
1896 hexdump_ascii_option = HEXDUMP_ASCII_DELIMIT;
1897 else if (strcmp(ws_optarg, "noascii") == 0)
1898 hexdump_ascii_option = HEXDUMP_ASCII_EXCLUDE;
1899 else if (strcmp("help", ws_optarg) == 0) {
1900 hexdump_option_help(stdout);
1901 exit_status = EXIT_SUCCESS;
1902 goto clean_exit;
1903 } else {
1904 fprintf(stderr, "tshark: \"%s\" is an invalid value for --hexdump <hexoption>\n", ws_optarg);
1905 fprintf(stderr, "For valid <hexoption> values enter: tshark --hexdump help\n");
1906 exit_status = WS_EXIT_INVALID_OPTION;
1907 goto clean_exit;
1909 break;
1910 case LONGOPT_SELECTED_FRAME:
1911 /* Hidden option to mark a frame as "selected". Used for testing and debugging.
1912 * Only active in two-pass mode. */
1913 if (!ws_strtou32(ws_optarg, NULL, &selected_frame_number)) {
1914 fprintf(stderr, "tshark: \"%s\" is not a valid frame number\n", ws_optarg);
1915 exit_status = WS_EXIT_INVALID_OPTION;
1916 goto clean_exit;
1918 break;
1919 case LONGOPT_PRINT_TIMERS:
1920 opt_print_timers = true;
1921 break;
1922 case LONGOPT_GLOBAL_PROFILE:
1923 /* already processed; just ignore it now */
1924 break;
1925 case LONGOPT_COMPRESS: /* compress type */
1926 compression_type = wtap_name_to_compression_type(ws_optarg);
1927 if (compression_type == WTAP_UNKNOWN_COMPRESSION) {
1928 cmdarg_err("\"%s\" isn't a valid output compression mode",
1929 ws_optarg);
1930 list_output_compression_types();
1931 goto clean_exit;
1933 break;
1934 default:
1935 case '?': /* Bad flag - print usage message */
1936 switch(ws_optopt) {
1937 case 'F':
1938 list_capture_types();
1939 break;
1940 case LONGOPT_COMPRESS:
1941 list_output_compression_types();
1942 break;
1943 default:
1944 print_usage(stderr);
1946 exit_status = WS_EXIT_INVALID_OPTION;
1947 goto clean_exit;
1948 break;
1952 /* set the default output action to TEXT */
1953 if (output_action == WRITE_NONE)
1954 output_action = WRITE_TEXT;
1956 /* set the default file type to pcapng */
1957 if (out_file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
1958 out_file_type = wtap_pcapng_file_type_subtype();
1961 * Print packet summary information is the default if neither -V or -x
1962 * were specified. Note that this is new behavior, which allows for the
1963 * possibility of printing only hex/ascii output without necessarily
1964 * requiring that either the summary or details be printed too.
1966 if (!print_summary && !print_details && !print_hex)
1967 print_summary = true;
1969 if (no_duplicate_keys && output_action != WRITE_JSON && output_action != WRITE_JSON_RAW) {
1970 cmdarg_err("--no-duplicate-keys can only be used with \"-T json\" and \"-T jsonraw\"");
1971 exit_status = WS_EXIT_INVALID_OPTION;
1972 goto clean_exit;
1975 /* If we specified output fields, but not the output field type... */
1976 /* XXX: If we specfied both output fields with -e *and* protocol filters
1977 * with -j/-J, only the former are used. Should we warn or abort?
1978 * This also doesn't distinguish PDML from PSML, but shouldn't allow the
1979 * latter.
1981 if ((WRITE_FIELDS != output_action && WRITE_XML != output_action && WRITE_JSON != output_action && WRITE_EK != output_action) && 0 != output_fields_num_fields(output_fields)) {
1982 cmdarg_err("Output fields were specified with \"-e\", "
1983 "but \"-Tek, -Tfields, -Tjson or -Tpdml\" was not specified.");
1984 exit_status = WS_EXIT_INVALID_OPTION;
1985 goto clean_exit;
1986 } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
1987 cmdarg_err("\"-Tfields\" was specified, but no fields were "
1988 "specified with \"-e\".");
1990 exit_status = WS_EXIT_INVALID_OPTION;
1991 goto clean_exit;
1994 if (dissect_color) {
1995 if (!color_filters_init(&err_msg, NULL)) {
1996 fprintf(stderr, "%s\n", err_msg);
1997 g_free(err_msg);
2001 /* If no capture filter or display filter has been specified, and there are
2002 still command-line arguments, treat them as the tokens of a capture
2003 filter (if no "-r" flag was specified) or a display filter (if a "-r"
2004 flag was specified. */
2005 if (ws_optind < argc) {
2006 if (cf_name != NULL) {
2007 if (dfilter != NULL) {
2008 cmdarg_err("Display filters were specified both with \"-Y\" "
2009 "and with additional command-line arguments.");
2010 exit_status = WS_EXIT_INVALID_OPTION;
2011 goto clean_exit;
2013 dfilter = get_args_as_string(argc, argv, ws_optind);
2014 } else {
2015 #ifdef HAVE_LIBPCAP
2016 unsigned i;
2018 if (global_capture_opts.default_options.cfilter) {
2019 cmdarg_err("A default capture filter was specified both with \"-f\""
2020 " and with additional command-line arguments.");
2021 exit_status = WS_EXIT_INVALID_OPTION;
2022 goto clean_exit;
2024 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2025 interface_options *interface_opts;
2026 interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
2027 if (interface_opts->cfilter == NULL) {
2028 interface_opts->cfilter = get_args_as_string(argc, argv, ws_optind);
2029 } else {
2030 cmdarg_err("A capture filter was specified both with \"-f\""
2031 " and with additional command-line arguments.");
2032 exit_status = WS_EXIT_INVALID_OPTION;
2033 goto clean_exit;
2036 global_capture_opts.default_options.cfilter = get_args_as_string(argc, argv, ws_optind);
2037 #else
2038 capture_option_specified = true;
2039 #endif
2043 if (!output_file_name) {
2044 /* We're not saving the capture to a file; if "-q" wasn't specified,
2045 we should print packet information */
2046 if (!quiet)
2047 print_packet_info = true;
2048 } else {
2049 const char *save_file = output_file_name;
2050 /* We're saving to a file; if we're writing to the standard output.
2051 and we'll also be writing dissected packets to the standard
2052 output, reject the request. At best, we could redirect that
2053 to the standard error; we *can't* write both to the standard
2054 output and have either of them be useful. */
2055 if (strcmp(save_file, "-") == 0 && print_packet_info) {
2056 cmdarg_err("You can't write both raw packet data and dissected packets"
2057 " to the standard output.");
2058 exit_status = WS_EXIT_INVALID_OPTION;
2059 goto clean_exit;
2061 if (compression_type == WTAP_UNKNOWN_COMPRESSION) {
2062 /* An explicitly specified compression type overrides filename
2063 * magic. (Should we allow a way to specify "no" compression
2064 * with, e.g. a ".gz" extension?) */
2065 const char *sfx = strrchr(save_file, '.');
2066 if (sfx) {
2067 compression_type = wtap_extension_to_compression_type(sfx + 1);
2072 if (compression_type == WTAP_UNKNOWN_COMPRESSION) {
2073 compression_type = WTAP_UNCOMPRESSED;
2076 if (!wtap_can_write_compression_type(compression_type)) {
2077 cmdarg_err("Output files can't be written as %s",
2078 wtap_compression_type_description(compression_type));
2079 exit_status = WS_EXIT_INVALID_OPTION;
2080 goto clean_exit;
2083 if (compression_type != WTAP_UNCOMPRESSED && !wtap_dump_can_compress(out_file_type)) {
2084 cmdarg_err("The file format %s can't be written to output compressed format",
2085 wtap_file_type_subtype_name(out_file_type));
2086 exit_status = WS_EXIT_INVALID_OPTION;
2087 goto clean_exit;
2090 if (compression_type != WTAP_UNCOMPRESSED && is_capturing) {
2091 cmdarg_err("Writing to compressed output is not supported for live captures");
2092 exit_status = WS_EXIT_INVALID_OPTION;
2093 goto clean_exit;
2096 #ifndef HAVE_LIBPCAP
2097 if (capture_option_specified)
2098 cmdarg_err("This version of TShark was not built with support for capturing packets.");
2099 #endif
2100 if (arg_error) {
2101 print_usage(stderr);
2102 exit_status = WS_EXIT_INVALID_OPTION;
2103 goto clean_exit;
2106 if (print_hex) {
2107 if (output_action != WRITE_TEXT && output_action != WRITE_JSON && output_action != WRITE_JSON_RAW && output_action != WRITE_EK) {
2108 cmdarg_err("Raw packet hex data can only be printed as text, PostScript, JSON, JSONRAW or EK JSON");
2109 exit_status = WS_EXIT_INVALID_OPTION;
2110 goto clean_exit;
2114 if (output_only != NULL) {
2115 char *ps;
2117 if (!print_details) {
2118 cmdarg_err("-O requires -V");
2119 exit_status = WS_EXIT_INVALID_OPTION;
2120 goto clean_exit;
2123 output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
2124 for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
2125 const char *name = ps;
2126 header_field_info *hfi = proto_registrar_get_byalias(name);
2127 if (hfi) {
2128 name = hfi->abbrev;
2130 g_hash_table_insert(output_only_tables, (void *)name, (void *)name);
2134 if (rfilter != NULL && !perform_two_pass_analysis) {
2135 cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
2136 exit_status = WS_EXIT_INVALID_OPTION;
2137 goto clean_exit;
2140 #ifdef HAVE_LIBPCAP
2141 if (caps_queries) {
2142 /* We're supposed to list the link-layer/timestamp types for an interface;
2143 did the user also specify a capture file to be read? */
2144 if (cf_name) {
2145 /* Yes - that's bogus. */
2146 cmdarg_err("You can't specify %s and a capture file to be read.",
2147 caps_queries & CAPS_QUERY_LINK_TYPES ? "-L" : "--list-time-stamp-types");
2148 exit_status = WS_EXIT_INVALID_OPTION;
2149 goto clean_exit;
2151 /* No - did they specify a ring buffer option? */
2152 if (global_capture_opts.multi_files_on) {
2153 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2154 exit_status = WS_EXIT_INVALID_OPTION;
2155 goto clean_exit;
2157 } else {
2158 if (cf_name) {
2160 * "-r" was specified, so we're reading a capture file.
2161 * Capture options don't apply here.
2164 /* We don't support capture filters when reading from a capture file
2165 (the BPF compiler doesn't support all link-layer types that we
2166 support in capture files we read). */
2167 if (global_capture_opts.default_options.cfilter) {
2168 cmdarg_err("Only read filters, not capture filters, "
2169 "can be specified when reading a capture file.");
2170 exit_status = WS_EXIT_INVALID_OPTION;
2171 goto clean_exit;
2173 if (global_capture_opts.multi_files_on) {
2174 cmdarg_err("Multiple capture files requested, but "
2175 "a capture isn't being done.");
2176 exit_status = WS_EXIT_INVALID_OPTION;
2177 goto clean_exit;
2179 if (global_capture_opts.has_file_duration) {
2180 cmdarg_err("Switching capture files after a time period was specified, but "
2181 "a capture isn't being done.");
2182 exit_status = WS_EXIT_INVALID_OPTION;
2183 goto clean_exit;
2185 if (global_capture_opts.has_file_interval) {
2186 cmdarg_err("Switching capture files after a time interval was specified, but "
2187 "a capture isn't being done.");
2188 exit_status = WS_EXIT_INVALID_OPTION;
2189 goto clean_exit;
2191 if (global_capture_opts.has_ring_num_files) {
2192 cmdarg_err("A ring buffer of capture files was specified, but "
2193 "a capture isn't being done.");
2194 exit_status = WS_EXIT_INVALID_OPTION;
2195 goto clean_exit;
2197 if (global_capture_opts.has_autostop_files) {
2198 cmdarg_err("A maximum number of capture files was specified, but "
2199 "a capture isn't being done.");
2200 exit_status = WS_EXIT_INVALID_OPTION;
2201 goto clean_exit;
2204 /* Note: TShark now allows the restriction of a _read_ file by packet count
2205 * and byte count as well as a write file. Other autostop options remain valid
2206 * only for a write file.
2208 if (global_capture_opts.has_autostop_duration) {
2209 cmdarg_err("A maximum capture time was specified, but "
2210 "a capture isn't being done.");
2211 exit_status = WS_EXIT_INVALID_OPTION;
2212 goto clean_exit;
2214 } else {
2216 * "-r" wasn't specified, so we're doing a live capture.
2218 bool use_pcapng = true;
2220 if (perform_two_pass_analysis) {
2221 /* Two-pass analysis doesn't work with live capture since it requires us
2222 * to buffer packets until we've read all of them, but a live capture
2223 * has no useful/meaningful definition of "all" */
2224 cmdarg_err("Live captures do not support two-pass analysis.");
2225 exit_status = WS_EXIT_INVALID_OPTION;
2226 goto clean_exit;
2229 if (global_capture_opts.saving_to_file) {
2230 /* They specified a "-w" flag, so we'll be saving to a capture file. */
2232 /* When capturing, we only support writing pcap or pcapng format. */
2233 if (out_file_type == wtap_pcapng_file_type_subtype()) {
2234 use_pcapng = true;
2235 } else if (out_file_type == wtap_pcap_file_type_subtype()) {
2236 use_pcapng = false;
2237 } else if (out_file_type == wtap_pcap_nsec_file_type_subtype()) {
2238 /* XXX - We request nanosecond time resolution regardless.
2239 * In the future wiretap might treat the two pcap subtypes
2240 * the same.
2242 use_pcapng = false;
2243 } else {
2244 cmdarg_err("Live captures can only be saved in pcap or pcapng format.");
2245 capture_opts_list_file_types();
2246 exit_status = WS_EXIT_INVALID_OPTION;
2247 goto clean_exit;
2249 if (capture_comments != NULL && !use_pcapng) {
2250 cmdarg_err("Capture comments can only be written to a pcapng file.");
2251 exit_status = WS_EXIT_INVALID_OPTION;
2252 goto clean_exit;
2254 if (global_capture_opts.multi_files_on) {
2255 /* Multiple-file mode doesn't work under certain conditions:
2256 a) it doesn't work if you're writing to the standard output;
2257 b) it doesn't work if you're writing to a pipe;
2259 if (strcmp(global_capture_opts.save_file, "-") == 0) {
2260 cmdarg_err("Multiple capture files requested, but "
2261 "the capture is being written to the standard output.");
2262 exit_status = WS_EXIT_INVALID_OPTION;
2263 goto clean_exit;
2265 if (global_capture_opts.output_to_pipe) {
2266 cmdarg_err("Multiple capture files requested, but "
2267 "the capture file is a pipe.");
2268 exit_status = WS_EXIT_INVALID_OPTION;
2269 goto clean_exit;
2271 if (!global_capture_opts.has_autostop_filesize &&
2272 !global_capture_opts.has_file_duration &&
2273 !global_capture_opts.has_file_interval &&
2274 !global_capture_opts.has_file_packets) {
2275 cmdarg_err("Multiple capture files requested, but "
2276 "no maximum capture file size, duration, interval or packets were specified.");
2277 exit_status = WS_EXIT_INVALID_OPTION;
2278 goto clean_exit;
2281 /* Currently, we don't support read or display filters when capturing
2282 and saving the packets. */
2283 if (rfilter != NULL) {
2284 cmdarg_err("Read filters aren't supported when capturing and saving the captured packets.");
2285 exit_status = WS_EXIT_INVALID_OPTION;
2286 goto clean_exit;
2288 if (dfilter != NULL) {
2289 cmdarg_err("Display filters aren't supported when capturing and saving the captured packets.");
2290 exit_status = WS_EXIT_INVALID_OPTION;
2291 goto clean_exit;
2293 global_capture_opts.use_pcapng = use_pcapng;
2294 } else {
2295 /* They didn't specify a "-w" flag, so we won't be saving to a
2296 capture file. Check for options that only make sense if
2297 we're saving to a file. */
2298 if (global_capture_opts.has_autostop_filesize) {
2299 cmdarg_err("Maximum capture file size specified, but "
2300 "capture isn't being saved to a file.");
2301 exit_status = WS_EXIT_INVALID_OPTION;
2302 goto clean_exit;
2304 if (global_capture_opts.multi_files_on) {
2305 cmdarg_err("Multiple capture files requested, but "
2306 "the capture isn't being saved to a file.");
2307 exit_status = WS_EXIT_INVALID_OPTION;
2308 goto clean_exit;
2310 if (capture_comments != NULL) {
2311 cmdarg_err("Capture comments were specified, but "
2312 "the capture isn't being saved to a file.");
2313 exit_status = WS_EXIT_INVALID_OPTION;
2314 goto clean_exit;
2319 #endif
2322 * If capture comments were specified, -w also has to have been specified.
2324 if (capture_comments != NULL) {
2325 if (output_file_name) {
2326 /* They specified a "-w" flag, so we'll be saving to a capture file.
2327 * This is fine if they're writing in a format that supports
2328 * section block comments.
2330 if (wtap_file_type_subtype_supports_option(out_file_type,
2331 WTAP_BLOCK_SECTION,
2332 OPT_COMMENT) == OPTION_NOT_SUPPORTED) {
2333 GArray *writable_type_subtypes;
2335 cmdarg_err("Capture comments can only be written to files of the following types:");
2336 writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME);
2337 for (unsigned i = 0; i < writable_type_subtypes->len; i++) {
2338 int ft = g_array_index(writable_type_subtypes, int, i);
2340 if (wtap_file_type_subtype_supports_option(ft, WTAP_BLOCK_SECTION,
2341 OPT_COMMENT) != OPTION_NOT_SUPPORTED)
2342 cmdarg_err_cont(" %s - %s", wtap_file_type_subtype_name(ft),
2343 wtap_file_type_subtype_description(ft));
2345 exit_status = WS_EXIT_INVALID_OPTION;
2346 goto clean_exit;
2349 else {
2350 cmdarg_err("Capture comments were specified, but you aren't writing a capture file.");
2351 exit_status = WS_EXIT_INVALID_OPTION;
2352 goto clean_exit;
2356 err_msg = ws_init_sockets();
2357 if (err_msg != NULL)
2359 cmdarg_err("%s", err_msg);
2360 g_free(err_msg);
2361 cmdarg_err_cont("%s", please_report_bug());
2362 exit_status = WS_EXIT_INIT_FAILED;
2363 goto clean_exit;
2366 /* Notify all registered modules that have had any of their preferences
2367 changed either from one of the preferences file or from the command
2368 line that their preferences have changed. */
2369 prefs_apply_all();
2371 /* We can also enable specified taps for export object */
2372 start_exportobjects();
2374 /* At this point MATE will have registered its field array so we can
2375 check if the fields specified by the user are all good.
2378 GSList* it = NULL;
2379 GSList *invalid_fields = output_fields_valid(output_fields);
2380 if (invalid_fields != NULL) {
2382 cmdarg_err("Some fields aren't valid:");
2383 for (it=invalid_fields; it != NULL; it = g_slist_next(it)) {
2384 cmdarg_err_cont("\t%s", (char *)it->data);
2386 g_slist_free(invalid_fields);
2387 exit_status = WS_EXIT_INVALID_OPTION;
2388 goto clean_exit;
2392 if (ex_opt_count("read_format") > 0) {
2393 const char* name = ex_opt_get_next("read_format");
2394 in_file_type = open_info_name_to_type(name);
2395 if (in_file_type == WTAP_TYPE_AUTO) {
2396 cmdarg_err("\"%s\" isn't a valid read file format type", name? name : "");
2397 list_read_capture_types();
2398 exit_status = WS_EXIT_INVALID_OPTION;
2399 goto clean_exit;
2403 if (global_dissect_options.time_format != TS_NOT_SET)
2404 timestamp_set_type(global_dissect_options.time_format);
2405 if (global_dissect_options.time_precision != TS_PREC_NOT_SET)
2406 timestamp_set_precision(global_dissect_options.time_precision);
2409 * Enabled and disabled protocols and heuristic dissectors as per
2410 * command-line options.
2412 if (!setup_enabled_and_disabled_protocols()) {
2413 exit_status = WS_EXIT_INVALID_OPTION;
2414 goto clean_exit;
2417 /* Build the column format array */
2418 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, true);
2420 /* Everything is setup, dump glossaries now if that's what we're doing.
2421 * We want to do this after protocols and heuristic dissectors are
2422 * enabled and disabled. Doing it after building the column format
2423 * array might make it easier to add a report that describes the
2424 * current list of columns and how to add a new one (#17332).
2426 if (glossary != NULL) {
2427 exit_status = dump_glossary(glossary, elastic_mapping_filter);
2428 goto clean_exit;
2431 #ifdef HAVE_LIBPCAP
2432 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2433 capture_opts_trim_ring_num_files(&global_capture_opts);
2434 #endif
2436 if (rfilter != NULL) {
2437 ws_debug("Compiling read filter: '%s'", rfilter);
2438 if (!compile_dfilter(rfilter, &rfcode)) {
2439 epan_cleanup();
2440 extcap_cleanup();
2442 #ifdef HAVE_LIBPCAP
2443 warn_about_capture_filter(rfilter);
2444 #endif
2446 exit_status = WS_EXIT_INVALID_INTERFACE;
2447 goto clean_exit;
2450 cfile.rfcode = rfcode;
2452 if (dfilter != NULL) {
2453 ws_debug("Compiling display filter: '%s'", dfilter);
2454 if (!compile_dfilter(dfilter, &dfcode)) {
2455 epan_cleanup();
2456 extcap_cleanup();
2458 #ifdef HAVE_LIBPCAP
2459 warn_about_capture_filter(dfilter);
2460 #endif
2462 exit_status = WS_EXIT_INVALID_FILTER;
2463 goto clean_exit;
2466 cfile.dfcode = dfcode;
2468 if (print_packet_info) {
2469 /* If we're printing as text or PostScript, we have
2470 to create a print stream. */
2471 if (output_action == WRITE_TEXT) {
2472 switch (print_format) {
2474 case PR_FMT_TEXT:
2475 print_stream = print_stream_text_stdio_new(stdout);
2476 break;
2478 case PR_FMT_PS:
2479 print_stream = print_stream_ps_stdio_new(stdout);
2480 break;
2482 default:
2483 ws_assert_not_reached();
2488 /* PDU export requested. Take the ownership of the '-w' file, apply tap
2489 * filters and start tapping. */
2490 if (pdu_export_arg) {
2491 const char *exp_pdu_tap_name = pdu_export_arg;
2492 const char *exp_pdu_filter = dfilter; /* may be NULL to disable filter */
2493 char *exp_pdu_error;
2494 int exp_fd;
2495 char *comment;
2497 if (!cf_name) {
2498 cmdarg_err("PDUs export requires a capture file (specify with -r).");
2499 exit_status = WS_EXIT_INVALID_OPTION;
2500 goto clean_exit;
2502 /* Take ownership of the '-w' output file. */
2503 exp_pdu_filename = output_file_name;
2504 output_file_name = NULL;
2505 #ifdef HAVE_LIBPCAP
2506 global_capture_opts.save_file = NULL;
2507 #endif
2508 if (exp_pdu_filename == NULL) {
2509 cmdarg_err("PDUs export requires an output file (-w).");
2510 exit_status = WS_EXIT_INVALID_OPTION;
2511 goto clean_exit;
2514 exp_pdu_error = exp_pdu_pre_open(exp_pdu_tap_name, exp_pdu_filter,
2515 &exp_pdu_tap_data);
2516 if (exp_pdu_error) {
2517 cmdarg_err("Cannot register tap: %s", exp_pdu_error);
2518 g_free(exp_pdu_error);
2519 list_export_pdu_taps();
2520 exit_status = INVALID_TAP;
2521 goto clean_exit;
2524 if (strcmp(exp_pdu_filename, "-") == 0) {
2525 /* Write to the standard output. */
2526 exp_fd = 1;
2527 } else {
2528 exp_fd = ws_open(exp_pdu_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
2529 if (exp_fd == -1) {
2530 cmdarg_err("%s: %s", exp_pdu_filename, file_open_error_message(errno, true));
2531 exit_status = WS_EXIT_INVALID_FILE;
2532 goto clean_exit;
2536 /* Activate the export PDU tap */
2537 /* Write to our output file with this comment (if the type supports it,
2538 * otherwise exp_pdu_open() will ignore the comment) */
2539 comment = ws_strdup_printf("Dump of PDUs from %s", cf_name);
2540 exp_pdu_status = exp_pdu_open(&exp_pdu_tap_data, exp_pdu_filename,
2541 out_file_type, exp_fd, comment,
2542 &err, &err_info);
2543 g_free(comment);
2544 if (!exp_pdu_status) {
2545 cfile_dump_open_failure_message(exp_pdu_filename, err, err_info,
2546 out_file_type);
2547 exit_status = INVALID_EXPORT;
2548 goto clean_exit;
2552 if (cf_name) {
2553 ws_debug("tshark: Opening capture file: %s", cf_name);
2555 * We're reading a capture file.
2557 if (cf_open(&cfile, cf_name, in_file_type, false, &err) != CF_OK) {
2558 epan_cleanup();
2559 extcap_cleanup();
2560 exit_status = WS_EXIT_INVALID_FILE;
2561 goto clean_exit;
2564 /* Start statistics taps; we do so after successfully opening the
2565 capture file, so we know we have something to compute stats
2566 on, and after registering all dissectors, so that MATE will
2567 have registered its field array so we can have a tap filter
2568 with one of MATE's late-registered fields as part of the
2569 filter. */
2570 start_requested_stats();
2572 /* Do we need to do dissection of packets? That depends on, among
2573 other things, what taps are listening, so determine that after
2574 starting the statistics taps. */
2575 do_dissection = must_do_dissection(rfcode, dfcode, pdu_export_arg);
2576 ws_debug("tshark: do_dissection = %s", do_dissection ? "TRUE" : "FALSE");
2578 /* Process the packets in the file */
2579 ws_debug("tshark: invoking process_cap_file() to process the packets");
2580 TRY {
2581 status = process_cap_file(&cfile, output_file_name, out_file_type, out_file_name_res,
2582 #ifdef HAVE_LIBPCAP
2583 global_capture_opts.has_autostop_packets ? global_capture_opts.autostop_packets : 0,
2584 global_capture_opts.has_autostop_filesize ? global_capture_opts.autostop_filesize : 0,
2585 global_capture_opts.has_autostop_written_packets ? global_capture_opts.autostop_written_packets : 0,
2586 compression_type);
2587 #else
2588 max_packet_count,
2591 WTAP_UNCOMPRESSED);
2592 #endif
2594 CATCH(OutOfMemoryError) {
2595 fprintf(stderr,
2596 "Out Of Memory.\n"
2597 "\n"
2598 "Sorry, but TShark has to terminate now.\n"
2599 "\n"
2600 "More information and workarounds can be found at\n"
2601 WS_WIKI_URL("KnownBugs/OutOfMemory") "\n");
2602 status = PROCESS_FILE_ERROR;
2604 ENDTRY;
2606 switch (status) {
2608 case PROCESS_FILE_SUCCEEDED:
2609 /* Everything worked OK; draw the taps. */
2610 draw_taps = true;
2611 break;
2613 case PROCESS_FILE_NO_FILE_PROCESSED:
2614 /* We never got to try to read the file, so there are no tap
2615 results to dump. Exit with an error status. */
2616 exit_status = 2;
2617 break;
2619 case PROCESS_FILE_ERROR:
2620 /* We still dump out the results of taps, etc., as we might have
2621 read some packets; however, we exit with an error status. */
2622 draw_taps = true;
2623 exit_status = 2;
2624 break;
2626 case PROCESS_FILE_INTERRUPTED:
2627 /* The user interrupted the read process; Don't dump out the
2628 result of taps, etc., and exit with an error status. */
2629 exit_status = 2;
2630 break;
2633 if (pdu_export_arg) {
2634 if (!exp_pdu_close(&exp_pdu_tap_data, &err, &err_info)) {
2635 cfile_close_failure_message(exp_pdu_filename, err, err_info);
2636 exit_status = 2;
2638 g_free(pdu_export_arg);
2639 g_free(exp_pdu_filename);
2641 } else {
2642 ws_debug("tshark: no capture file specified");
2643 /* No capture file specified, so we're supposed to do a live capture
2644 or get a list of link-layer types for a live capture device;
2645 do we have support for live captures? */
2646 #ifdef HAVE_LIBPCAP
2647 #ifdef _WIN32
2648 /* Warn the user if npf.sys isn't loaded. */
2649 if (!npf_sys_is_running()) {
2650 fprintf(stderr, "The NPF driver isn't running. You may have trouble "
2651 "capturing or\nlisting interfaces.\n");
2653 #endif /* _WIN32 */
2655 /* if no interface was specified, pick a default */
2656 exit_status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2657 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2658 if (exit_status != 0) {
2659 goto clean_exit;
2663 * If requested, list the link layer types and/or time stamp types
2664 * and exit.
2666 if (caps_queries) {
2667 unsigned i;
2669 /* Get the list of link-layer types for the capture devices. */
2670 exit_status = EXIT_SUCCESS;
2671 GList *if_cap_queries = NULL;
2672 if_cap_query_t *if_cap_query;
2673 GHashTable *capability_hash;
2674 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2675 interface_options *interface_opts;
2676 interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
2677 if_cap_query = g_new(if_cap_query_t, 1);
2678 if_cap_query->name = interface_opts->name;
2679 if_cap_query->monitor_mode = interface_opts->monitor_mode;
2680 if_cap_query->auth_username = NULL;
2681 if_cap_query->auth_password = NULL;
2682 #ifdef HAVE_PCAP_REMOTE
2683 if (interface_opts->auth_type == CAPTURE_AUTH_PWD) {
2684 if_cap_query->auth_username = interface_opts->auth_username;
2685 if_cap_query->auth_password = interface_opts->auth_password;
2687 #endif
2688 if_cap_queries = g_list_prepend(if_cap_queries, if_cap_query);
2690 if_cap_queries = g_list_reverse(if_cap_queries);
2691 capability_hash = capture_get_if_list_capabilities(if_cap_queries, &err_str, &err_str_secondary, NULL);
2692 g_list_free_full(if_cap_queries, g_free);
2693 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2694 interface_options *interface_opts;
2695 interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
2696 if_capabilities_t *caps;
2697 caps = g_hash_table_lookup(capability_hash, interface_opts->name);
2698 if (caps == NULL) {
2699 cmdarg_err("%s%s%s", err_str, err_str_secondary ? "\n" : "", err_str_secondary ? err_str_secondary : "");
2700 g_free(err_str);
2701 g_free(err_str_secondary);
2702 exit_status = WS_EXIT_INVALID_CAPABILITY;
2703 break;
2705 exit_status = capture_opts_print_if_capabilities(caps, interface_opts,
2706 caps_queries);
2707 if (exit_status != EXIT_SUCCESS) {
2708 break;
2711 g_hash_table_destroy(capability_hash);
2712 goto clean_exit;
2716 * If the standard error isn't a terminal, don't print packet counts,
2717 * as they won't show up on the user's terminal and they'll get in
2718 * the way of error messages in the file (to which we assume the
2719 * standard error was redirected; if it's redirected to the null
2720 * device, there's no point in printing packet counts anyway).
2722 * Otherwise, if we're printing packet information and the standard
2723 * output is a terminal (which we assume means the standard output and
2724 * error are going to the same terminal), don't print packet counts,
2725 * as they'll get in the way of the packet information.
2727 * Otherwise, if the user specified -q, don't print packet counts.
2729 * Otherwise, print packet counts.
2731 * XXX - what if the user wants to do a live capture, doesn't want
2732 * to save it to a file, doesn't want information printed for each
2733 * packet, does want some "-z" statistic, and wants packet counts
2734 * so they know whether they're seeing any packets? -q will
2735 * suppress the information printed for each packet, but it'll
2736 * also suppress the packet counts.
2738 if (!ws_isatty(ws_fileno(stderr)))
2739 print_packet_counts = false;
2740 else if (print_packet_info && ws_isatty(ws_fileno(stdout)))
2741 print_packet_counts = false;
2742 else if (quiet)
2743 print_packet_counts = false;
2744 else
2745 print_packet_counts = true;
2747 ws_debug("tshark: performing live capture");
2749 /* Start statistics taps; we should only do so after the capture
2750 started successfully, so we know we have something to compute
2751 stats, but we currently don't check for that - see below.
2753 We do so after registering all dissectors, so that MATE will
2754 have registered its field array so we can have a tap filter
2755 with one of MATE's late-registered fields as part of the
2756 filter. */
2757 start_requested_stats();
2759 /* Do we need to do dissection of packets? That depends on, among
2760 other things, what taps are listening, so determine that after
2761 starting the statistics taps. */
2762 do_dissection = must_do_dissection(rfcode, dfcode, pdu_export_arg);
2763 ws_debug("tshark: do_dissection = %s", do_dissection ? "TRUE" : "FALSE");
2765 /* We're doing live capture; if the capture child is writing to a pipe,
2766 we can't do dissection, because that would mean two readers for
2767 the pipe, tshark and whatever else. */
2768 if (do_dissection && global_capture_opts.output_to_pipe) {
2769 if (tap_listeners_require_dissection()) {
2770 cmdarg_err("Taps aren't supported when capturing and saving to a pipe.");
2771 exit_status = WS_EXIT_INVALID_OPTION;
2772 goto clean_exit;
2774 if (print_packet_info) {
2775 cmdarg_err("Printing dissected packets isn't supported when capturing and saving to a pipe.");
2776 exit_status = WS_EXIT_INVALID_OPTION;
2777 goto clean_exit;
2779 /* We already checked the next three reasons for supersets of
2780 capturing and saving to a pipe, but this doesn't hurt. */
2781 if (pdu_export_arg) {
2782 cmdarg_err("PDUs export isn't supported when capturing and saving to a pipe.");
2783 exit_status = WS_EXIT_INVALID_OPTION;
2784 goto clean_exit;
2786 if (rfcode != NULL) {
2787 cmdarg_err("Read filters aren't supported when capturing and saving to a pipe.");
2788 exit_status = WS_EXIT_INVALID_OPTION;
2789 goto clean_exit;
2791 if (dfcode != NULL) {
2792 cmdarg_err("Display filters aren't supported when capturing and saving to a pipe.");
2793 exit_status = WS_EXIT_INVALID_OPTION;
2794 goto clean_exit;
2796 /* There's some other reason we're dissecting. */
2797 cmdarg_err("Dissection isn't supported when capturing and saving to a pipe.");
2798 exit_status = WS_EXIT_INVALID_OPTION;
2799 goto clean_exit;
2802 /* Write a preamble if we're printing one. Do this after all checking
2803 * for invalid options, so we don't print just a preamble and quit. */
2804 if (print_packet_info) {
2805 if (!write_preamble(&cfile)) {
2806 show_print_file_io_error();
2807 exit_status = WS_EXIT_INVALID_FILE;
2808 goto clean_exit;
2813 * XXX - this returns false if an error occurred, but it also
2814 * returns false if the capture stops because a time limit
2815 * was reached (and possibly other limits), so we can't assume
2816 * it means an error.
2818 * The capture code is a bit twisty, so it doesn't appear to
2819 * be an easy fix. We just ignore the return value for now.
2820 * Instead, pass on the exit status from the capture child.
2822 capture();
2823 exit_status = global_capture_session.fork_child_status;
2825 if (print_packet_info) {
2826 if (!write_finale()) {
2827 show_print_file_io_error();
2832 * If we never got a capture file, don't draw the taps; we not only
2833 * didn't capture any packets, we never even did any capturing.
2835 if (cfile.filename != NULL)
2836 draw_taps = true;
2837 #else
2838 /* No - complain. */
2839 cmdarg_err("This version of TShark was not built with support for capturing packets.");
2840 exit_status = INVALID_CAPTURE;
2841 goto clean_exit;
2842 #endif
2845 if (cfile.provider.frames != NULL) {
2846 free_frame_data_sequence(cfile.provider.frames);
2847 cfile.provider.frames = NULL;
2850 if (draw_taps)
2851 draw_tap_listeners(true);
2853 if (tls_session_keys_file) {
2854 size_t keylist_length;
2855 char *keylist = ssl_export_sessions(&keylist_length);
2856 write_file_binary_mode(tls_session_keys_file, keylist, keylist_length);
2857 g_free(keylist);
2860 if (opt_print_timers) {
2861 if (cf_name == NULL) {
2862 /* We're doind a live capture. That isn't currently supported
2863 * with timers. */
2864 ws_message("Ignoring option --print-timers because we are doing a live capture");
2866 else {
2867 print_elapsed_json(cf_name, dfilter);
2871 /* Memory cleanup */
2872 reset_tap_listeners();
2873 funnel_dump_all_text_windows();
2874 epan_free(cfile.epan);
2875 epan_cleanup();
2876 extcap_cleanup();
2878 output_fields_free(output_fields);
2879 output_fields = NULL;
2881 clean_exit:
2882 cf_close(&cfile);
2883 g_free(cf_name);
2884 destroy_print_stream(print_stream);
2885 g_free(output_file_name);
2886 #ifdef HAVE_LIBPCAP
2887 capture_opts_cleanup(&global_capture_opts);
2888 if (cached_if_list) {
2889 free_interface_list(cached_if_list);
2891 #endif
2892 col_cleanup(&cfile.cinfo);
2893 wtap_cleanup();
2894 free_progdirs();
2895 dfilter_free(dfcode);
2896 g_free(dfilter);
2897 return exit_status;
2900 bool loop_running;
2901 uint32_t packet_count;
2903 static epan_t *
2904 tshark_epan_new(capture_file *cf)
2906 static const struct packet_provider_funcs funcs = {
2907 cap_file_provider_get_frame_ts,
2908 cap_file_provider_get_interface_name,
2909 cap_file_provider_get_interface_description,
2910 NULL,
2913 return epan_new(&cf->provider, &funcs);
2916 #ifdef HAVE_LIBPCAP
2917 static bool
2918 capture(void)
2920 volatile bool ret = true;
2921 GString *str;
2922 GMainContext *ctx;
2923 #ifndef _WIN32
2924 struct sigaction action, oldaction;
2925 #endif
2927 /* Create new dissection section. */
2928 epan_free(cfile.epan);
2929 cfile.epan = tshark_epan_new(&cfile);
2931 #ifdef _WIN32
2932 /* Catch a CTRL+C event and, if we get it, clean up and exit. */
2933 SetConsoleCtrlHandler(capture_cleanup, true);
2934 #else /* _WIN32 */
2935 /* Catch SIGINT and SIGTERM and, if we get either of them,
2936 clean up and exit. If SIGHUP isn't being ignored, catch
2937 it too and, if we get it, clean up and exit.
2939 We restart any read that was in progress, so that it doesn't
2940 disrupt reading from the sync pipe. The signal handler tells
2941 the capture child to finish; it will report that it finished,
2942 or will exit abnormally, so we'll stop reading from the sync
2943 pipe, pick up the exit status, and quit. */
2944 memset(&action, 0, sizeof(action));
2945 action.sa_handler = capture_cleanup;
2946 action.sa_flags = SA_RESTART;
2947 sigemptyset(&action.sa_mask);
2948 sigaction(SIGTERM, &action, NULL);
2949 sigaction(SIGINT, &action, NULL);
2950 sigaction(SIGHUP, NULL, &oldaction);
2951 if (oldaction.sa_handler == SIG_DFL)
2952 sigaction(SIGHUP, &action, NULL);
2954 #ifdef SIGINFO
2955 /* Catch SIGINFO and, if we get it and we're capturing to a file in
2956 quiet mode, report the number of packets we've captured.
2958 Again, restart any read that was in progress, so that it doesn't
2959 disrupt reading from the sync pipe. */
2960 action.sa_handler = report_counts_siginfo;
2961 action.sa_flags = SA_RESTART;
2962 sigemptyset(&action.sa_mask);
2963 sigaction(SIGINFO, &action, NULL);
2964 #endif /* SIGINFO */
2965 #endif /* _WIN32 */
2967 global_capture_session.state = CAPTURE_PREPARING;
2969 /* Let the user know which interfaces were chosen. */
2970 str = get_iface_list_string(&global_capture_opts, IFLIST_QUOTE_IF_DESCRIPTION);
2971 if (really_quiet == false)
2972 fprintf(stderr, "Capturing on %s\n", str->str);
2973 fflush(stderr);
2974 g_string_free(str, TRUE);
2976 ret = sync_pipe_start(&global_capture_opts, capture_comments,
2977 &global_capture_session, &global_info_data, NULL);
2979 if (!ret)
2980 return false;
2983 * Force synchronous resolution of IP addresses; we're doing only
2984 * one pass, so we can't do it in the background and fix up past
2985 * dissections.
2987 set_resolution_synchrony(true);
2989 /* the actual capture loop */
2990 ctx = g_main_context_default();
2991 loop_running = true;
2995 while (loop_running)
2997 g_main_context_iteration(ctx, true);
3000 CATCH(OutOfMemoryError) {
3001 fprintf(stderr,
3002 "Out Of Memory.\n"
3003 "\n"
3004 "Sorry, but TShark has to terminate now.\n"
3005 "\n"
3006 "More information and workarounds can be found at\n"
3007 WS_WIKI_URL("KnownBugs/OutOfMemory") "\n");
3008 abort();
3010 ENDTRY;
3011 return ret;
3014 /* capture child detected an error */
3015 static void
3016 capture_input_error(capture_session *cap_session _U_, char *error_msg, char *secondary_error_msg)
3018 /* The primary message might be an empty string, e.g. when the error was
3019 * from extcap. (The extcap stderr is gathered when the session closes
3020 * and printed in capture_input_closed below.) */
3021 if (*error_msg != '\0') {
3022 cmdarg_err("%s", error_msg);
3023 if (secondary_error_msg != NULL && *secondary_error_msg != '\0') {
3024 /* We have both primary and secondary messages. */
3025 cmdarg_err_cont("%s", secondary_error_msg);
3031 /* capture child detected an capture filter related error */
3032 static void
3033 capture_input_cfilter_error(capture_session *cap_session, unsigned i, const char *error_message)
3035 capture_options *capture_opts = cap_session->capture_opts;
3036 dfilter_t *rfcode = NULL;
3037 interface_options *interface_opts;
3039 ws_assert(i < capture_opts->ifaces->len);
3040 interface_opts = &g_array_index(capture_opts->ifaces, interface_options, i);
3042 if (dfilter_compile(interface_opts->cfilter, &rfcode, NULL) && rfcode != NULL) {
3043 cmdarg_err(
3044 "Invalid capture filter \"%s\" for interface '%s'.\n"
3045 "\n"
3046 "That string looks like a valid display filter; however, it isn't a valid\n"
3047 "capture filter (%s).\n"
3048 "\n"
3049 "Note that display filters and capture filters don't have the same syntax,\n"
3050 "so you can't use most display filter expressions as capture filters.\n"
3051 "\n"
3052 "See the User's Guide for a description of the capture filter syntax.",
3053 interface_opts->cfilter, interface_opts->descr, error_message);
3054 dfilter_free(rfcode);
3055 } else {
3056 cmdarg_err(
3057 "Invalid capture filter \"%s\" for interface '%s'.\n"
3058 "\n"
3059 "That string isn't a valid capture filter (%s).\n"
3060 "See the User's Guide for a description of the capture filter syntax.",
3061 interface_opts->cfilter, interface_opts->descr, error_message);
3066 /* capture child tells us we have a new (or the first) capture file */
3067 static bool
3068 capture_input_new_file(capture_session *cap_session, char *new_file)
3070 capture_options *capture_opts = cap_session->capture_opts;
3071 capture_file *cf = cap_session->cf;
3072 bool is_tempfile;
3073 int err;
3075 if (really_quiet == false) {
3076 if (cap_session->state == CAPTURE_PREPARING) {
3077 ws_info("Capture started.");
3079 ws_info("File: \"%s\"", new_file);
3082 ws_assert(cap_session->state == CAPTURE_PREPARING || cap_session->state == CAPTURE_RUNNING);
3084 /* free the old filename */
3085 if (capture_opts->save_file != NULL) {
3087 /* we start a new capture file, close the old one (if we had one before) */
3088 if (cf->state != FILE_CLOSED) {
3089 cf_close(cf);
3092 g_free(capture_opts->save_file);
3093 is_tempfile = false;
3095 epan_free(cf->epan);
3096 cf->epan = tshark_epan_new(cf);
3097 } else {
3098 /* we didn't had a save_file before, must be a tempfile */
3099 is_tempfile = true;
3102 /* save the new filename */
3103 capture_opts->save_file = g_strdup(new_file);
3105 /* if we are in real-time mode, open the new file now */
3106 if (do_dissection) {
3107 /* this is probably unnecessary, but better safe than sorry */
3108 cap_session->cf->open_type = WTAP_TYPE_AUTO;
3109 /* Attempt to open the capture file and set up to read from it. */
3110 switch(cf_open(cap_session->cf, capture_opts->save_file, WTAP_TYPE_AUTO, is_tempfile, &err)) {
3111 case CF_OK:
3112 break;
3113 case CF_ERROR:
3114 /* Don't unlink (delete) the save file - leave it around,
3115 for debugging purposes. */
3116 g_free(capture_opts->save_file);
3117 capture_opts->save_file = NULL;
3118 return false;
3120 } else if (quiet && is_tempfile) {
3121 cf->state = FILE_READ_ABORTED;
3122 cf->filename = g_strdup(new_file);
3123 cf->is_tempfile = is_tempfile;
3126 cap_session->state = CAPTURE_RUNNING;
3128 return true;
3132 /* capture child tells us we have new packets to read */
3133 static void
3134 capture_input_new_packets(capture_session *cap_session, int to_read)
3136 bool ret;
3137 int err;
3138 char *err_info;
3139 int64_t data_offset;
3140 capture_file *cf = cap_session->cf;
3141 bool filtering_tap_listeners;
3142 unsigned tap_flags;
3144 #ifdef SIGINFO
3146 * Prevent a SIGINFO handler from writing to the standard error while
3147 * we're doing so or writing to the standard output; instead, have it
3148 * just set a flag telling us to print that information when we're done.
3150 infodelay = true;
3151 #endif /* SIGINFO */
3153 /* Do we have any tap listeners with filters? */
3154 filtering_tap_listeners = have_filtering_tap_listeners();
3156 /* Get the union of the flags for all tap listeners. */
3157 tap_flags = union_of_tap_listener_flags();
3159 if (do_dissection) {
3160 bool create_proto_tree;
3161 epan_dissect_t *edt;
3162 wtap_rec rec;
3163 Buffer buf;
3166 * Determine whether we need to create a protocol tree.
3167 * We do if:
3169 * we're going to apply a read filter;
3171 * we're going to apply a display filter;
3173 * we're going to print the protocol tree;
3175 * one of the tap listeners is going to apply a filter;
3177 * one of the tap listeners requires a protocol tree;
3179 * a postdissector wants field values or protocols
3180 * on the first pass;
3182 * we have custom columns (which require field values, which
3183 * currently requires that we build a protocol tree).
3185 create_proto_tree =
3186 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
3187 (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
3188 have_custom_cols(&cf->cinfo) || dissect_color);
3190 /* The protocol tree will be "visible", i.e., nothing faked, only if
3191 we're printing packet details, which is true if we're printing stuff
3192 ("print_packet_info" is true) and we're in verbose mode
3193 ("packet_details" is true). But if we specified certain fields with
3194 "-e", we'll prime those directly later. */
3195 bool visible = print_packet_info && print_details && output_fields_num_fields(output_fields) == 0;
3196 edt = epan_dissect_new(cf->epan, create_proto_tree, visible);
3198 wtap_rec_init(&rec);
3199 ws_buffer_init(&buf, 1514);
3201 while (to_read-- && cf->provider.wth) {
3202 wtap_cleareof(cf->provider.wth);
3203 ret = wtap_read(cf->provider.wth, &rec, &buf, &err, &err_info, &data_offset);
3204 reset_epan_mem(cf, edt, create_proto_tree, print_packet_info && print_details);
3205 if (ret == false) {
3206 /* read from file failed, tell the capture child to stop */
3207 sync_pipe_stop(cap_session);
3208 wtap_close(cf->provider.wth);
3209 cf->provider.wth = NULL;
3210 } else {
3211 ret = process_packet_single_pass(cf, edt, data_offset, &rec, &buf,
3212 tap_flags);
3214 if (ret != false) {
3215 /* packet successfully read and gone through the "Read Filter" */
3216 packet_count++;
3218 wtap_rec_reset(&rec);
3221 epan_dissect_free(edt);
3223 wtap_rec_cleanup(&rec);
3224 ws_buffer_free(&buf);
3226 } else {
3228 * Dumpcap's doing all the work; we're not doing any dissection.
3229 * Count all the packets it wrote.
3231 packet_count += to_read;
3234 if (print_packet_counts) {
3235 /* We're printing packet counts. */
3236 if (packet_count != 0) {
3237 fprintf(stderr, "\r%u ", packet_count);
3238 /* stderr could be line buffered */
3239 fflush(stderr);
3243 #ifdef SIGINFO
3245 * Allow SIGINFO handlers to write.
3247 infodelay = false;
3250 * If a SIGINFO handler asked us to write out capture counts, do so.
3252 if (infoprint)
3253 report_counts();
3254 #endif /* SIGINFO */
3257 static void
3258 report_counts(void)
3260 if ((print_packet_counts == false) && (really_quiet == false)) {
3261 /* Report the count only if we aren't printing a packet count
3262 as packets arrive. */
3263 fprintf(stderr, "%u packet%s captured\n", packet_count,
3264 plurality(packet_count, "", "s"));
3266 #ifdef SIGINFO
3267 infoprint = false; /* we just reported it */
3268 #endif /* SIGINFO */
3271 #ifdef SIGINFO
3272 static void
3273 report_counts_siginfo(int signum _U_)
3275 int sav_errno = errno;
3276 /* If we've been told to delay printing, just set a flag asking
3277 that we print counts (if we're supposed to), otherwise print
3278 the count of packets captured (if we're supposed to). */
3279 if (infodelay)
3280 infoprint = true;
3281 else
3282 report_counts();
3283 errno = sav_errno;
3285 #endif /* SIGINFO */
3288 /* capture child detected any packet drops? */
3289 static void
3290 capture_input_drops(capture_session *cap_session _U_, uint32_t dropped, const char* interface_name)
3292 if (print_packet_counts) {
3293 /* We're printing packet counts to stderr.
3294 Send a newline so that we move to the line after the packet count. */
3295 fprintf(stderr, "\n");
3298 if (dropped != 0) {
3299 /* We're printing packet counts to stderr.
3300 Send a newline so that we move to the line after the packet count. */
3301 if (interface_name != NULL) {
3302 fprintf(stderr, "%u packet%s dropped from %s\n", dropped, plurality(dropped, "", "s"), interface_name);
3303 } else {
3304 fprintf(stderr, "%u packet%s dropped\n", dropped, plurality(dropped, "", "s"));
3311 * Capture child closed its side of the pipe, report any error and
3312 * do the required cleanup.
3314 static void
3315 capture_input_closed(capture_session *cap_session _U_, char *msg)
3317 if (msg != NULL && *msg != '\0')
3318 fprintf(stderr, "tshark: %s\n", msg);
3320 report_counts();
3322 loop_running = false;
3325 #ifdef _WIN32
3326 static BOOL WINAPI
3327 capture_cleanup(DWORD ctrltype _U_)
3329 /* CTRL_C_EVENT is sort of like SIGINT, CTRL_BREAK_EVENT is unique to
3330 Windows, CTRL_CLOSE_EVENT is sort of like SIGHUP, CTRL_LOGOFF_EVENT
3331 is also sort of like SIGHUP, and CTRL_SHUTDOWN_EVENT is sort of
3332 like SIGTERM at least when the machine's shutting down.
3334 For now, we handle them all as indications that we should clean up
3335 and quit, just as we handle SIGINT, SIGHUP, and SIGTERM in that
3336 way on UNIX.
3338 We must return true so that no other handler - such as one that would
3339 terminate the process - gets called.
3341 XXX - for some reason, typing ^C to TShark, if you run this in
3342 a Cygwin console window in at least some versions of Cygwin,
3343 causes TShark to terminate immediately; this routine gets
3344 called, but the main loop doesn't get a chance to run and
3345 exit cleanly, at least if this is compiled with Microsoft Visual
3346 C++ (i.e., it's a property of the Cygwin console window or Bash;
3347 it happens if TShark is not built with Cygwin - for all I know,
3348 building it with Cygwin may make the problem go away). */
3350 /* tell the capture child to stop */
3351 sync_pipe_stop(&global_capture_session);
3353 /* don't stop our own loop already here, otherwise status messages and
3354 * cleanup wouldn't be done properly. The child will indicate the stop of
3355 * everything by calling capture_input_closed() later */
3357 return true;
3359 #else
3360 static void
3361 capture_cleanup(int signum _U_)
3363 /* tell the capture child to stop */
3364 sync_pipe_stop(&global_capture_session);
3366 /* don't stop our own loop already here, otherwise status messages and
3367 * cleanup wouldn't be done properly. The child will indicate the stop of
3368 * everything by calling capture_input_closed() later */
3370 #endif /* _WIN32 */
3371 #endif /* HAVE_LIBPCAP */
3373 static bool
3374 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
3375 int64_t offset, wtap_rec *rec, Buffer *buf)
3377 frame_data fdlocal;
3378 uint32_t framenum;
3379 bool passed;
3380 int64_t elapsed_start;
3382 /* The frame number of this packet is one more than the count of
3383 frames in this packet. */
3384 framenum = cf->count + 1;
3386 /* If we're not running a display filter and we're not printing any
3387 packet information, we don't need to do a dissection. This means
3388 that all packets can be marked as 'passed'. */
3389 passed = true;
3391 frame_data_init(&fdlocal, framenum, rec, offset, cum_bytes);
3393 /* If we're going to run a read filter or a display filter, set up to
3394 do a dissection and do so. (This is the first pass of two passes
3395 over the packets, so we will not be printing any information
3396 from the dissection or running taps on the packet; if we're doing
3397 any of that, we'll do it in the second pass.) */
3398 if (edt) {
3399 if (gbl_resolv_flags.network_name || gbl_resolv_flags.maxmind_geoip) {
3400 /* If we're doing async lookups, send any that are queued and
3401 * retrieve results.
3403 * Ideally we'd force any lookups that need to happen on the second pass
3404 * to be sent asynchronously on this pass so the results would be ready.
3405 * That will happen if they're involved in a filter (because we prime the
3406 * tree below), but not currently for taps, if we're printing packet
3407 * summaries or details, etc.
3409 * XXX - If we're running a read filter that depends on a resolved
3410 * name, we should be doing synchronous lookups in that case. Also
3411 * marking the dependent frames below might not work with a display
3412 * filter that depends on a resolved name.
3414 host_name_lookup_process();
3417 column_info *cinfo = NULL;
3419 /* If we're running a read filter, prime the epan_dissect_t with that
3420 filter. */
3421 if (cf->rfcode)
3422 epan_dissect_prime_with_dfilter(edt, cf->rfcode);
3424 if (cf->dfcode)
3425 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
3427 /* This is the first pass, so prime the epan_dissect_t with the
3428 hfids postdissectors want on the first pass. */
3429 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
3431 frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
3432 &cf->provider.ref, cf->provider.prev_dis);
3433 if (cf->provider.ref == &fdlocal) {
3434 ref_frame = fdlocal;
3435 cf->provider.ref = &ref_frame;
3438 /* If we're applying a filter that needs the columns, construct them. */
3439 if (dfilter_requires_columns(cf->rfcode) || dfilter_requires_columns(cf->dfcode)) {
3440 cinfo = &cf->cinfo;
3443 elapsed_start = g_get_monotonic_time();
3444 epan_dissect_run(edt, cf->cd_t, rec,
3445 frame_tvbuff_new_buffer(&cf->provider, &fdlocal, buf),
3446 &fdlocal, cinfo);
3447 tshark_elapsed.first_pass.dissect += g_get_monotonic_time() - elapsed_start;
3449 /* Run the read filter if we have one. */
3450 if (cf->rfcode) {
3451 elapsed_start = g_get_monotonic_time();
3452 passed = dfilter_apply_edt(cf->rfcode, edt);
3453 tshark_elapsed.first_pass.dfilter_read += g_get_monotonic_time() - elapsed_start;
3457 if (passed) {
3458 frame_data_set_after_dissect(&fdlocal, &cum_bytes);
3459 cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
3461 /* If we're not doing dissection then there won't be any dependent frames.
3462 * More importantly, edt.pi.fd.dependent_frames won't be initialized because
3463 * epan hasn't been initialized.
3464 * if we *are* doing dissection, then mark the dependent frames, but only
3465 * if a display filter was given and it matches this packet.
3467 if (edt && cf->dfcode) {
3468 elapsed_start = g_get_monotonic_time();
3469 if (dfilter_apply_edt(cf->dfcode, edt) && edt->pi.fd->dependent_frames) {
3470 g_hash_table_foreach(edt->pi.fd->dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
3473 if (selected_frame_number != 0 && selected_frame_number == cf->count + 1) {
3474 /* If we are doing dissection and we have a "selected frame"
3475 * then load that frame's references (if any) onto the compiled
3476 * display filter. Selected frame number is ordinal, count is cardinal. */
3477 dfilter_load_field_references(cf->dfcode, edt->tree);
3479 tshark_elapsed.first_pass.dfilter_filter += g_get_monotonic_time() - elapsed_start;
3482 cf->count++;
3483 } else {
3484 /* if we don't add it to the frame_data_sequence, clean it up right now
3485 * to avoid leaks */
3486 frame_data_destroy(&fdlocal);
3489 if (edt)
3490 epan_dissect_reset(edt);
3492 return passed;
3496 * Set if reading a file was interrupted by a CTRL_ event on Windows or
3497 * a signal on UN*X.
3499 static bool read_interrupted;
3501 #ifdef _WIN32
3502 static BOOL WINAPI
3503 read_cleanup(DWORD ctrltype _U_)
3505 /* CTRL_C_EVENT is sort of like SIGINT, CTRL_BREAK_EVENT is unique to
3506 Windows, CTRL_CLOSE_EVENT is sort of like SIGHUP, CTRL_LOGOFF_EVENT
3507 is also sort of like SIGHUP, and CTRL_SHUTDOWN_EVENT is sort of
3508 like SIGTERM at least when the machine's shutting down.
3510 For now, we handle them all as indications that we should clean up
3511 and quit, just as we handle SIGINT, SIGHUP, and SIGTERM in that
3512 way on UNIX.
3514 We must return true so that no other handler - such as one that would
3515 terminate the process - gets called.
3517 XXX - for some reason, typing ^C to TShark, if you run this in
3518 a Cygwin console window in at least some versions of Cygwin,
3519 causes TShark to terminate immediately; this routine gets
3520 called, but the main loop doesn't get a chance to run and
3521 exit cleanly, at least if this is compiled with Microsoft Visual
3522 C++ (i.e., it's a property of the Cygwin console window or Bash;
3523 it happens if TShark is not built with Cygwin - for all I know,
3524 building it with Cygwin may make the problem go away). */
3526 /* tell the read to stop */
3527 read_interrupted = true;
3529 return true;
3531 #else
3532 static void
3533 read_cleanup(int signum _U_)
3535 /* tell the read to stop */
3536 read_interrupted = true;
3538 #endif /* _WIN32 */
3540 typedef enum {
3541 PASS_SUCCEEDED,
3542 PASS_READ_ERROR,
3543 PASS_WRITE_ERROR,
3544 PASS_INTERRUPTED
3545 } pass_status_t;
3547 static pass_status_t
3548 process_cap_file_first_pass(capture_file *cf, int max_packet_count,
3549 int64_t max_byte_count, int *err, char **err_info)
3551 wtap_rec rec;
3552 Buffer buf;
3553 epan_dissect_t *edt = NULL;
3554 int64_t data_offset;
3555 pass_status_t status = PASS_SUCCEEDED;
3556 int framenum = 0;
3558 wtap_rec_init(&rec);
3559 ws_buffer_init(&buf, 1514);
3561 /* Allocate a frame_data_sequence for all the frames. */
3562 cf->provider.frames = new_frame_data_sequence();
3564 if (do_dissection) {
3565 bool create_proto_tree;
3568 * Determine whether we need to create a protocol tree.
3569 * We do if:
3571 * we're going to apply a read filter;
3573 * we're going to apply a display filter;
3575 * a postdissector wants field values or protocols
3576 * on the first pass.
3578 create_proto_tree =
3579 (cf->rfcode != NULL || cf->dfcode != NULL || postdissectors_want_hfids() || dissect_color);
3581 ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
3583 /* We're not going to display the protocol tree on this pass,
3584 so it's not going to be "visible". */
3585 edt = epan_dissect_new(cf->epan, create_proto_tree, false);
3588 ws_debug("tshark: reading records for first pass");
3589 *err = 0;
3590 while (wtap_read(cf->provider.wth, &rec, &buf, err, err_info, &data_offset)) {
3591 if (read_interrupted) {
3592 status = PASS_INTERRUPTED;
3593 break;
3595 framenum++;
3597 if (process_packet_first_pass(cf, edt, data_offset, &rec, &buf)) {
3598 /* Stop reading if we hit a stop condition */
3599 if (max_packet_count > 0 && framenum >= max_packet_count) {
3600 ws_debug("tshark: max_packet_count (%d) reached", max_packet_count);
3601 *err = 0; /* This is not an error */
3602 break;
3604 if (max_byte_count != 0 && data_offset >= max_byte_count) {
3605 ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached",
3606 data_offset, max_byte_count);
3607 *err = 0; /* This is not an error */
3608 break;
3611 wtap_rec_reset(&rec);
3613 if (*err != 0)
3614 status = PASS_READ_ERROR;
3616 if (edt)
3617 epan_dissect_free(edt);
3619 /* Close the sequential I/O side, to free up memory it requires. */
3620 wtap_sequential_close(cf->provider.wth);
3622 /* Allow the protocol dissectors to free up memory that they
3623 * don't need after the sequential run-through of the packets. */
3624 postseq_cleanup_all_protocols();
3626 cf->provider.prev_dis = NULL;
3627 cf->provider.prev_cap = NULL;
3629 ws_buffer_free(&buf);
3630 wtap_rec_cleanup(&rec);
3632 return status;
3635 static bool
3636 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
3637 frame_data *fdata, wtap_rec *rec,
3638 Buffer *buf, unsigned tap_flags _U_)
3640 column_info *cinfo;
3641 bool passed;
3642 wtap_block_t block = NULL;
3643 int64_t elapsed_start;
3645 /* If we're not running a display filter and we're not printing any
3646 packet information, we don't need to do a dissection. This means
3647 that all packets can be marked as 'passed'. */
3648 passed = true;
3650 /* If we're going to print packet information, or we're going to
3651 run a read filter, or we're going to process taps, set up to
3652 do a dissection and do so. (This is the second pass of two
3653 passes over the packets; that's the pass where we print
3654 packet information or run taps.) */
3655 if (edt) {
3656 /* If we're running a display filter, prime the epan_dissect_t with that
3657 filter. */
3658 if (cf->dfcode)
3659 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
3661 col_custom_prime_edt(edt, &cf->cinfo);
3663 output_fields_prime_edt(edt, output_fields);
3664 /* The PDML spec requires a 'geninfo' pseudo-protocol that needs
3665 * information from our 'frame' protocol.
3667 if (output_fields_num_fields(output_fields) != 0 &&
3668 output_action == WRITE_XML) {
3669 epan_dissect_prime_with_hfid(edt, proto_registrar_get_id_byname("frame"));
3672 /* We only need the columns if either
3673 1) some tap or filter needs the columns
3675 2) we're printing packet info but we're *not* verbose; in verbose
3676 mode, we print the protocol tree, not the protocol summary.
3678 3) there is a column mapped to an individual field
3680 if ((tap_listeners_require_columns()) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields) || dfilter_requires_columns(cf->dfcode))
3681 cinfo = &cf->cinfo;
3682 else
3683 cinfo = NULL;
3685 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
3686 &cf->provider.ref, cf->provider.prev_dis);
3687 if (cf->provider.ref == fdata) {
3688 ref_frame = *fdata;
3689 cf->provider.ref = &ref_frame;
3692 if (dissect_color) {
3693 color_filters_prime_edt(edt);
3694 fdata->need_colorize = 1;
3697 /* epan_dissect_run (and epan_dissect_reset) unref the block.
3698 * We need it later, e.g. in order to copy the options. */
3699 block = wtap_block_ref(rec->block);
3700 elapsed_start = g_get_monotonic_time();
3701 epan_dissect_run_with_taps(edt, cf->cd_t, rec,
3702 frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
3703 fdata, cinfo);
3704 tshark_elapsed.second_pass.dissect += g_get_monotonic_time() - elapsed_start;
3706 /* Run the display filter if we have one. */
3707 if (cf->dfcode) {
3708 elapsed_start = g_get_monotonic_time();
3709 passed = dfilter_apply_edt(cf->dfcode, edt);
3710 tshark_elapsed.second_pass.dfilter_filter += g_get_monotonic_time() - elapsed_start;
3714 if (passed) {
3715 frame_data_set_after_dissect(fdata, &cum_bytes);
3716 /* Process this packet. */
3717 if (print_packet_info) {
3718 /* We're printing packet information; print the information for
3719 this packet. */
3720 print_packet(cf, edt);
3722 /* If we're doing "line-buffering", flush the standard output
3723 after every packet. See the comment above, for the "-l"
3724 option, for an explanation of why we do that. */
3725 if (line_buffered)
3726 fflush(stdout);
3728 if (ferror(stdout)) {
3729 show_print_file_io_error();
3730 exit(2);
3733 cf->provider.prev_dis = fdata;
3735 cf->provider.prev_cap = fdata;
3737 if (edt) {
3738 epan_dissect_reset(edt);
3739 rec->block = block;
3741 return passed || fdata->dependent_of_displayed;
3744 static bool
3745 process_new_idbs(wtap *wth, wtap_dumper *pdh, int *err, char **err_info)
3747 wtap_block_t if_data;
3749 while ((if_data = wtap_get_next_interface_description(wth)) != NULL) {
3751 * Only add interface blocks if the output file supports (meaning
3752 * *requires*) them.
3754 * That mean that the abstract interface provided by libwiretap
3755 * involves WTAP_BLOCK_IF_ID_AND_INFO blocks.
3757 if (pdh != NULL) {
3758 if (wtap_file_type_subtype_supports_block(wtap_dump_file_type_subtype(pdh), WTAP_BLOCK_IF_ID_AND_INFO) != BLOCK_NOT_SUPPORTED) {
3759 if (!wtap_dump_add_idb(pdh, if_data, err, err_info))
3760 return false;
3764 return true;
3767 static pass_status_t
3768 process_cap_file_second_pass(capture_file *cf, wtap_dumper *pdh,
3769 int *err, char **err_info,
3770 volatile uint32_t *err_framenum,
3771 int max_write_packet_count)
3773 wtap_rec rec;
3774 Buffer buf;
3775 int framenum = 0;
3776 int write_framenum = 0;
3777 frame_data *fdata;
3778 bool filtering_tap_listeners;
3779 unsigned tap_flags;
3780 epan_dissect_t *edt = NULL;
3781 pass_status_t status = PASS_SUCCEEDED;
3784 * Process whatever IDBs we haven't seen yet. This will be all
3785 * the IDBs in the file, as we've finished reading it; they'll
3786 * all be at the beginning of the output file.
3788 if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
3789 *err_framenum = 0;
3790 return PASS_WRITE_ERROR;
3793 wtap_rec_init(&rec);
3794 ws_buffer_init(&buf, 1514);
3796 /* Do we have any tap listeners with filters? */
3797 filtering_tap_listeners = have_filtering_tap_listeners();
3799 /* Get the union of the flags for all tap listeners. */
3800 tap_flags = union_of_tap_listener_flags();
3802 if (do_dissection) {
3803 bool create_proto_tree;
3806 * Determine whether we need to create a protocol tree.
3807 * We do if:
3809 * we're going to apply a display filter;
3811 * we're going to print the protocol tree;
3813 * one of the tap listeners requires a protocol tree;
3815 * we have custom columns (which require field values, which
3816 * currently requires that we build a protocol tree).
3818 create_proto_tree =
3819 (cf->dfcode || print_details || filtering_tap_listeners ||
3820 (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo) || dissect_color);
3822 ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
3824 /* The protocol tree will be "visible", i.e., nothing faked, only if
3825 we're printing packet details, which is true if we're printing stuff
3826 ("print_packet_info" is true) and we're in verbose mode
3827 ("packet_details" is true). But if we specified certain fields with
3828 "-e", we'll prime those directly later. */
3829 bool visible = print_packet_info && print_details && output_fields_num_fields(output_fields) == 0;
3830 edt = epan_dissect_new(cf->epan, create_proto_tree, visible);
3834 * Force synchronous resolution of IP addresses; in this pass, we
3835 * can't do it in the background and fix up past dissections.
3837 set_resolution_synchrony(true);
3839 for (framenum = 1; framenum <= (int)cf->count; framenum++) {
3840 if (read_interrupted) {
3841 status = PASS_INTERRUPTED;
3842 break;
3844 fdata = frame_data_sequence_find(cf->provider.frames, framenum);
3845 if (!wtap_seek_read(cf->provider.wth, fdata->file_off, &rec, &buf, err,
3846 err_info)) {
3847 /* Error reading from the input file. */
3848 status = PASS_READ_ERROR;
3849 break;
3851 ws_debug("tshark: invoking process_packet_second_pass() for frame #%d", framenum);
3852 if (process_packet_second_pass(cf, edt, fdata, &rec, &buf, tap_flags)) {
3853 /* Either there's no read filtering or this packet passed the
3854 filter, so, if we're writing to a capture file, write
3855 this packet out. */
3856 write_framenum++;
3857 if (pdh != NULL) {
3858 ws_debug("tshark: writing packet #%d to outfile packet #%d", framenum, write_framenum);
3859 if (!wtap_dump(pdh, &rec, ws_buffer_start_ptr(&buf), err, err_info)) {
3860 /* Error writing to the output file. */
3861 ws_debug("tshark: error writing to a capture file (%d)", *err);
3862 *err_framenum = framenum;
3863 status = PASS_WRITE_ERROR;
3864 break;
3866 /* Stop reading if we hit a stop condition */
3867 if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) {
3868 ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count);
3869 *err = 0; /* This is not an error */
3870 break;
3874 wtap_rec_reset(&rec);
3877 if (edt)
3878 epan_dissect_free(edt);
3880 ws_buffer_free(&buf);
3881 wtap_rec_cleanup(&rec);
3883 return status;
3886 static pass_status_t
3887 process_cap_file_single_pass(capture_file *cf, wtap_dumper *pdh,
3888 int max_packet_count, int64_t max_byte_count,
3889 int max_write_packet_count,
3890 int *err, char **err_info,
3891 volatile uint32_t *err_framenum)
3893 wtap_rec rec;
3894 Buffer buf;
3895 bool create_proto_tree = false;
3896 bool filtering_tap_listeners;
3897 unsigned tap_flags;
3898 int framenum = 0;
3899 int write_framenum = 0;
3900 epan_dissect_t *edt = NULL;
3901 int64_t data_offset;
3902 pass_status_t status = PASS_SUCCEEDED;
3904 wtap_rec_init(&rec);
3905 ws_buffer_init(&buf, 1514);
3907 /* Do we have any tap listeners with filters? */
3908 filtering_tap_listeners = have_filtering_tap_listeners();
3910 /* Get the union of the flags for all tap listeners. */
3911 tap_flags = union_of_tap_listener_flags();
3913 if (do_dissection) {
3915 * Determine whether we need to create a protocol tree.
3916 * We do if:
3918 * we're going to apply a read filter;
3920 * we're going to apply a display filter;
3922 * we're going to print the protocol tree;
3924 * one of the tap listeners is going to apply a filter;
3926 * one of the tap listeners requires a protocol tree;
3928 * a postdissector wants field values or protocols
3929 * on the first pass;
3931 * we have custom columns (which require field values, which
3932 * currently requires that we build a protocol tree).
3934 create_proto_tree =
3935 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
3936 (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
3937 have_custom_cols(&cf->cinfo) || dissect_color);
3939 ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
3941 /* The protocol tree will be "visible", i.e., nothing faked, only if
3942 we're printing packet details, which is true if we're printing stuff
3943 ("print_packet_info" is true) and we're in verbose mode
3944 ("packet_details" is true). But if we specified certain fields with
3945 "-e", we'll prime those directly later. */
3946 bool visible = print_packet_info && print_details && output_fields_num_fields(output_fields) == 0;
3947 edt = epan_dissect_new(cf->epan, create_proto_tree, visible);
3951 * Force synchronous resolution of IP addresses; we're doing only
3952 * one pass, so we can't do it in the background and fix up past
3953 * dissections.
3955 set_resolution_synchrony(true);
3957 *err = 0;
3958 while (wtap_read(cf->provider.wth, &rec, &buf, err, err_info, &data_offset)) {
3959 if (read_interrupted) {
3960 status = PASS_INTERRUPTED;
3961 break;
3963 framenum++;
3966 * Process whatever IDBs we haven't seen yet.
3968 if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
3969 *err_framenum = framenum;
3970 status = PASS_WRITE_ERROR;
3971 break;
3974 ws_debug("tshark: processing packet #%d", framenum);
3976 reset_epan_mem(cf, edt, create_proto_tree, print_packet_info && print_details);
3978 if (process_packet_single_pass(cf, edt, data_offset, &rec, &buf, tap_flags)) {
3979 /* Either there's no read filtering or this packet passed the
3980 filter, so, if we're writing to a capture file, write
3981 this packet out. */
3982 write_framenum++;
3983 if (pdh != NULL) {
3984 ws_debug("tshark: writing packet #%d to outfile as #%d",
3985 framenum, write_framenum);
3986 if (!wtap_dump(pdh, &rec, ws_buffer_start_ptr(&buf), err, err_info)) {
3987 /* Error writing to the output file. */
3988 ws_debug("tshark: error writing to a capture file (%d)", *err);
3989 *err_framenum = framenum;
3990 status = PASS_WRITE_ERROR;
3991 break;
3995 /* Stop reading if we hit a stop condition */
3996 if (max_packet_count > 0 && framenum >= max_packet_count) {
3997 ws_debug("tshark: max_packet_count (%d) reached", max_packet_count);
3998 *err = 0; /* This is not an error */
3999 break;
4001 if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) {
4002 ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count);
4003 *err = 0; /* This is not an error */
4004 break;
4006 if (max_byte_count != 0 && data_offset >= max_byte_count) {
4007 ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached",
4008 data_offset, max_byte_count);
4009 *err = 0; /* This is not an error */
4010 break;
4012 wtap_rec_reset(&rec);
4014 if (status == PASS_SUCCEEDED) {
4015 if (*err != 0) {
4016 /* Error reading from the input file. */
4017 status = PASS_READ_ERROR;
4018 } else {
4020 * Process whatever IDBs we haven't seen yet.
4022 if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
4023 *err_framenum = framenum;
4024 status = PASS_WRITE_ERROR;
4029 if (edt)
4030 epan_dissect_free(edt);
4032 ws_buffer_free(&buf);
4033 wtap_rec_cleanup(&rec);
4035 return status;
4038 static process_file_status_t
4039 process_cap_file(capture_file *cf, char *save_file, int out_file_type,
4040 bool out_file_name_res, int max_packet_count, int64_t max_byte_count,
4041 int max_write_packet_count, wtap_compression_type compression_type)
4043 process_file_status_t status = PROCESS_FILE_SUCCEEDED;
4044 wtap_dumper *pdh;
4045 #ifndef _WIN32
4046 struct sigaction action, oldaction;
4047 #endif
4048 int err = 0, err_pass1 = 0;
4049 char *err_info = NULL, *err_info_pass1 = NULL;
4050 volatile uint32_t err_framenum;
4051 wtap_dump_params params = WTAP_DUMP_PARAMS_INIT;
4052 char *shb_user_appl;
4053 pass_status_t first_pass_status, second_pass_status;
4054 int64_t elapsed_start;
4056 if (save_file != NULL) {
4057 /* Set up to write to the capture file. */
4058 wtap_dump_params_init_no_idbs(&params, cf->provider.wth);
4060 /* If we don't have an application name add TShark */
4061 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) {
4062 /* this is free'd by wtap_block_unref() later */
4063 wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, "%s", get_appname_and_version());
4065 if (capture_comments != NULL) {
4066 for (unsigned i = 0; i < capture_comments->len; i++) {
4067 wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0),
4068 OPT_COMMENT, "%s",
4069 (char *)g_ptr_array_index(capture_comments, i));
4073 ws_debug("tshark: writing format type %d, to %s", out_file_type, save_file);
4074 if (strcmp(save_file, "-") == 0) {
4075 /* Write to the standard output. */
4076 pdh = wtap_dump_open_stdout(out_file_type, compression_type, &params,
4077 &err, &err_info);
4078 } else {
4079 pdh = wtap_dump_open(save_file, out_file_type, compression_type, &params,
4080 &err, &err_info);
4083 g_free(params.idb_inf);
4084 params.idb_inf = NULL;
4086 if (pdh == NULL) {
4087 /* We couldn't set up to write to the capture file. */
4088 cfile_dump_open_failure_message(save_file, err, err_info,
4089 out_file_type);
4090 status = PROCESS_FILE_NO_FILE_PROCESSED;
4091 goto out;
4093 } else {
4094 /* Set up to print packet information. */
4095 if (print_packet_info) {
4096 if (!write_preamble(cf)) {
4097 show_print_file_io_error();
4098 status = PROCESS_FILE_NO_FILE_PROCESSED;
4099 goto out;
4102 pdh = NULL;
4105 #ifdef _WIN32
4106 /* Catch a CTRL+C event and, if we get it, clean up and exit. */
4107 SetConsoleCtrlHandler(read_cleanup, true);
4108 #else /* _WIN32 */
4109 /* Catch SIGINT and SIGTERM and, if we get either of them,
4110 clean up and exit. If SIGHUP isn't being ignored, catch
4111 it too and, if we get it, clean up and exit.
4113 We restart any read that was in progress, so that it doesn't
4114 disrupt reading from the sync pipe. The signal handler tells
4115 the capture child to finish; it will report that it finished,
4116 or will exit abnormally, so we'll stop reading from the sync
4117 pipe, pick up the exit status, and quit. */
4118 memset(&action, 0, sizeof(action));
4119 action.sa_handler = read_cleanup;
4120 action.sa_flags = SA_RESTART;
4121 sigemptyset(&action.sa_mask);
4122 sigaction(SIGTERM, &action, NULL);
4123 sigaction(SIGINT, &action, NULL);
4124 sigaction(SIGHUP, NULL, &oldaction);
4125 if (oldaction.sa_handler == SIG_DFL)
4126 sigaction(SIGHUP, &action, NULL);
4127 #endif /* _WIN32 */
4129 if (perform_two_pass_analysis) {
4130 ws_debug("tshark: perform_two_pass_analysis, do_dissection=%s", do_dissection ? "TRUE" : "FALSE");
4132 elapsed_start = g_get_monotonic_time();
4133 first_pass_status = process_cap_file_first_pass(cf, max_packet_count,
4134 max_byte_count,
4135 &err_pass1,
4136 &err_info_pass1);
4137 tshark_elapsed.elapsed_first_pass = g_get_monotonic_time() - elapsed_start;
4139 ws_debug("tshark: done with first pass");
4141 if (first_pass_status == PASS_INTERRUPTED) {
4142 /* The first pass was interrupted; skip the second pass.
4143 It won't be run, so it won't get an error. */
4144 second_pass_status = PASS_SUCCEEDED;
4145 } else {
4147 * If we got a read error on the first pass, we still do the second
4148 * pass, so we can at least process the packets we read, and then
4149 * report the first-pass error after the second pass (and before
4150 * we report any second-pass errors), so all the errors show up
4151 * at the end.
4153 elapsed_start = g_get_monotonic_time();
4154 second_pass_status = process_cap_file_second_pass(cf, pdh, &err, &err_info,
4155 &err_framenum,
4156 max_write_packet_count);
4157 tshark_elapsed.elapsed_second_pass = g_get_monotonic_time() - elapsed_start;
4159 ws_debug("tshark: done with second pass");
4162 else {
4163 /* !perform_two_pass_analysis */
4164 ws_debug("tshark: perform one pass analysis, do_dissection=%s", do_dissection ? "TRUE" : "FALSE");
4166 first_pass_status = PASS_SUCCEEDED; /* There is no first pass */
4168 elapsed_start = g_get_monotonic_time();
4169 second_pass_status = process_cap_file_single_pass(cf, pdh,
4170 max_packet_count,
4171 max_byte_count,
4172 max_write_packet_count,
4173 &err, &err_info,
4174 &err_framenum);
4175 tshark_elapsed.elapsed_first_pass = g_get_monotonic_time() - elapsed_start;
4177 ws_debug("tshark: done with single pass");
4180 if (first_pass_status != PASS_SUCCEEDED ||
4181 second_pass_status != PASS_SUCCEEDED) {
4183 * At least one of the passes didn't succeed; either it got a failure
4184 * or it was interrupted.
4186 if (first_pass_status != PASS_INTERRUPTED ||
4187 second_pass_status != PASS_INTERRUPTED) {
4188 /* At least one of the passes got an error. */
4189 ws_debug("tshark: something failed along the line (%d)", err);
4191 * If we're printing packet data, and the standard output and error
4192 * are going to the same place, flush the standard output, so everything
4193 * buffered up is written, and then print a newline to the standard
4194 * error before printing the error message, to separate it from the
4195 * packet data. (Alas, that only works on UN*X; st_dev is meaningless,
4196 * and the _fstat() documentation at Microsoft doesn't indicate whether
4197 * st_ino is even supported.)
4199 #ifndef _WIN32
4200 if (print_packet_info) {
4201 ws_statb64 stat_stdout, stat_stderr;
4203 if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
4204 if (stat_stdout.st_dev == stat_stderr.st_dev &&
4205 stat_stdout.st_ino == stat_stderr.st_ino) {
4206 fflush(stdout);
4207 fprintf(stderr, "\n");
4211 #endif
4213 /* Report status of pass 1 of two-pass processing. */
4214 switch (first_pass_status) {
4216 case PASS_SUCCEEDED:
4217 /* No problem. */
4218 break;
4220 case PASS_READ_ERROR:
4221 /* Read error. */
4222 cfile_read_failure_message(cf->filename, err_pass1, err_info_pass1);
4223 status = PROCESS_FILE_ERROR;
4224 break;
4226 case PASS_WRITE_ERROR:
4227 /* Won't happen on the first pass. */
4228 break;
4230 case PASS_INTERRUPTED:
4231 /* Not an error, so nothing to report. */
4232 status = PROCESS_FILE_INTERRUPTED;
4233 break;
4236 /* Report status of pass 2 of two-pass processing or the only pass
4237 of one-pass processing. */
4238 switch (second_pass_status) {
4240 case PASS_SUCCEEDED:
4241 /* No problem. */
4242 break;
4244 case PASS_READ_ERROR:
4245 /* Read error. */
4246 cfile_read_failure_message(cf->filename, err, err_info);
4247 status = PROCESS_FILE_ERROR;
4248 break;
4250 case PASS_WRITE_ERROR:
4251 /* Write error.
4252 XXX - framenum is not necessarily the frame number in
4253 the input file if there was a read filter. */
4254 cfile_write_failure_message(cf->filename, save_file, err, err_info,
4255 err_framenum, out_file_type);
4256 status = PROCESS_FILE_ERROR;
4257 break;
4259 case PASS_INTERRUPTED:
4260 /* Not an error, so nothing to report. */
4261 status = PROCESS_FILE_INTERRUPTED;
4262 break;
4265 if (save_file != NULL) {
4266 if (second_pass_status != PASS_WRITE_ERROR) {
4267 if (pdh && out_file_name_res) {
4268 /* XXX: This doesn't work as expected. First, it should be
4269 * moved to between the first and second passes (if doing
4270 * two-pass mode), so that the new NRB appears before packets,
4271 * which is better for subsequent one-pass mode. It never works
4272 * well in one-pass mode.
4274 * Second, it only writes hosts that we've done lookups for,
4275 * which means unless packet details are printed (or there's
4276 * a display filter that matches something that will do a host
4277 * lookup, e.g. -Y "ip") it doesn't actually have anything
4278 * in the list to save. Notably, that includes the case of
4279 * "tshark [-2] -H hosts.txt -r <infile> -w <outfile>",
4280 * which a user would certainly expect to dissect packets,
4281 * lookup hostnames, and add them to an NRB for later use.
4282 * A workaround is if "-V > /dev/null" is added, but who
4283 * expects that?
4285 * A third issue is that name resolution blocks aren't
4286 * written for live captures.
4288 if (!wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list())) {
4289 cmdarg_err("The file format \"%s\" doesn't support name resolution information.",
4290 wtap_file_type_subtype_name(out_file_type));
4293 /* Now close the capture file. */
4294 if (!wtap_dump_close(pdh, NULL, &err, &err_info)) {
4295 cfile_close_failure_message(save_file, err, err_info);
4296 status = PROCESS_FILE_ERROR;
4298 } else {
4299 /* We got a write error; it was reported, so just close the dump file
4300 without bothering to check for further errors. */
4301 wtap_dump_close(pdh, NULL, &err, &err_info);
4302 g_free(err_info);
4303 status = PROCESS_FILE_ERROR;
4305 } else {
4306 if (print_packet_info) {
4307 if (!write_finale()) {
4308 show_print_file_io_error();
4309 status = PROCESS_FILE_ERROR;
4314 out:
4315 wtap_close(cf->provider.wth);
4316 cf->provider.wth = NULL;
4318 wtap_dump_params_cleanup(&params);
4320 return status;
4323 static bool
4324 process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, int64_t offset,
4325 wtap_rec *rec, Buffer *buf, unsigned tap_flags _U_)
4327 frame_data fdata;
4328 column_info *cinfo;
4329 bool passed;
4330 wtap_block_t block = NULL;
4331 int64_t elapsed_start;
4333 /* Count this packet. */
4334 cf->count++;
4336 /* If we're not running a display filter and we're not printing any
4337 packet information, we don't need to do a dissection. This means
4338 that all packets can be marked as 'passed'. */
4339 passed = true;
4341 frame_data_init(&fdata, cf->count, rec, offset, cum_bytes);
4343 /* If we're going to print packet information, or we're going to
4344 run a read filter, or we're going to process taps, set up to
4345 do a dissection and do so. (This is the one and only pass
4346 over the packets, so, if we'll be printing packet information
4347 or running taps, we'll be doing it here.) */
4348 if (edt) {
4349 /* If we're running a filter, prime the epan_dissect_t with that
4350 filter. */
4351 if (cf->dfcode)
4352 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
4354 /* This is the first and only pass, so prime the epan_dissect_t
4355 with the hfids postdissectors want on the first pass. */
4356 prime_epan_dissect_with_postdissector_wanted_hfids(edt);
4358 col_custom_prime_edt(edt, &cf->cinfo);
4360 output_fields_prime_edt(edt, output_fields);
4361 /* The PDML spec requires a 'geninfo' pseudo-protocol that needs
4362 * information from our 'frame' protocol.
4364 if (output_fields_num_fields(output_fields) != 0 &&
4365 output_action == WRITE_XML) {
4366 epan_dissect_prime_with_hfid(edt, proto_registrar_get_id_byname("frame"));
4369 /* We only need the columns if either
4370 1) some tap or filter needs the columns
4372 2) we're printing packet info but we're *not* verbose; in verbose
4373 mode, we print the protocol tree, not the protocol summary.
4375 3) there is a column mapped as an individual field */
4376 if ((tap_listeners_require_columns()) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields) || dfilter_requires_columns(cf->dfcode))
4377 cinfo = &cf->cinfo;
4378 else
4379 cinfo = NULL;
4381 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
4382 &cf->provider.ref, cf->provider.prev_dis);
4383 if (cf->provider.ref == &fdata) {
4384 ref_frame = fdata;
4385 cf->provider.ref = &ref_frame;
4388 if (dissect_color) {
4389 color_filters_prime_edt(edt);
4390 fdata.need_colorize = 1;
4393 /* epan_dissect_run (and epan_dissect_reset) unref the block.
4394 * We need it later, e.g. in order to copy the options. */
4395 block = wtap_block_ref(rec->block);
4396 elapsed_start = g_get_monotonic_time();
4397 epan_dissect_run_with_taps(edt, cf->cd_t, rec,
4398 frame_tvbuff_new_buffer(&cf->provider, &fdata, buf),
4399 &fdata, cinfo);
4400 tshark_elapsed.first_pass.dissect += g_get_monotonic_time() - elapsed_start;
4402 /* Run the filter if we have it. */
4403 if (cf->dfcode) {
4404 elapsed_start = g_get_monotonic_time();
4405 passed = dfilter_apply_edt(cf->dfcode, edt);
4406 tshark_elapsed.first_pass.dfilter_filter += g_get_monotonic_time() - elapsed_start;
4410 if (passed) {
4411 frame_data_set_after_dissect(&fdata, &cum_bytes);
4413 /* Process this packet. */
4414 if (print_packet_info) {
4415 /* We're printing packet information; print the information for
4416 this packet. */
4417 ws_assert(edt);
4418 print_packet(cf, edt);
4420 /* If we're doing "line-buffering", flush the standard output
4421 after every packet. See the comment above, for the "-l"
4422 option, for an explanation of why we do that. */
4423 if (line_buffered)
4424 fflush(stdout);
4426 if (ferror(stdout)) {
4427 show_print_file_io_error();
4428 exit(2);
4432 /* this must be set after print_packet() [bug #8160] */
4433 prev_dis_frame = fdata;
4434 cf->provider.prev_dis = &prev_dis_frame;
4437 prev_cap_frame = fdata;
4438 cf->provider.prev_cap = &prev_cap_frame;
4440 if (edt) {
4441 epan_dissect_reset(edt);
4442 frame_data_destroy(&fdata);
4443 rec->block = block;
4445 return passed;
4448 static bool
4449 write_preamble(capture_file *cf)
4451 switch (output_action) {
4453 case WRITE_TEXT:
4454 return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
4456 case WRITE_XML:
4457 if (print_details)
4458 write_pdml_preamble(stdout, cf->filename);
4459 else
4460 write_psml_preamble(&cf->cinfo, stdout);
4461 return !ferror(stdout);
4463 case WRITE_FIELDS:
4464 write_fields_preamble(output_fields, stdout);
4465 return !ferror(stdout);
4467 case WRITE_JSON:
4468 case WRITE_JSON_RAW:
4469 jdumper = write_json_preamble(stdout);
4470 return !ferror(stdout);
4472 case WRITE_EK:
4473 return true;
4475 default:
4476 ws_assert_not_reached();
4477 return false;
4481 static char *
4482 get_line_buf(size_t len)
4484 static char *line_bufp = NULL;
4485 static size_t line_buf_len = 256;
4486 size_t new_line_buf_len;
4488 for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
4489 new_line_buf_len *= 2)
4491 if (line_bufp == NULL) {
4492 line_buf_len = new_line_buf_len;
4493 line_bufp = (char *)g_malloc(line_buf_len + 1);
4494 } else {
4495 if (new_line_buf_len > line_buf_len) {
4496 line_buf_len = new_line_buf_len;
4497 line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
4500 return line_bufp;
4503 static inline void
4504 put_string(char *dest, const char *str, size_t str_len)
4506 memcpy(dest, str, str_len);
4507 dest[str_len] = '\0';
4510 static inline void
4511 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
4513 size_t i;
4515 for (i = str_len; i < str_with_spaces; i++)
4516 *dest++ = ' ';
4518 put_string(dest, str, str_len);
4521 static inline void
4522 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
4524 size_t i;
4526 memcpy(dest, str, str_len);
4527 for (i = str_len; i < str_with_spaces; i++)
4528 dest[i] = ' ';
4530 dest[str_with_spaces] = '\0';
4533 static bool
4534 print_columns(capture_file *cf, const epan_dissect_t *edt)
4536 char *line_bufp;
4537 int i;
4538 size_t buf_offset;
4539 size_t column_len;
4540 size_t col_len;
4541 col_item_t* col_item;
4542 char str_format[11];
4543 const color_filter_t *color_filter = NULL;
4545 line_bufp = get_line_buf(256);
4546 buf_offset = 0;
4547 *line_bufp = '\0';
4549 if (dissect_color)
4550 color_filter = edt->pi.fd->color_filter;
4552 for (i = 0; i < cf->cinfo.num_cols; i++) {
4553 col_item = &cf->cinfo.columns[i];
4554 /* Skip columns not marked as visible. */
4555 if (!get_column_visible(i))
4556 continue;
4557 const char* col_text = get_column_text(&cf->cinfo, i);
4558 switch (col_item->col_fmt) {
4559 case COL_NUMBER:
4560 case COL_NUMBER_DIS:
4561 column_len = col_len = strlen(col_text);
4562 if (column_len < 5)
4563 column_len = 5;
4564 line_bufp = get_line_buf(buf_offset + column_len);
4565 put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
4566 break;
4568 case COL_CLS_TIME:
4569 case COL_REL_TIME:
4570 case COL_ABS_TIME:
4571 case COL_ABS_YMD_TIME: /* XXX - wider */
4572 case COL_ABS_YDOY_TIME: /* XXX - wider */
4573 case COL_UTC_TIME:
4574 case COL_UTC_YMD_TIME: /* XXX - wider */
4575 case COL_UTC_YDOY_TIME: /* XXX - wider */
4576 column_len = col_len = strlen(col_text);
4577 if (column_len < 10)
4578 column_len = 10;
4579 line_bufp = get_line_buf(buf_offset + column_len);
4580 put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
4581 break;
4583 case COL_DEF_SRC:
4584 case COL_RES_SRC:
4585 case COL_UNRES_SRC:
4586 case COL_DEF_DL_SRC:
4587 case COL_RES_DL_SRC:
4588 case COL_UNRES_DL_SRC:
4589 case COL_DEF_NET_SRC:
4590 case COL_RES_NET_SRC:
4591 case COL_UNRES_NET_SRC:
4592 column_len = col_len = strlen(col_text);
4593 if (column_len < 12)
4594 column_len = 12;
4595 line_bufp = get_line_buf(buf_offset + column_len);
4596 put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
4597 break;
4599 case COL_DEF_DST:
4600 case COL_RES_DST:
4601 case COL_UNRES_DST:
4602 case COL_DEF_DL_DST:
4603 case COL_RES_DL_DST:
4604 case COL_UNRES_DL_DST:
4605 case COL_DEF_NET_DST:
4606 case COL_RES_NET_DST:
4607 case COL_UNRES_NET_DST:
4608 column_len = col_len = strlen(col_text);
4609 if (column_len < 12)
4610 column_len = 12;
4611 line_bufp = get_line_buf(buf_offset + column_len);
4612 put_string_spaces(line_bufp + buf_offset, col_text, col_len, column_len);
4613 break;
4615 default:
4616 column_len = strlen(col_text);
4617 line_bufp = get_line_buf(buf_offset + column_len);
4618 put_string(line_bufp + buf_offset, col_text, column_len);
4619 break;
4621 buf_offset += column_len;
4622 if (i != cf->cinfo.num_cols - 1) {
4624 * This isn't the last column, so we need to print a
4625 * separator between this column and the next.
4627 * If we printed a network source and are printing a
4628 * network destination of the same type next, separate
4629 * them with a UTF-8 right arrow; if we printed a network
4630 * destination and are printing a network source of the same
4631 * type next, separate them with a UTF-8 left arrow;
4632 * otherwise separate them with a space.
4634 * We add enough space to the buffer for " \xe2\x86\x90 "
4635 * or " \xe2\x86\x92 ", even if we're only adding " ".
4637 line_bufp = get_line_buf(buf_offset + 5);
4638 switch (col_item->col_fmt) {
4640 case COL_DEF_SRC:
4641 case COL_RES_SRC:
4642 case COL_UNRES_SRC:
4643 switch (cf->cinfo.columns[i+1].col_fmt) {
4645 case COL_DEF_DST:
4646 case COL_RES_DST:
4647 case COL_UNRES_DST:
4648 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
4649 put_string(line_bufp + buf_offset, str_format, 5);
4650 buf_offset += 5;
4651 break;
4653 default:
4654 put_string(line_bufp + buf_offset, delimiter_char, 1);
4655 buf_offset += 1;
4656 break;
4658 break;
4660 case COL_DEF_DL_SRC:
4661 case COL_RES_DL_SRC:
4662 case COL_UNRES_DL_SRC:
4663 switch (cf->cinfo.columns[i+1].col_fmt) {
4665 case COL_DEF_DL_DST:
4666 case COL_RES_DL_DST:
4667 case COL_UNRES_DL_DST:
4668 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
4669 put_string(line_bufp + buf_offset, str_format, 5);
4670 buf_offset += 5;
4671 break;
4673 default:
4674 put_string(line_bufp + buf_offset, delimiter_char, 1);
4675 buf_offset += 1;
4676 break;
4678 break;
4680 case COL_DEF_NET_SRC:
4681 case COL_RES_NET_SRC:
4682 case COL_UNRES_NET_SRC:
4683 switch (cf->cinfo.columns[i+1].col_fmt) {
4685 case COL_DEF_NET_DST:
4686 case COL_RES_NET_DST:
4687 case COL_UNRES_NET_DST:
4688 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
4689 put_string(line_bufp + buf_offset, str_format, 5);
4690 buf_offset += 5;
4691 break;
4693 default:
4694 put_string(line_bufp + buf_offset, delimiter_char, 1);
4695 buf_offset += 1;
4696 break;
4698 break;
4700 case COL_DEF_DST:
4701 case COL_RES_DST:
4702 case COL_UNRES_DST:
4703 switch (cf->cinfo.columns[i+1].col_fmt) {
4705 case COL_DEF_SRC:
4706 case COL_RES_SRC:
4707 case COL_UNRES_SRC:
4708 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
4709 put_string(line_bufp + buf_offset, str_format, 5);
4710 buf_offset += 5;
4711 break;
4713 default:
4714 put_string(line_bufp + buf_offset, delimiter_char, 1);
4715 buf_offset += 1;
4716 break;
4718 break;
4720 case COL_DEF_DL_DST:
4721 case COL_RES_DL_DST:
4722 case COL_UNRES_DL_DST:
4723 switch (cf->cinfo.columns[i+1].col_fmt) {
4725 case COL_DEF_DL_SRC:
4726 case COL_RES_DL_SRC:
4727 case COL_UNRES_DL_SRC:
4728 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
4729 put_string(line_bufp + buf_offset, str_format, 5);
4730 buf_offset += 5;
4731 break;
4733 default:
4734 put_string(line_bufp + buf_offset, delimiter_char, 1);
4735 buf_offset += 1;
4736 break;
4738 break;
4740 case COL_DEF_NET_DST:
4741 case COL_RES_NET_DST:
4742 case COL_UNRES_NET_DST:
4743 switch (cf->cinfo.columns[i+1].col_fmt) {
4745 case COL_DEF_NET_SRC:
4746 case COL_RES_NET_SRC:
4747 case COL_UNRES_NET_SRC:
4748 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
4749 put_string(line_bufp + buf_offset, str_format, 5);
4750 buf_offset += 5;
4751 break;
4753 default:
4754 put_string(line_bufp + buf_offset, delimiter_char, 1);
4755 buf_offset += 1;
4756 break;
4758 break;
4760 default:
4761 put_string(line_bufp + buf_offset, delimiter_char, 1);
4762 buf_offset += 1;
4763 break;
4768 if (dissect_color && color_filter != NULL)
4769 return print_line_color(print_stream, 0, line_bufp, &color_filter->fg_color, &color_filter->bg_color);
4770 else
4771 return print_line(print_stream, 0, line_bufp);
4774 static bool
4775 print_packet(capture_file *cf, epan_dissect_t *edt)
4777 if (print_summary || output_fields_has_cols(output_fields))
4778 /* Just fill in the columns. */
4779 epan_dissect_fill_in_columns(edt, false, true);
4781 /* Print summary columns and/or protocol tree */
4782 switch (output_action) {
4784 case WRITE_TEXT:
4785 if (print_summary && !print_columns(cf, edt))
4786 return false;
4787 if (print_details) {
4788 if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
4789 print_hex, edt, output_only_tables, print_stream))
4790 return false;
4791 if (!print_hex) {
4792 if (!print_line(print_stream, 0, separator))
4793 return false;
4796 break;
4798 case WRITE_XML:
4799 if (print_summary) {
4800 write_psml_columns(edt, stdout, dissect_color);
4801 return !ferror(stdout);
4803 if (print_details) {
4804 write_pdml_proto_tree(output_fields, edt, &cf->cinfo, stdout, dissect_color);
4805 printf("\n");
4806 return !ferror(stdout);
4808 break;
4810 case WRITE_FIELDS:
4811 if (print_summary) {
4812 /*No non-verbose "fields" format */
4813 ws_assert_not_reached();
4815 if (print_details) {
4816 write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
4817 printf("\n");
4818 return !ferror(stdout);
4820 break;
4822 case WRITE_JSON:
4823 if (print_summary)
4824 ws_assert_not_reached();
4825 if (print_details) {
4826 write_json_proto_tree(output_fields, print_dissections_expanded,
4827 print_hex, edt, &cf->cinfo, node_children_grouper, &jdumper);
4828 return !ferror(stdout);
4830 break;
4832 case WRITE_JSON_RAW:
4833 if (print_summary)
4834 ws_assert_not_reached();
4835 if (print_details) {
4836 write_json_proto_tree(output_fields, print_dissections_none,
4837 true, edt, &cf->cinfo, node_children_grouper, &jdumper);
4838 return !ferror(stdout);
4840 break;
4842 case WRITE_EK:
4843 write_ek_proto_tree(output_fields, print_summary, print_hex,
4844 edt, &cf->cinfo, stdout);
4845 return !ferror(stdout);
4847 default:
4848 ws_assert_not_reached();
4851 if (print_hex) {
4852 if (print_summary || print_details) {
4853 if (!print_line(print_stream, 0, ""))
4854 return false;
4856 if (!print_hex_data(print_stream, edt, hexdump_source_option | hexdump_ascii_option))
4857 return false;
4858 if (!print_line(print_stream, 0, separator))
4859 return false;
4861 return true;
4864 static bool
4865 write_finale(void)
4867 switch (output_action) {
4869 case WRITE_TEXT:
4870 return print_finale(print_stream);
4872 case WRITE_XML:
4873 if (print_details)
4874 write_pdml_finale(stdout);
4875 else
4876 write_psml_finale(stdout);
4877 return !ferror(stdout);
4879 case WRITE_FIELDS:
4880 write_fields_finale(output_fields, stdout);
4881 return !ferror(stdout);
4883 case WRITE_JSON:
4884 case WRITE_JSON_RAW:
4885 write_json_finale(&jdumper);
4886 return !ferror(stdout);
4888 case WRITE_EK:
4889 return true;
4891 default:
4892 ws_assert_not_reached();
4893 return false;
4897 void
4898 cf_close(capture_file *cf)
4900 if (cf->state == FILE_CLOSED)
4901 return; /* Nothing to do */
4903 if (cf->provider.wth != NULL) {
4904 wtap_close(cf->provider.wth);
4905 cf->provider.wth = NULL;
4907 /* We have no file open... */
4908 if (cf->filename != NULL) {
4909 /* If it's a temporary file, remove it. */
4910 if (cf->is_tempfile)
4911 ws_unlink(cf->filename);
4912 g_free(cf->filename);
4913 cf->filename = NULL;
4916 /* We have no file open. */
4917 cf->state = FILE_CLOSED;
4920 cf_status_t
4921 cf_open(capture_file *cf, const char *fname, unsigned int type, bool is_tempfile, int *err)
4923 wtap *wth;
4924 char *err_info;
4926 wth = wtap_open_offline(fname, type, err, &err_info, perform_two_pass_analysis);
4927 if (wth == NULL)
4928 goto fail;
4930 /* The open succeeded. Fill in the information for this file. */
4932 cf->provider.wth = wth;
4933 cf->f_datalen = 0; /* not used, but set it anyway */
4935 /* Set the file name because we need it to set the follow stream filter.
4936 XXX - is that still true? We need it for other reasons, though,
4937 in any case. */
4938 cf->filename = g_strdup(fname);
4940 /* Indicate whether it's a permanent or temporary file. */
4941 cf->is_tempfile = is_tempfile;
4943 /* No user changes yet. */
4944 cf->unsaved_changes = false;
4946 cf->cd_t = wtap_file_type_subtype(cf->provider.wth);
4947 cf->open_type = type;
4948 cf->count = 0;
4949 cf->drops_known = false;
4950 cf->drops = 0;
4951 cf->snap = wtap_snapshot_length(cf->provider.wth);
4952 nstime_set_zero(&cf->elapsed_time);
4953 cf->provider.ref = NULL;
4954 cf->provider.prev_dis = NULL;
4955 cf->provider.prev_cap = NULL;
4957 cf->state = FILE_READ_IN_PROGRESS;
4959 /* Create new epan session for dissection. */
4960 epan_free(cf->epan);
4961 cf->epan = tshark_epan_new(cf);
4963 wtap_set_cb_new_ipv4(cf->provider.wth, add_ipv4_name);
4964 wtap_set_cb_new_ipv6(cf->provider.wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
4965 wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
4967 return CF_OK;
4969 fail:
4970 cfile_open_failure_message(fname, *err, err_info);
4971 return CF_ERROR;
4974 static void
4975 show_print_file_io_error(void)
4977 switch (errno) {
4979 case ENOSPC:
4980 cmdarg_err("Not all the packets could be printed because there is "
4981 "no space left on the file system.");
4982 break;
4984 #ifdef EDQUOT
4985 case EDQUOT:
4986 cmdarg_err("Not all the packets could be printed because you are "
4987 "too close to, or over your disk quota.");
4988 break;
4989 #endif
4991 case EPIPE:
4993 * This almost certainly means "the next program after us in
4994 * the pipeline exited before we were finished writing", so
4995 * this isn't a real error, it just means we're done. (We
4996 * don't get SIGPIPE because libwireshark ignores SIGPIPE
4997 * to avoid getting killed if writing to the MaxMind process
4998 * gets SIGPIPE because that process died.)
5000 * Presumably either that program exited deliberately (for
5001 * example, "head -N" read N lines and printed them), in
5002 * which case there's no error to report, or it terminated
5003 * due to an error or a signal, in which case *that's* the
5004 * error and that error has been reported.
5006 break;
5008 default:
5009 #ifdef _WIN32
5010 if (errno == EINVAL && _doserrno == ERROR_NO_DATA) {
5012 * XXX - on Windows, a write to a pipe where the read side
5013 * has been closed apparently may return the Windows error
5014 * ERROR_BROKEN_PIPE, which the Visual Studio C library maps
5015 * to EPIPE, or may return the Windows error ERROR_NO_DATA,
5016 * which the Visual Studio C library maps to EINVAL.
5018 * Either of those almost certainly means "the next program
5019 * after us in the pipeline exited before we were finished
5020 * writing", so, if _doserrno is ERROR_NO_DATA, this isn't
5021 * a real error, it just means we're done. (Windows doesn't
5022 * SIGPIPE.)
5024 * Presumably either that program exited deliberately (for
5025 * example, "head -N" read N lines and printed them), in
5026 * which case there's no error to report, or it terminated
5027 * due to an error or a signal, in which case *that's* the
5028 * error and that error has been reported.
5030 break;
5034 * It's a different error; report it, but with the error
5035 * message for _doserrno, which will give more detail
5036 * than just "Invalid argument".
5038 cmdarg_err("An error occurred while printing packets: %s.",
5039 win32strerror(_doserrno));
5040 #else
5041 cmdarg_err("An error occurred while printing packets: %s.",
5042 g_strerror(errno));
5043 #endif
5044 break;
5049 * Report an error in command-line arguments.
5051 static void
5052 tshark_cmdarg_err(const char *msg_format, va_list ap)
5054 fprintf(stderr, "tshark: ");
5055 vfprintf(stderr, msg_format, ap);
5056 fprintf(stderr, "\n");
5060 * Report additional information for an error in command-line arguments.
5062 static void
5063 tshark_cmdarg_err_cont(const char *msg_format, va_list ap)
5065 vfprintf(stderr, msg_format, ap);
5066 fprintf(stderr, "\n");
5069 static void
5070 reset_epan_mem(capture_file *cf,epan_dissect_t *edt, bool tree, bool visual)
5072 if (!epan_auto_reset || (cf->count < epan_auto_reset_count))
5073 return;
5075 fprintf(stderr, "resetting session.\n");
5077 epan_dissect_cleanup(edt);
5078 epan_free(cf->epan);
5080 cf->epan = tshark_epan_new(cf);
5081 epan_dissect_init(edt, cf->epan, tree, visual);
5082 cf->count = 0;