Bug Summary

File:builds/wireshark/wireshark/tshark.c
Warning:line 3281, column 21
Value stored to 'ret' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name tshark.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2026-02-12-100355-3623-1 -x c /builds/wireshark/wireshark/tshark.c
1/* tshark.c
2 *
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>.
5 *
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13#include <config.h>
14
15#define WS_LOG_DOMAIN"Main" LOG_DOMAIN_MAIN"Main"
16
17#include <stdlib.h>
18#include <stdio.h>
19#include <string.h>
20#include <locale.h>
21#include <limits.h>
22
23#include <wsutil/ws_getopt.h>
24
25#include <errno(*__errno_location ()).h>
26
27#ifdef _WIN32
28# include <winsock2.h>
29#endif
30
31#ifndef _WIN32
32#include <signal.h>
33#endif
34
35#include <glib.h>
36
37#include <epan/exceptions.h>
38#include <epan/epan.h>
39
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 <wsutil/report_message.h>
54#include <app/application_flavor.h>
55#include <wsutil/path_config.h>
56#include <cli_main.h>
57#include <wsutil/version_info.h>
58#include <wiretap/wtap_opttypes.h>
59
60#include "globals.h"
61#include <epan/timestamp.h>
62#include <epan/packet.h>
63#ifdef HAVE_LUA1
64#include <epan/wslua/init_wslua.h>
65#endif
66#include <epan/disabled_protos.h>
67#include <epan/prefs.h>
68#include <epan/column.h>
69#include <epan/decode_as.h>
70#include <epan/print.h>
71#include <epan/addr_resolv.h>
72#include <epan/iana-info.h>
73#include <epan/manuf.h>
74#include <epan/secrets.h>
75#ifdef HAVE_LIBPCAP1
76#include "ui/capture_ui_utils.h"
77#endif
78#include "ui/taps.h"
79#include "ui/util.h"
80#include "ui/ws_ui_util.h"
81#include "ui/decode_as_utils.h"
82#include "wsutil/filter_files.h"
83#include "ui/cli/tshark-tap.h"
84#include "ui/cli/tap-exportobject.h"
85#include "ui/tap_export_pdu.h"
86#include "ui/dissect_opts.h"
87#include "ui/failure_message.h"
88#include "ui/capture_opts.h"
89#if defined(HAVE_LIBSMI1)
90#include "epan/oids.h"
91#endif
92#include "epan/maxmind_db.h"
93#include <epan/epan_dissect.h>
94#include <epan/tap.h>
95#include <epan/stat_tap_ui.h>
96#include <epan/conversation_table.h>
97#include <epan/srt_table.h>
98#include <epan/rtd_table.h>
99#include <epan/ex-opt.h>
100#include <epan/exported_pdu.h>
101#include <epan/secrets.h>
102
103#include "capture/capture-pcap-util.h"
104
105#ifdef HAVE_LIBPCAP1
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>
115
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
123
124#include "extcap.h"
125
126#ifdef HAVE_PLUGINS1
127#include <wsutil/codecs.h>
128#include <wsutil/plugins.h>
129#endif
130
131/* Additional exit codes */
132#define INVALID_EXPORT2 2
133#define INVALID_TAP2 2
134#define INVALID_CAPTURE2 2
135
136#define LONGOPT_EXPORT_OBJECTS3000 +1 LONGOPT_BASE_APPLICATION3000+1
137#define LONGOPT_COLOR3000 +2 LONGOPT_BASE_APPLICATION3000+2
138#define LONGOPT_NO_DUPLICATE_KEYS3000 +3 LONGOPT_BASE_APPLICATION3000+3
139#define LONGOPT_ELASTIC_MAPPING_FILTER3000 +4 LONGOPT_BASE_APPLICATION3000+4
140#define LONGOPT_EXPORT_TLS_SESSION_KEYS3000 +5 LONGOPT_BASE_APPLICATION3000+5
141#define LONGOPT_CAPTURE_COMMENT3000 +6 LONGOPT_BASE_APPLICATION3000+6
142#define LONGOPT_HEXDUMP3000 +7 LONGOPT_BASE_APPLICATION3000+7
143#define LONGOPT_SELECTED_FRAME3000 +8 LONGOPT_BASE_APPLICATION3000+8
144#define LONGOPT_PRINT_TIMERS3000 +9 LONGOPT_BASE_APPLICATION3000+9
145#define LONGOPT_GLOBAL_PROFILE3000 +10 LONGOPT_BASE_APPLICATION3000+10
146#define LONGOPT_COMPRESS3000 +11 LONGOPT_BASE_APPLICATION3000+11
147
148capture_file cfile;
149
150static uint32_t cum_bytes;
151static frame_data ref_frame;
152static frame_data prev_dis_frame;
153static frame_data prev_cap_frame;
154
155static bool_Bool perform_two_pass_analysis;
156static uint32_t epan_auto_reset_count;
157static bool_Bool epan_auto_reset;
158
159static uint32_t selected_frame_number;
160
161/*
162 * The way the packet decode is to be written.
163 */
164typedef 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;
174
175static output_action_e output_action;
176static bool_Bool do_dissection; /* true if we have to dissect each packet */
177static bool_Bool print_packet_info; /* true if we're to print packet information */
178static bool_Bool print_summary; /* true if we're to print packet summary information */
179static bool_Bool print_details; /* true if we're to print packet details information */
180static bool_Bool print_hex; /* true if we're to print hex/ascii information */
181static bool_Bool line_buffered;
182static bool_Bool quiet;
183static bool_Bool really_quiet;
184static char* delimiter_char = " ";
185static bool_Bool dissect_color;
186static unsigned hexdump_source_option = HEXDUMP_SOURCE_MULTI(0x0000U); /* Default - Enable legacy multi-source mode */
187static unsigned hexdump_ascii_option = HEXDUMP_ASCII_INCLUDE(0x0000U); /* Default - Enable legacy undelimited ASCII dump */
188static unsigned hexdump_timestamp_option = HEXDUMP_TIMESTAMP_NONE(0x0000U); /* Default - no timestamp preamble */
189
190static print_format_e print_format = PR_FMT_TEXT;
191static print_stream_t *print_stream;
192
193static char *output_file_name;
194
195static output_fields_t* output_fields;
196
197static bool_Bool no_duplicate_keys;
198static proto_node_children_grouper_func node_children_grouper = proto_node_group_children_by_unique;
199
200static json_dumper jdumper;
201
202/* The line separator used between packets, changeable via the -S option */
203static const char *separator = "";
204
205/* Per-file comments to be added to the output file. */
206static GPtrArray *capture_comments;
207
208static bool_Bool prefs_loaded;
209
210#ifdef HAVE_LIBPCAP1
211/*
212 * true if we're to print packet counts to keep track of captured packets.
213 */
214static bool_Bool print_packet_counts;
215
216static capture_options global_capture_opts;
217static capture_session global_capture_session;
218static info_data_t global_info_data;
219
220#ifdef SIGINFO
221static bool_Bool infodelay; /* if true, don't print capture info in SIGINFO handler */
222static bool_Bool infoprint; /* if true, print capture info after clearing infodelay */
223#endif /* SIGINFO */
224
225static bool_Bool capture(void);
226static bool_Bool capture_input_new_file(capture_session *cap_session,
227 char *new_file);
228static void capture_input_new_packets(capture_session *cap_session,
229 int to_read);
230static void capture_input_drops(capture_session *cap_session, uint32_t dropped,
231 const char* interface_name);
232static void capture_input_error(capture_session *cap_session,
233 char *error_msg, char *secondary_error_msg);
234static void capture_input_cfilter_error(capture_session *cap_session,
235 unsigned i, const char *error_message);
236static void capture_input_closed(capture_session *cap_session, char *msg);
237
238static void report_counts(void);
239#ifdef _WIN32
240static BOOL WINAPI capture_cleanup(DWORD);
241#else /* _WIN32 */
242static void capture_cleanup(int);
243#ifdef SIGINFO
244static void report_counts_siginfo(int);
245#endif /* SIGINFO */
246#endif /* _WIN32 */
247#endif /* HAVE_LIBPCAP */
248
249static void reset_epan_mem(capture_file *cf, epan_dissect_t *edt, bool_Bool tree, bool_Bool visual);
250
251typedef enum {
252 PROCESS_FILE_SUCCEEDED,
253 PROCESS_FILE_NO_FILE_PROCESSED,
254 PROCESS_FILE_ERROR,
255 PROCESS_FILE_INTERRUPTED
256} process_file_status_t;
257static process_file_status_t process_cap_file(capture_file *, char *, int, bool_Bool, int, int64_t, int, ws_compression_type);
258
259typedef enum {
260 PROCESS_PACKET_PASSED,
261 PROCESS_PACKET_DIDNT_PASS,
262 PROCESS_PACKET_PRINT_ERROR
263} process_packet_status_t;
264static process_packet_status_t process_packet_single_pass(capture_file *cf,
265 epan_dissect_t *edt, int64_t offset, wtap_rec *rec, unsigned tap_flags);
266static void show_print_file_io_error(void);
267static bool_Bool write_preamble(capture_file *cf);
268static bool_Bool print_packet(capture_file *cf, epan_dissect_t *edt);
269static bool_Bool write_finale(void);
270
271static GHashTable *output_only_tables;
272
273static bool_Bool opt_print_timers;
274struct elapsed_pass_s {
275 int64_t dissect;
276 int64_t dfilter_read;
277 int64_t dfilter_filter;
278};
279static struct {
280 int64_t dfilter_expand;
281 int64_t dfilter_compile;
282 struct elapsed_pass_s first_pass;
283 int64_t elapsed_first_pass;
284 struct elapsed_pass_s second_pass;
285 int64_t elapsed_second_pass;
286}
287tshark_elapsed;
288
289static void
290print_elapsed_json(const char *cf_name, const char *dfilter)
291{
292 json_dumper dumper = {
293 .output_file = stderrstderr,
294 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
295 };
296
297 if (tshark_elapsed.elapsed_first_pass == 0) {
298 // Should not happen
299 ws_warning("Print timers requested but no timing info provided")do { if (1) { ws_log_full("Main", LOG_LEVEL_WARNING, "tshark.c"
, 299, __func__, "Print timers requested but no timing info provided"
); } } while (0)
;
300 return;
301 }
302
303#define DUMP(name, val)json_dumper_set_member_name(&dumper, name); json_dumper_value_anyf
(&dumper, "%""l" "d", val)
\
304 json_dumper_set_member_name(&dumper, name); \
305 json_dumper_value_anyf(&dumper, "%"PRId64"l" "d", val)
306
307 json_dumper_begin_object(&dumper);
308 json_dumper_set_member_name(&dumper, "version");
309 json_dumper_value_string(&dumper, application_get_vcs_version_info_short());
310 if (cf_name) {
311 json_dumper_set_member_name(&dumper, "path");
312 json_dumper_value_string(&dumper, cf_name);
313 }
314 if (dfilter) {
315 json_dumper_set_member_name(&dumper, "filter");
316 json_dumper_value_string(&dumper, dfilter);
317 }
318 json_dumper_set_member_name(&dumper, "time_unit");
319 json_dumper_value_string(&dumper, "microseconds");
320 DUMP("elapsed", tshark_elapsed.elapsed_first_pass +json_dumper_set_member_name(&dumper, "elapsed"); json_dumper_value_anyf
(&dumper, "%""l" "d", tshark_elapsed.elapsed_first_pass +
tshark_elapsed.elapsed_second_pass)
321 tshark_elapsed.elapsed_second_pass)json_dumper_set_member_name(&dumper, "elapsed"); json_dumper_value_anyf
(&dumper, "%""l" "d", tshark_elapsed.elapsed_first_pass +
tshark_elapsed.elapsed_second_pass)
;
322 DUMP("dfilter_expand", tshark_elapsed.dfilter_expand)json_dumper_set_member_name(&dumper, "dfilter_expand"); json_dumper_value_anyf
(&dumper, "%""l" "d", tshark_elapsed.dfilter_expand)
;
323 DUMP("dfilter_compile", tshark_elapsed.dfilter_compile)json_dumper_set_member_name(&dumper, "dfilter_compile"); json_dumper_value_anyf
(&dumper, "%""l" "d", tshark_elapsed.dfilter_compile)
;
324 json_dumper_begin_array(&dumper);
325 json_dumper_begin_object(&dumper);
326 DUMP("elapsed", tshark_elapsed.elapsed_first_pass)json_dumper_set_member_name(&dumper, "elapsed"); json_dumper_value_anyf
(&dumper, "%""l" "d", tshark_elapsed.elapsed_first_pass)
;
327 DUMP("dissect", tshark_elapsed.first_pass.dissect)json_dumper_set_member_name(&dumper, "dissect"); json_dumper_value_anyf
(&dumper, "%""l" "d", tshark_elapsed.first_pass.dissect)
;
328 DUMP("display_filter", tshark_elapsed.first_pass.dfilter_filter)json_dumper_set_member_name(&dumper, "display_filter"); json_dumper_value_anyf
(&dumper, "%""l" "d", tshark_elapsed.first_pass.dfilter_filter
)
;
329 DUMP("read_filter", tshark_elapsed.first_pass.dfilter_read)json_dumper_set_member_name(&dumper, "read_filter"); json_dumper_value_anyf
(&dumper, "%""l" "d", tshark_elapsed.first_pass.dfilter_read
)
;
330 json_dumper_end_object(&dumper);
331 if (tshark_elapsed.elapsed_second_pass) {
332 json_dumper_begin_object(&dumper);
333 DUMP("elapsed", tshark_elapsed.elapsed_second_pass)json_dumper_set_member_name(&dumper, "elapsed"); json_dumper_value_anyf
(&dumper, "%""l" "d", tshark_elapsed.elapsed_second_pass)
;
334 DUMP("dissect", tshark_elapsed.second_pass.dissect)json_dumper_set_member_name(&dumper, "dissect"); json_dumper_value_anyf
(&dumper, "%""l" "d", tshark_elapsed.second_pass.dissect)
;
335 DUMP("display_filter", tshark_elapsed.second_pass.dfilter_filter)json_dumper_set_member_name(&dumper, "display_filter"); json_dumper_value_anyf
(&dumper, "%""l" "d", tshark_elapsed.second_pass.dfilter_filter
)
;
336 DUMP("read_filter", tshark_elapsed.second_pass.dfilter_read)json_dumper_set_member_name(&dumper, "read_filter"); json_dumper_value_anyf
(&dumper, "%""l" "d", tshark_elapsed.second_pass.dfilter_read
)
;
337 json_dumper_end_object(&dumper);
338 }
339 json_dumper_end_array(&dumper);
340 json_dumper_end_object(&dumper);
341 json_dumper_finish(&dumper);
342}
343
344static void
345list_capture_types(void)
346{
347 GArray *writable_type_subtypes;
348
349 fprintf(stderrstderr, "tshark: The available capture file types for the \"-F\" flag are:\n");
350 writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME);
351 for (unsigned i = 0; i < writable_type_subtypes->len; i++) {
352 int ft = g_array_index(writable_type_subtypes, int, i)(((int*) (void *) (writable_type_subtypes)->data) [(i)]);
353 fprintf(stderrstderr, " %s - %s\n", wtap_file_type_subtype_name(ft),
354 wtap_file_type_subtype_description(ft));
355 }
356 g_array_free(writable_type_subtypes, TRUE(!(0)));
357}
358
359static void
360list_output_compression_types(void) {
361 GSList *output_compression_types;
362
363 cmdarg_err("The available output compression type(s) are:");
364 output_compression_types = ws_get_all_output_compression_type_names_list();
365 for (GSList *compression_type = output_compression_types;
366 compression_type != NULL((void*)0);
367 compression_type = g_slist_next(compression_type)((compression_type) ? (((GSList *)(compression_type))->next
) : ((void*)0))
) {
368 cmdarg_err_cont(" %s", (const char *)compression_type->data);
369 }
370
371 g_slist_free(output_compression_types);
372}
373
374struct string_elem {
375 const char *sstr; /* The short string */
376 const char *lstr; /* The long string */
377};
378
379static int
380string_compare(const void *a, const void *b)
381{
382 return strcmp(((const struct string_elem *)a)->sstr,
383 ((const struct string_elem *)b)->sstr);
384}
385
386static void
387string_elem_print(void *data)
388{
389 fprintf(stderrstderr, " %s - %s\n",
390 ((struct string_elem *)data)->sstr,
391 ((struct string_elem *)data)->lstr);
392}
393
394static void
395list_read_capture_types(void)
396{
397 unsigned i;
398 size_t num_file_types;
399 struct string_elem *captypes;
400 GSList *list = NULL((void*)0);
401 const char *magic = "Magic-value-based";
402 const char *heuristic = "Heuristics-based";
403
404 /* How many readable file types are there? */
405 num_file_types = 0;
406 for (i = 0; open_routines[i].name != NULL((void*)0); i++)
407 num_file_types++;
408 captypes = g_new(struct string_elem, num_file_types)((struct string_elem *) g_malloc_n ((num_file_types), sizeof (
struct string_elem)))
;
409
410 fprintf(stderrstderr, "tshark: The available read file types for the \"-X read_format:\" option are:\n");
411 for (i = 0; i < num_file_types && open_routines[i].name != NULL((void*)0); i++) {
412 captypes[i].sstr = open_routines[i].name;
413 captypes[i].lstr = (open_routines[i].type == OPEN_INFO_MAGIC) ? magic : heuristic;
414 list = g_slist_insert_sorted(list, &captypes[i], string_compare);
415 }
416 g_slist_free_full(list, string_elem_print);
417 g_free(captypes);
418}
419
420static void
421list_export_pdu_taps(void)
422{
423 fprintf(stderrstderr, "tshark: The available export tap names and the encapsulation types they produce for the \"-U tap_name\" option are:\n");
424 for (GSList *export_pdu_tap_name_list = get_export_pdu_tap_list();
425 export_pdu_tap_name_list != NULL((void*)0);
426 export_pdu_tap_name_list = g_slist_next(export_pdu_tap_name_list)((export_pdu_tap_name_list) ? (((GSList *)(export_pdu_tap_name_list
))->next) : ((void*)0))
) {
427 fprintf(stderrstderr, " %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)));
428 }
429}
430
431static void
432print_usage(FILE *output)
433{
434 fprintf(output, "\n");
435 fprintf(output, "Usage: tshark [options] ...\n");
436 fprintf(output, "\n");
437
438#ifdef HAVE_LIBPCAP1
439 fprintf(output, "Capture interface:\n");
440 fprintf(output, " -i <interface>, --interface <interface>\n");
441 fprintf(output, " name or idx of interface (def: first non-loopback)\n");
442 fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
443 fprintf(output, " -s <snaplen>, --snapshot-length <snaplen>\n");
444 fprintf(output, " packet snapshot length (def: appropriate maximum)\n");
445 fprintf(output, " -p, --no-promiscuous-mode\n");
446 fprintf(output, " don't capture in promiscuous mode\n");
447 fprintf(output, " -I, --monitor-mode capture in monitor mode, if available\n");
448 fprintf(output, " -B <buffer size>, --buffer-size <buffer size>\n");
449 fprintf(output, " size of kernel buffer in MiB (def: %dMiB)\n", DEFAULT_CAPTURE_BUFFER_SIZE2);
450 fprintf(output, " -y <link type>, --linktype <link type>\n");
451 fprintf(output, " link layer type (def: first appropriate)\n");
452 fprintf(output, " --time-stamp-type <type> timestamp method for interface\n");
453 fprintf(output, " -D, --list-interfaces print list of interfaces and exit\n");
454 fprintf(output, " -L, --list-data-link-types\n");
455 fprintf(output, " print list of link-layer types of iface and exit\n");
456 fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n");
457 fprintf(output, " --no-optimize do not optimize capture filter\n");
458 fprintf(output, "\n");
459 fprintf(output, "Capture display:\n");
460 fprintf(output, " --update-interval interval between updates with new packets, in milliseconds (def: %dms)\n", DEFAULT_UPDATE_INTERVAL100);
461 fprintf(output, "Capture stop conditions:\n");
462 fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
463 fprintf(output, " -a <autostop cond.> ..., --autostop <autostop cond.> ...\n");
464 fprintf(output, " duration:NUM - stop after NUM seconds\n");
465 fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
466 fprintf(output, " files:NUM - stop after NUM files\n");
467 fprintf(output, " packets:NUM - stop after NUM packets\n");
468 /*fprintf(output, "\n");*/
469 fprintf(output, "Capture output:\n");
470 fprintf(output, " -b <ringbuffer opt.> ..., --ring-buffer <ringbuffer opt.>\n");
471 fprintf(output, " duration:NUM - switch to next file after NUM secs\n");
472 fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
473 fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
474 fprintf(output, " packets:NUM - switch to next file after NUM packets\n");
475 fprintf(output, " interval:NUM - switch to next file when the time is\n");
476 fprintf(output, " an exact multiple of NUM secs\n");
477 fprintf(output, " printname:FILE - print filename to FILE when written\n");
478 fprintf(output, " (can use 'stdout' or 'stderr')\n");
479#endif /* HAVE_LIBPCAP */
480#ifdef HAVE_PCAP_REMOTE
481 fprintf(output, "RPCAP options:\n");
482 fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
483#endif
484 /*fprintf(output, "\n");*/
485 fprintf(output, "Input file:\n");
486 fprintf(output, " -r <infile>, --read-file <infile>\n");
487 fprintf(output, " set the filename to read from (or '-' for stdin)\n");
488
489 fprintf(output, "\n");
490 fprintf(output, "Processing:\n");
491 fprintf(output, " -2 perform a two-pass analysis\n");
492 fprintf(output, " -M <packet count> perform session auto reset\n");
493 fprintf(output, " -R <read filter>, --read-filter <read filter>\n");
494 fprintf(output, " packet Read filter in Wireshark display filter syntax\n");
495 fprintf(output, " (requires -2)\n");
496 fprintf(output, " -Y <display filter>, --display-filter <display filter>\n");
497 fprintf(output, " packet displaY filter in Wireshark display filter\n");
498 fprintf(output, " syntax\n");
499 fprintf(output, " -n disable all name resolutions (def: \"mNd\" enabled, or\n");
500 fprintf(output, " as set in preferences)\n");
501 // Note: the order of the flags here matches the options in the settings dialog e.g. "dsN" only have an effect if "n" is set
502 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mtndsNvg\"\n");
503 fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE"<layer_type>==<selector>,<decode_as_protocol>");
504 fprintf(output, " \"Decode As\", see the man page for details\n");
505 fprintf(output, " Example: tcp.port==8888,http\n");
506 fprintf(output, " -H <hosts file> read a list of entries from a hosts file, which will\n");
507 fprintf(output, " then be written to a capture file. (Implies -W n)\n");
508 fprintf(output, " --enable-protocol <proto_name>\n");
509 fprintf(output, " enable dissection of proto_name\n");
510 fprintf(output, " --disable-protocol <proto_name>\n");
511 fprintf(output, " disable dissection of proto_name\n");
512 fprintf(output, " --only-protocols <protocols>\n");
513 fprintf(output, " Only enable dissection of these protocols, comma\n");
514 fprintf(output, " separated. Disable everything else\n");
515 fprintf(output, " --disable-all-protocols\n");
516 fprintf(output, " Disable dissection of all protocols\n");
517 fprintf(output, " --enable-heuristic <short_name>\n");
518 fprintf(output, " enable dissection of heuristic protocol\n");
519 fprintf(output, " --disable-heuristic <short_name>\n");
520 fprintf(output, " disable dissection of heuristic protocol\n");
521
522 /*fprintf(output, "\n");*/
523 fprintf(output, "Output:\n");
524 fprintf(output, " -w <outfile|-> write packets to a pcapng-format file named \"outfile\"\n");
525 fprintf(output, " (or '-' for stdout). If the output filename has the\n");
526 fprintf(output, " .gz extension, it will be compressed to a gzip archive\n");
527 fprintf(output, " --capture-comment <comment>\n");
528 fprintf(output, " add a capture file comment, if supported\n");
529 fprintf(output, " -C <config profile> start with specified configuration profile\n");
530 fprintf(output, " --global-profile use the global profile instead of personal profile\n");
531 fprintf(output, " -F <output file type> set the output file type; default is pcapng.\n");
532 fprintf(output, " an empty \"-F\" option will list the file types\n");
533 fprintf(output, " -V add output of packet tree (Packet Details)\n");
534 fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
535 fprintf(output, " separated\n");
536 fprintf(output, " -P, --print print packet summary even when writing to a file\n");
537 fprintf(output, " -S <separator> the line separator to print between packets\n");
538 fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
539 fprintf(output, " --hexdump <hexoption> add hexdump, set options for data source and ASCII dump\n");
540 fprintf(output, " all dump all data sources (-x default)\n");
541 fprintf(output, " frames dump only frame data source\n");
542 fprintf(output, " ascii include ASCII dump text (-x default)\n");
543 fprintf(output, " delimit delimit ASCII dump text with '|' characters\n");
544 fprintf(output, " noascii exclude ASCII dump text\n");
545 fprintf(output, " time include frame timestamp preamble\n");
546 fprintf(output, " notime do not include frame timestamp preamble (-x default)\n");
547 fprintf(output, " help display help for --hexdump and exit\n");
548 fprintf(output, " -T pdml|ps|psml|json|jsonraw|ek|tabs|text|fields|?\n");
549 fprintf(output, " format of text output (def: text)\n");
550 fprintf(output, " -j <protocolfilter> protocols layers filter if -T ek|pdml|json selected\n");
551 fprintf(output, " (e.g. \"ip ip.flags text\", filter does not expand child\n");
552 fprintf(output, " nodes, unless child is specified also in the filter)\n");
553 fprintf(output, " -J <protocolfilter> top level protocol filter if -T ek|pdml|json selected\n");
554 fprintf(output, " (e.g. \"http tcp\", filter which expands all child nodes)\n");
555 fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
556 fprintf(output, " _ws.col.info)\n");
557 fprintf(output, " this option can be repeated to print multiple fields\n");
558 fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
559 fprintf(output, " bom=y|n print a UTF-8 BOM\n");
560 fprintf(output, " header=y|n switch headers on and off\n");
561 fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
562 fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
563 fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
564 fprintf(output, " aggregator\n");
565 fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
566 fprintf(output, " -t (a|ad|adoy|d|dd|e|r|rc|u|ud|udoy)[.[N]]|.[N]\n");
567 fprintf(output, " output format of time stamps (def: r: rel. to first)\n");
568 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
569 fprintf(output, " -l flush standard output after each packet\n");
570 fprintf(output, " (implies --update-interval 0)\n");
571 fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
572 fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
573 fprintf(output, " -g enable group read access on the output file(s)\n");
574 fprintf(output, " -W n Save extra information in the file, if supported.\n");
575 fprintf(output, " n = write network address resolution information\n");
576 fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
577 fprintf(output, " -U tap_name PDUs export mode, see the man page for details\n");
578 fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
579 fprintf(output, " --export-objects <protocol>,<destdir>\n");
580 fprintf(output, " save exported objects for a protocol to a directory\n");
581 fprintf(output, " named \"destdir\"\n");
582 fprintf(output, " --export-tls-session-keys <keyfile>\n");
583 fprintf(output, " export TLS Session Keys to a file named \"keyfile\"\n");
584 fprintf(output, " --color color output text similarly to the Wireshark GUI,\n");
585 fprintf(output, " requires a terminal with 24-bit color support\n");
586 fprintf(output, " Also supplies color attributes to pdml and psml formats\n");
587 fprintf(output, " (Note that attributes are nonstandard)\n");
588 fprintf(output, " --no-duplicate-keys If -T json is specified, merge duplicate keys in an object\n");
589 fprintf(output, " into a single key with as value a json array containing all\n");
590 fprintf(output, " values\n");
591 fprintf(output, " --elastic-mapping-filter <protocols> If -G elastic-mapping is specified, put only the\n");
592 fprintf(output, " specified protocols within the mapping file\n");
593 fprintf(output, " --temp-dir <directory> write temporary files to this directory\n");
594 fprintf(output, " (default: %s)\n", g_get_tmp_dir());
595 fprintf(output, " --compress <type> compress the output file using the type compression format\n");
596 fprintf(output, "\n");
597
598 ws_log_print_usage(output);
599 fprintf(output, "\n");
600
601 fprintf(output, "Miscellaneous:\n");
602 fprintf(output, " -h, --help display this help and exit\n");
603 fprintf(output, " -v, --version display version info and exit\n");
604 fprintf(output, " -o <name>:<value> ... override preference setting\n");
605 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
606 fprintf(output, " -G [report] dump one of several available reports and exit\n");
607 fprintf(output, " default report=\"fields\"\n");
608 fprintf(output, " use \"-G help\" for more help\n");
609#ifdef __linux__1
610 fprintf(output, "\n");
611 fprintf(output, "Dumpcap can benefit from an enabled BPF JIT compiler if available.\n");
612 fprintf(output, "You might want to enable it by executing:\n");
613 fprintf(output, " \"echo 1 > /proc/sys/net/core/bpf_jit_enable\"\n");
614 fprintf(output, "Note that this can make your system less secure!\n");
615#endif
616
617}
618
619static void
620glossary_option_help(void)
621{
622 FILE *output;
623
624 output = stdoutstdout;
625
626 fprintf(output, "%s\n", get_appname_and_version());
627
628 fprintf(output, "\n");
629 fprintf(output, "Usage: tshark -G <report>\n");
630 fprintf(output, "\n");
631 fprintf(output, "Glossary table reports:\n");
632 fprintf(output, " -G column-formats dump column format codes and exit\n");
633 fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
634 fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
635 fprintf(output, " -G dissectors dump registered dissector names\n");
636 fprintf(output, " -G elastic-mapping dump ElasticSearch mapping file\n");
637 fprintf(output, " -G enterprises dump IANA Private Enterprise Number (PEN) table\n");
638 fprintf(output, " -G fieldcount dump count of header fields and exit\n");
639 fprintf(output, " -G fields,[prefix] dump fields glossary and exit\n");
640 fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
641 fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
642 fprintf(output, " -G manuf dump ethernet manufacturer tables\n");
643 fprintf(output, " -G plugins dump installed plugins and exit\n");
644 fprintf(output, " -G protocols dump protocols in registration database and exit\n");
645 fprintf(output, " -G services dump transport service (port) names\n");
646 fprintf(output, " -G values dump value, range, true/false strings and exit\n");
647 fprintf(output, "\n");
648 fprintf(output, "Preference reports:\n");
649 fprintf(output, " -G currentprefs dump current preferences and exit\n");
650 fprintf(output, " -G defaultprefs dump default preferences and exit\n");
651 fprintf(output, " -G folders dump about:folders\n");
652 fprintf(output, "\n");
653}
654
655static void
656hexdump_option_help(FILE *output)
657{
658 fprintf(output, "%s\n", get_appname_and_version());
659 fprintf(output, "\n");
660 fprintf(output, "tshark: Valid --hexdump <hexoption> values include:\n");
661 fprintf(output, "\n");
662 fprintf(output, "Data source options:\n");
663 fprintf(output, " all add hexdump, dump all data sources (-x default)\n");
664 fprintf(output, " frames add hexdump, dump only frame data source\n");
665 fprintf(output, "\n");
666 fprintf(output, "ASCII options:\n");
667 fprintf(output, " ascii add hexdump, include ASCII dump text (-x default)\n");
668 fprintf(output, " delimit add hexdump, delimit ASCII dump text with '|' characters\n");
669 fprintf(output, " noascii add hexdump, exclude ASCII dump text\n");
670 fprintf(output, "\n");
671 fprintf(output, "Timestamp options:\n");
672 fprintf(output, " time add hexdump, include frame timestamp preamble (uses the format from -t)\n");
673 fprintf(output, " notime add hexdump, do not include frame timestamp preamble (-x default)\n");
674 fprintf(output, "Miscellaneous:\n");
675 fprintf(output, " help display this help and exit\n");
676 fprintf(output, "\n");
677 fprintf(output, "Example:\n");
678 fprintf(output, "\n");
679 fprintf(output, " $ tshark ... --hexdump frames --hexdump delimit ...\n");
680 fprintf(output, "\n");
681}
682
683static void
684print_current_user(void)
685{
686 char *cur_user, *cur_group;
687
688 if (started_with_special_privs()) {
689 cur_user = get_cur_username();
690 cur_group = get_cur_groupname();
691 fprintf(stderrstderr, "Running as user \"%s\" and group \"%s\".",
692 cur_user, cur_group);
693 g_free(cur_user);
694 g_free(cur_group);
695 if (running_with_special_privs()) {
696 fprintf(stderrstderr, " This could be dangerous.");
697 }
698 fprintf(stderrstderr, "\n");
699 }
700}
701
702static void
703gather_tshark_compile_info(feature_list l)
704{
705 /* Capture libraries */
706 gather_caplibs_compile_info(l);
707 epan_gather_compile_info(l);
708}
709
710static void
711gather_tshark_runtime_info(feature_list l)
712{
713#ifdef HAVE_LIBPCAP1
714 gather_caplibs_runtime_info(l);
715#endif
716
717 /* stuff used by libwireshark */
718 epan_gather_runtime_info(l);
719}
720
721static bool_Bool
722_compile_dfilter(const char *text, dfilter_t **dfp, const char *caller)
723{
724 bool_Bool ok;
725 df_error_t *df_err;
726 char *err_off;
727 char *expanded;
728 int64_t elapsed_start;
729
730 elapsed_start = g_get_monotonic_time();
731 expanded = dfilter_expand(text, &df_err);
732 if (expanded == NULL((void*)0)) {
733 cmdarg_err("%s", df_err->msg);
734 df_error_free(&df_err);
735 return false0;
736 }
737 tshark_elapsed.dfilter_expand = g_get_monotonic_time() - elapsed_start;
738
739 elapsed_start = g_get_monotonic_time();
740 ok = dfilter_compile_full(expanded, dfp, &df_err, DF_OPTIMIZE(1U << 2), caller);
741 if (!ok ) {
742 cmdarg_err("%s", df_err->msg);
743
744 if (df_err->loc.col_start >= 0) {
745 err_off = ws_strdup_underline(NULL((void*)0), df_err->loc.col_start, df_err->loc.col_len);
746 cmdarg_err_cont(" %s", expanded);
747 cmdarg_err_cont(" %s", err_off);
748 g_free(err_off);
749 }
750 df_error_free(&df_err);
751 }
752 tshark_elapsed.dfilter_compile = g_get_monotonic_time() - elapsed_start;
753
754 g_free(expanded);
755 return ok;
756}
757
758#define compile_dfilter(text, dfp)_compile_dfilter(text, dfp, __func__) _compile_dfilter(text, dfp, __func__)
759
760static bool_Bool
761protocolfilter_add_opt(const char* arg, pf_flags filter_flags)
762{
763 char **newfilter = NULL((void*)0);
764 for (newfilter = wmem_strsplit(wmem_epan_scope(), arg, " ", -1); *newfilter; newfilter++) {
765 if (strcmp(*newfilter, "") == 0) {
766 /* Don't treat the empty string as an intended field abbreviation
767 * to output, consecutive spaces on the command line probably
768 * aren't intentional.
769 */
770 continue;
771 }
772 if (!output_fields_add_protocolfilter(output_fields, *newfilter, filter_flags)) {
773 cmdarg_err("%s was already specified with different filter flags. Overwriting previous protocol filter.", *newfilter);
774 }
775 }
776 return true1;
777}
778
779static void
780about_folders(void)
781{
782 const char *constpath;
783 char *path;
784 int i;
785 char **resultArray;
786 const char *env_prefix = application_configuration_environment_prefix();
787
788 /* "file open" */
789
790 /*
791 * Fetching the "File" dialogs folder not implemented.
792 * This is arguably just a pwd for a ui/cli .
793 */
794
795 /* temp */
796 constpath = g_get_tmp_dir();
797#ifdef HAVE_LIBPCAP1
798 /* global_capture_opts only exists in this case */
799 if (global_capture_opts.temp_dir)
800 constpath = global_capture_opts.temp_dir;
801#endif
802 printf("%-21s\t%s\n", "Temp:", constpath);
803
804 /* pers conf */
805 path = get_persconffile_path("", false0, env_prefix);
806 printf("%-21s\t%s\n", "Personal configuration:", path);
807 g_free(path);
808
809 /* global conf */
810 constpath = get_datafile_dir(env_prefix);
811 if (constpath != NULL((void*)0)) {
812 printf("%-21s\t%s\n", "Global configuration:", constpath);
813 }
814
815 /* system */
816 constpath = get_systemfile_dir(env_prefix);
817 printf("%-21s\t%s\n", "System:", constpath);
818
819 /* program */
820 constpath = get_progfile_dir();
821 printf("%-21s\t%s\n", "Program:", constpath);
822
823#ifdef HAVE_PLUGINS1
824 /* pers plugins */
825 printf("%-21s\t%s\n", "Personal Plugins:", get_plugins_pers_dir_with_version(env_prefix));
826
827 /* global plugins */
828 printf("%-21s\t%s\n", "Global Plugins:", get_plugins_dir_with_version(env_prefix));
829#endif
830
831#ifdef HAVE_LUA1
832 /* pers lua plugins */
833 printf("%-21s\t%s\n", "Personal Lua Plugins:", get_plugins_pers_dir(env_prefix));
834
835 /* global lua plugins */
836 printf("%-21s\t%s\n", "Global Lua Plugins:", get_plugins_dir(env_prefix));
837#endif
838
839 /* Personal Extcap */
840 constpath = get_extcap_pers_dir(env_prefix);
841
842 resultArray = g_strsplit(constpath, G_SEARCHPATH_SEPARATOR_S":", 10);
843 for(i = 0; resultArray[i]; i++)
844 printf("%-21s\t%s\n", "Personal Extcap path:", g_strstrip(resultArray[i])g_strchomp (g_strchug (resultArray[i])));
845
846 g_strfreev(resultArray);
847
848 /* Global Extcap */
849 constpath = get_extcap_dir(env_prefix, application_extcap_dir());
850
851 resultArray = g_strsplit(constpath, G_SEARCHPATH_SEPARATOR_S":", 10);
852 for(i = 0; resultArray[i]; i++)
853 printf("%-21s\t%s\n", "Global Extcap path:", g_strstrip(resultArray[i])g_strchomp (g_strchug (resultArray[i])));
854
855 g_strfreev(resultArray);
856
857 /* MaxMindDB */
858 path = maxmind_db_get_paths();
859
860 resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S":", 10);
861
862 for(i = 0; resultArray[i]; i++)
863 printf("%-21s\t%s\n", "MaxMind database path:", g_strstrip(resultArray[i])g_strchomp (g_strchug (resultArray[i])));
864
865 g_strfreev(resultArray);
866 g_free(path);
867
868#ifdef HAVE_LIBSMI1
869 /* SMI MIBs/PIBs */
870 path = oid_get_default_mib_path(application_configuration_environment_prefix());
871
872 resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S":", 20);
873
874 for(i = 0; resultArray[i]; i++)
875 printf("%-21s\t%s\n", "MIB/PIB path:", g_strstrip(resultArray[i])g_strchomp (g_strchug (resultArray[i])));
876
877 g_strfreev(resultArray);
878 g_free(path);
879#endif
880
881}
882
883static int
884dump_glossary(const char* glossary, const char* elastic_mapping_filter)
885{
886 int exit_status = EXIT_SUCCESS0;
887 /* If invoked with the "-G" flag, we dump out information based on
888 the argument to the "-G" flag.
889 */
890
891 /* This is now called after the preferences are loaded and all
892 * the command line options are handled, including -o, -d,
893 * --[enable|disable]-[protocol|heuristic].
894 * Some UATs can register new fields (e.g. HTTP/2), so for most
895 * cases load everything.
896 *
897 * prefs_reset() is used for defaultprefs to get the default values.
898 * Note that makes it difficult to use defaultprefs in concert with
899 * any other glossary (we could do it last.)
900 */
901 proto_initialize_all_prefixes();
902
903 if (strcmp(glossary, "column-formats") == 0)
904 column_dump_column_formats();
905 else if (strcmp(glossary, "currentprefs") == 0) {
906 write_prefs(application_configuration_environment_prefix(), NULL((void*)0));
907 }
908 else if (strcmp(glossary, "decodes") == 0) {
909 dissector_dump_decodes();
910 } else if (strcmp(glossary, "defaultprefs") == 0) {
911 prefs_reset(application_configuration_environment_prefix(), application_columns(), application_num_columns());
912 write_prefs(application_configuration_environment_prefix(), NULL((void*)0));
913 } else if (strcmp(glossary, "dissector-tables") == 0)
914 dissector_dump_dissector_tables();
915 else if (strcmp(glossary, "dissectors") == 0)
916 dissector_dump_dissectors();
917 else if (strcmp(glossary, "elastic-mapping") == 0)
918 proto_registrar_dump_elastic(elastic_mapping_filter);
919 else if (strncmp(glossary, "elastic-mapping,", strlen("elastic-mapping,")) == 0) {
920 elastic_mapping_filter = glossary + strlen("elastic-mapping,");
921 proto_registrar_dump_elastic(elastic_mapping_filter);
922 }
923 else if (strcmp(glossary, "fieldcount") == 0) {
924 /* return value for the test suite */
925 exit_status = proto_registrar_dump_fieldcount();
926 }
927 else if (strcmp(glossary, "fields") == 0) {
928 proto_registrar_dump_fields();
929 }
930 else if (strncmp(glossary, "fields,", strlen("fields,")) == 0) {
931 const char* prefix = glossary + strlen("fields,");
932 bool_Bool matched = proto_registrar_dump_field_completions(prefix);
933 if (!matched) {
934 cmdarg_err("No field or protocol begins with \"%s\"", prefix);
935 exit_status = EXIT_FAILURE1;
936 }
937 }
938 else if (strcmp(glossary, "folders") == 0) {
939 about_folders();
940 } else if (strcmp(glossary, "ftypes") == 0)
941 proto_registrar_dump_ftypes();
942 else if (strcmp(glossary, "heuristic-decodes") == 0) {
943 dissector_dump_heur_decodes();
944 } else if (strcmp(glossary, "manuf") == 0)
945 ws_manuf_dump(stdoutstdout);
946 else if (strcmp(glossary, "enterprises") == 0)
947 global_enterprises_dump(stdoutstdout);
948 else if (strcmp(glossary, "services") == 0)
949 global_services_dump(stdoutstdout);
950 else if (strcmp(glossary, "plugins") == 0) {
951#ifdef HAVE_PLUGINS1
952 codecs_init(application_configuration_environment_prefix());
953 plugins_dump_all();
954#endif
955#ifdef HAVE_LUA1
956 wslua_plugins_dump_all();
957#endif
958 extcap_dump_all();
959 }
960 else if (strcmp(glossary, "protocols") == 0) {
961 proto_registrar_dump_protocols();
962 } else if (strcmp(glossary, "values") == 0)
963 proto_registrar_dump_values();
964 else if (strcmp(glossary, "help") == 0)
965 glossary_option_help();
966 /* These are supported only for backwards compatibility and may or may not work
967 * for a given user in a given directory on a given operating system with a given
968 * command-line interpreter.
969 */
970 else if (strcmp(glossary, "?") == 0)
971 glossary_option_help();
972 else if (strcmp(glossary, "-?") == 0)
973 glossary_option_help();
974 else {
975 cmdarg_err("Invalid \"%s\" option for -G flag, enter -G help for more help.", glossary);
976 exit_status = WS_EXIT_INVALID_OPTION1;
977 }
978
979 return exit_status;
980}
981
982static bool_Bool
983must_do_dissection(dfilter_t *rfcode, dfilter_t *dfcode,
984 char *volatile pdu_export_arg)
985{
986 /* We have to dissect each packet if:
987
988 we're printing information about each packet;
989
990 we're using a read filter on the packets;
991
992 we're using a display filter on the packets;
993
994 we're exporting PDUs;
995
996 we're using any taps that need dissection. */
997 return print_packet_info || rfcode || dfcode || pdu_export_arg ||
998 tap_listeners_require_dissection();
999}
1000
1001#ifdef HAVE_LIBPCAP1
1002/*
1003 * Check whether a purported *shark packet-matching expression (display
1004 * or read filter) looks like a capture filter and, if so, print a
1005 * warning.
1006 *
1007 * Used, for example, if the string in question isn't a valid packet-
1008 * matching expression.
1009 */
1010static void
1011warn_about_capture_filter(const char *rfilter)
1012{
1013 struct bpf_program fcode;
1014 pcap_t *pc;
1015
1016 pc = pcap_open_dead(DLT_EN10MB1, MIN_PACKET_SIZE1);
1017 if (pc != NULL((void*)0)) {
1018 if (pcap_compile(pc, &fcode, rfilter, 0, 0) != -1) {
1019 pcap_freecode(&fcode);
1020 cmdarg_err_cont(
1021 " Note: That read filter code looks like a valid capture filter;\n"
1022 " maybe you mixed them up?");
1023 }
1024 pcap_close(pc);
1025 }
1026}
1027#endif
1028
1029#ifdef HAVE_LIBPCAP1
1030static GList *cached_if_list;
1031
1032static GList *
1033capture_opts_get_interface_list(int *err, char **err_str)
1034{
1035 if (cached_if_list == NULL((void*)0)) {
1036 /*
1037 * This isn't a GUI tool, so no need for a callback.
1038 */
1039 cached_if_list = capture_interface_list(global_capture_opts.app_name, err, err_str, NULL((void*)0));
1040 }
1041 /*
1042 * Routines expect to free the returned interface list, so return
1043 * a deep copy.
1044 */
1045 return interface_list_copy(cached_if_list);
1046}
1047#endif
1048
1049int
1050main(int argc, char *argv[])
1051{
1052 char *err_msg;
1053 int opt;
1054 static const struct ws_option long_options[] = {
1055 {"help", ws_no_argument0, NULL((void*)0), 'h'},
1056 {"version", ws_no_argument0, NULL((void*)0), 'v'},
1057 LONGOPT_CAPTURE_COMMON{"autostop", 1, ((void*)0), 'a'}, {"ring-buffer", 1, ((void*)
0), 'b'}, {"buffer-size", 1, ((void*)0), 'B'}, {"list-interfaces"
, 0, ((void*)0), 'D'}, {"list-sources", 0, ((void*)0), 'D'}, {
"interface", 1, ((void*)0), 'i'}, {"source", 1, ((void*)0), 'i'
}, {"monitor-mode", 0, ((void*)0), 'I'}, {"list-data-link-types"
, 0, ((void*)0), 'L'}, {"no-promiscuous-mode", 0, ((void*)0),
'p'}, {"snapshot-length", 1, ((void*)0), 's'}, {"linktype", 1
, ((void*)0), 'y'}, {"list-time-stamp-types", 0, ((void*)0), 1000
+1}, {"no-optimize", 0, ((void*)0), 1000 +6}, {"time-stamp-type"
, 1, ((void*)0), 1000 +2}, {"compress-type", 1, ((void*)0), 1000
+3}, {"temp-dir", 1, ((void*)0), 1000 +4}, {"update-interval"
, 1, ((void*)0), 1000 +5},
1058 LONGOPT_DISSECT_COMMON{"disable-protocol", 1, ((void*)0), 2000 +1 }, {"enable-heuristic"
, 1, ((void*)0), 2000 +2 }, {"disable-heuristic", 1, ((void*)
0), 2000 +3 }, {"enable-protocol", 1, ((void*)0), 2000 +4 }, {
"only-protocols", 1, ((void*)0), 2000 +5 }, {"disable-all-protocols"
, 0, ((void*)0), 2000 +6 }, {"read-filter", 1, ((void*)0), 'R'
}, {"display-filter", 1, ((void*)0), 'Y' },
1059 LONGOPT_READ_CAPTURE_COMMON{"read-file", 1, ((void*)0), 'r' },
1060 LONGOPT_WSLOG{"log-level", 1, ((void*)0), 5000 +1}, {"log-domain", 1, ((void
*)0), 5000 +2}, {"log-domains", 1, ((void*)0), 5000 +2}, {"log-file"
, 1, ((void*)0), 5000 +3}, {"log-fatal", 1, ((void*)0), 5000 +
4}, {"log-fatal-domain", 1, ((void*)0), 5000 +5}, {"log-fatal-domains"
, 1, ((void*)0), 5000 +5}, {"log-debug", 1, ((void*)0), 5000 +
6}, {"log-noisy", 1, ((void*)0), 5000 +7},
1061 {"print", ws_no_argument0, NULL((void*)0), 'P'},
1062 {"export-objects", ws_required_argument1, NULL((void*)0), LONGOPT_EXPORT_OBJECTS3000 +1},
1063 {"export-tls-session-keys", ws_required_argument1, NULL((void*)0), LONGOPT_EXPORT_TLS_SESSION_KEYS3000 +5},
1064 {"color", ws_no_argument0, NULL((void*)0), LONGOPT_COLOR3000 +2},
1065 {"no-duplicate-keys", ws_no_argument0, NULL((void*)0), LONGOPT_NO_DUPLICATE_KEYS3000 +3},
1066 {"elastic-mapping-filter", ws_required_argument1, NULL((void*)0), LONGOPT_ELASTIC_MAPPING_FILTER3000 +4},
1067 {"capture-comment", ws_required_argument1, NULL((void*)0), LONGOPT_CAPTURE_COMMENT3000 +6},
1068 {"hexdump", ws_required_argument1, NULL((void*)0), LONGOPT_HEXDUMP3000 +7},
1069 {"selected-frame", ws_required_argument1, NULL((void*)0), LONGOPT_SELECTED_FRAME3000 +8},
1070 {"print-timers", ws_no_argument0, NULL((void*)0), LONGOPT_PRINT_TIMERS3000 +9},
1071 {"global-profile", ws_no_argument0, NULL((void*)0), LONGOPT_GLOBAL_PROFILE3000 +10},
1072 {"compress", ws_required_argument1, NULL((void*)0), LONGOPT_COMPRESS3000 +11},
1073 {0, 0, 0, 0}
1074 };
1075 bool_Bool arg_error = false0;
1076 bool_Bool has_extcap_options = false0;
1077 volatile bool_Bool is_capturing = true1;
1078
1079 int err;
1080 char *err_info;
1081 bool_Bool exp_pdu_status;
1082 volatile process_file_status_t status;
1083 volatile bool_Bool draw_taps = false0;
1084 volatile int exit_status = EXIT_SUCCESS0;
1085#ifdef HAVE_LIBPCAP1
1086 int caps_queries = 0;
1087 GList *if_list;
1088 char *err_str, *err_str_secondary;
1089#else
1090 bool_Bool capture_option_specified = false0;
1091 int max_packet_count = 0;
1092#endif
1093 volatile int out_file_type = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN-1;
1094 volatile bool_Bool out_file_name_res = false0;
1095 volatile int in_file_type = WTAP_TYPE_AUTO0;
1096 char *volatile cf_name = NULL((void*)0);
1097 char *rfilter = NULL((void*)0);
1098 char *volatile dfilter = NULL((void*)0);
1099 dfilter_t *rfcode = NULL((void*)0);
1100 dfilter_t *dfcode = NULL((void*)0);
1101 e_prefs *prefs_p;
1102 char *output_only = NULL((void*)0);
1103 char *volatile pdu_export_arg = NULL((void*)0);
1104 char *volatile exp_pdu_filename = NULL((void*)0);
1105 const char *volatile tls_session_keys_file = NULL((void*)0);
1106 exp_pdu_t exp_pdu_tap_data;
1107 const char* glossary = NULL((void*)0);
1108 const char* elastic_mapping_filter = NULL((void*)0);
1109 ws_compression_type volatile compression_type = WS_FILE_UNKNOWN_COMPRESSION;
1110 const struct file_extension_info* file_extensions;
1111 unsigned num_extensions;
1112 epan_app_data_t app_data;
1113
1114 /*
1115 * The leading + ensures that getopt_long() does not permute the argv[]
1116 * entries.
1117 *
1118 * We have to make sure that the first getopt_long() preserves the content
1119 * of argv[] for the subsequent getopt_long() call.
1120 *
1121 * We use getopt_long() in both cases to ensure that we're using a routine
1122 * whose permutation behavior we can control in the same fashion on all
1123 * platforms, and so that, if we ever need to process a long argument before
1124 * doing further initialization, we can do so.
1125 *
1126 * Glibc and Solaris libc document that a leading + disables permutation
1127 * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
1128 * and macOS don't document it, but do so anyway.
1129 *
1130 * We do *not* use a leading - because the behavior of a leading - is
1131 * platform-dependent.
1132 */
1133#define OPTSTRING"+2" "a:" "b:" "B:" "c:Df:F:i:" "I" "Lps:y:" "d:K:nN:R:t:u:Y:"
"r:" "M:C:e:E:F:gG:hH:j:J:lo:O:PqQS:T:U:vVw:W:xX:z:"
"+2" OPTSTRING_CAPTURE_COMMON"a:" "b:" "B:" "c:Df:F:i:" "I" "Lps:y:" OPTSTRING_DISSECT_COMMON"d:K:nN:R:t:u:Y:" OPTSTRING_READ_CAPTURE_COMMON"r:" "M:C:e:E:F:gG:hH:j:J:lo:O:PqQS:T:U:vVw:W:xX:z:"
1134
1135 static const char optstring[] = OPTSTRING"+2" "a:" "b:" "B:" "c:Df:F:i:" "I" "Lps:y:" "d:K:nN:R:t:u:Y:"
"r:" "M:C:e:E:F:gG:hH:j:J:lo:O:PqQS:T:U:vVw:W:xX:z:"
;
1136
1137 /* Future proof by zeroing out all data */
1138 memset(&app_data, 0, sizeof(app_data));
1139
1140 /* Set the program name. */
1141 g_set_prgname("tshark");
1142
1143 /*
1144 * Set the C-language locale to the native environment and set the
1145 * code page to UTF-8 on Windows.
1146 */
1147#ifdef _WIN32
1148 setlocale(LC_ALL6, ".UTF-8");
1149#else
1150 setlocale(LC_ALL6, "");
1151#endif
1152
1153 ws_tzset();
1154
1155 cmdarg_err_init(stderr_cmdarg_err, stderr_cmdarg_err_cont);
1156
1157 /* Initialize log handler early so we can have proper logging during startup. */
1158 ws_log_init(vcmdarg_err, "TShark Debug Console");
1159
1160 /* Early logging command-line initialization. */
1161 ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION1);
1162
1163 ws_noisy("Finished log init and parsing command line log arguments")do { if (1) { ws_log_full("Main", LOG_LEVEL_NOISY, "tshark.c"
, 1163, __func__, "Finished log init and parsing command line log arguments"
); } } while (0)
;
1164 ws_debug("tshark started with %d args", argc)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 1164, __func__, "tshark started with %d args", argc); } } while
(0)
;
1165
1166#ifdef _WIN32
1167 create_app_running_mutex();
1168#endif /* _WIN32 */
1169
1170 /*
1171 * Get credential information for later use, and drop privileges
1172 * before doing anything else.
1173 * Let the user know if anything happened.
1174 */
1175 init_process_policies();
1176 relinquish_special_privs_perm();
1177 print_current_user();
1178
1179 /*
1180 * Attempt to get the pathname of the directory containing the
1181 * executable file.
1182 */
1183 err_msg = configuration_init(argv[0], "wireshark");
1184 if (err_msg != NULL((void*)0)) {
1185 fprintf(stderrstderr,
1186 "tshark: Can't get pathname of directory containing the tshark program: %s.\n"
1187 "It won't be possible to capture traffic.\n"
1188 "Report this to the Wireshark developers.",
1189 err_msg);
1190 g_free(err_msg);
1191 }
1192
1193 initialize_funnel_ops();
1194
1195#ifdef _WIN32
1196 ws_init_dll_search_path();
1197#ifdef HAVE_LIBPCAP1
1198 /* Load wpcap if possible. Do this before collecting the run-time version information */
1199 load_wpcap();
1200#endif /* HAVE_LIBPCAP */
1201#endif /* _WIN32 */
1202
1203 /* Initialize the version information. */
1204 ws_init_version_info("TShark", application_flavor_name_proper(), application_get_vcs_version_info,
1205 gather_tshark_compile_info, gather_tshark_runtime_info);
1206
1207 /* Fail sometimes. Useful for testing fuzz scripts. */
1208 /* if (g_random_int_range(0, 100) < 5) abort(); */
1209
1210 /*
1211 * In order to have the -X opts assigned before the wslua machine starts
1212 * we need to call getopt_long before epan_init() gets called.
1213 *
1214 * In order to handle, for example, -o options, we also need to call it
1215 * *after* epan_init() gets called, so that the dissectors have had a
1216 * chance to register their preferences.
1217 *
1218 * Spawning a bunch of extcap processes can delay program startup,
1219 * particularly on Windows. Check to see if we have any options that
1220 * might require extcap and set has_extcap_options = true if that's
1221 * the case.
1222 *
1223 * XXX - can we do this all with one getopt_long() call, saving the
1224 * arguments we can't handle until after initializing libwireshark,
1225 * and then process them after initializing libwireshark?
1226 *
1227 * We set ws_opterr to 0 so that ws_getopt_long doesn't print error
1228 * messages for bad long options. We'll do that once, in the final
1229 * call where all the error handling happens.
1230 */
1231 ws_opterr = 0;
1232
1233 /* We should check at first if we should use a global profile before
1234 parsing the profile name
1235 XXX - We could check this in the next ws_getopt_long, and save the
1236 profile name and only apply it after finishing the loop. */
1237 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL((void*)0))) != -1) {
1238 switch (opt) {
1239 case LONGOPT_GLOBAL_PROFILE3000 +10:
1240 set_persconffile_dir(get_datafile_dir(application_configuration_environment_prefix()));
1241 break;
1242 default:
1243 break;
1244 }
1245 }
1246
1247 /*
1248 * Reset the options parser, set ws_optreset to 1 and set ws_optind to 1.
1249 * We still don't want to print error messages, though.
1250 */
1251 ws_optreset = 1;
1252 ws_optind = 1;
1253
1254 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL((void*)0))) != -1) {
1255 switch (opt) {
1256 case 'C': /* Configuration Profile */
1257 if (profile_exists(application_configuration_environment_prefix(), ws_optarg, false0)) {
1258 set_profile_name (ws_optarg);
1259 } else if (profile_exists(application_configuration_environment_prefix(), ws_optarg, true1)) {
1260 char *pf_dir_path, *pf_dir_path2, *pf_filename;
1261 /* Copy from global profile */
1262 if (create_persconffile_profile(application_configuration_environment_prefix(), ws_optarg, &pf_dir_path) == -1) {
1263 cmdarg_err("Can't create directory\n\"%s\":\n%s.",
1264 pf_dir_path, g_strerror(errno(*__errno_location ())));
1265
1266 g_free(pf_dir_path);
1267 exit_status = WS_EXIT_INVALID_FILE3;
1268 goto clean_exit;
1269 }
1270 if (copy_persconffile_profile(application_configuration_environment_prefix(), ws_optarg, ws_optarg, true1, &pf_filename,
1271 &pf_dir_path, &pf_dir_path2) == -1) {
1272 cmdarg_err("Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
1273 pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno(*__errno_location ())));
1274
1275 g_free(pf_filename);
1276 g_free(pf_dir_path);
1277 g_free(pf_dir_path2);
1278 exit_status = WS_EXIT_INVALID_FILE3;
1279 goto clean_exit;
1280 }
1281 set_profile_name (ws_optarg);
1282 } else {
1283 cmdarg_err("Configuration Profile \"%s\" does not exist", ws_optarg);
1284 exit_status = WS_EXIT_INVALID_OPTION1;
1285 goto clean_exit;
1286 }
1287 break;
1288 case 'G':
1289 if (glossary != NULL((void*)0)) {
1290 /* Multiple glossaries are difficult especially due to defaultprefs */
1291 cmdarg_err("Multiple glossary reports (-G) are unsupported");
1292 exit_status = WS_EXIT_INVALID_OPTION1;
1293 goto clean_exit;
1294 } else {
1295 glossary = ws_optarg;
1296 }
1297 if (g_str_has_suffix(ws_optarg, "prefs")(__builtin_constant_p ("prefs")? __extension__ ({ const char *
const __str = (ws_optarg); const char * const __suffix = ("prefs"
); gboolean __result = (0); if (__str == ((void*)0) || __suffix
== ((void*)0)) __result = (g_str_has_suffix) (__str, __suffix
); else { const size_t __str_len = strlen (((__str) + !(__str
))); const size_t __suffix_len = strlen (((__suffix) + !(__suffix
))); if (__str_len >= __suffix_len) __result = memcmp (__str
+ __str_len - __suffix_len, ((__suffix) + !(__suffix)), __suffix_len
) == 0; } __result; }) : (g_str_has_suffix) (ws_optarg, "prefs"
) )
) {
1298 has_extcap_options = true1;
1299 }
1300 is_capturing = false0;
1301 break;
1302 case 'i':
1303 has_extcap_options = true1;
1304 break;
1305 case 'o':
1306 if (g_str_has_prefix(ws_optarg, "extcap.")(__builtin_constant_p ("extcap.")? __extension__ ({ const char
* const __str = (ws_optarg); const char * const __prefix = (
"extcap."); gboolean __result = (0); if (__str == ((void*)0) ||
__prefix == ((void*)0)) __result = (g_str_has_prefix) (__str
, __prefix); else { const size_t __str_len = strlen (((__str)
+ !(__str))); const size_t __prefix_len = strlen (((__prefix
) + !(__prefix))); if (__str_len >= __prefix_len) __result
= memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len
) == 0; } __result; }) : (g_str_has_prefix) (ws_optarg, "extcap."
) )
) {
1307 has_extcap_options = true1;
1308 }
1309 break;
1310 case 'P': /* Print packet summary info even when writing to a file */
1311 print_packet_info = true1;
1312 print_summary = true1;
1313 break;
1314 case 'r': /* Read capture file x */
1315 cf_name = g_strdup(ws_optarg)g_strdup_inline (ws_optarg);
1316 is_capturing = false0;
1317 break;
1318 case 'O': /* Only output these protocols */
1319 output_only = g_strdup(ws_optarg)g_strdup_inline (ws_optarg);
1320 /* FALLTHROUGH */
1321 case 'V': /* Verbose */
1322 print_details = true1;
1323 print_packet_info = true1;
1324 break;
1325 case 'x': /* Print packet data in hex (and ASCII) */
1326 print_hex = true1;
1327 /* The user asked for hex output, so let's ensure they get it,
1328 * even if they're writing to a file.
1329 */
1330 print_packet_info = true1;
1331 break;
1332 case 'X':
1333 ex_opt_add(ws_optarg);
1334 break;
1335 case 'h':
1336 case 'v':
1337 is_capturing = false0;
1338 break;
1339 default:
1340 break;
1341 }
1342 }
1343
1344#ifndef HAVE_LUA1
1345 if (ex_opt_count("lua_script") > 0) {
1346 cmdarg_err("This version of TShark was not built with support for Lua scripting.");
1347 exit_status = WS_EXIT_INIT_FAILED8;
1348 goto clean_exit;
1349 }
1350#endif /* HAVE_LUA */
1351
1352 init_report_failure_message("TShark");
1353
1354#ifdef HAVE_LIBPCAP1
1355 capture_opts_init(&global_capture_opts, application_flavor_name_lower(), capture_opts_get_interface_list);
1356 capture_session_init(&global_capture_session, &cfile,
1357 capture_input_new_file, capture_input_new_packets,
1358 capture_input_drops, capture_input_error,
1359 capture_input_cfilter_error, capture_input_closed);
1360#endif
1361
1362 timestamp_set_type(TS_RELATIVE);
1363 timestamp_set_precision(TS_PREC_AUTO);
1364 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
1365
1366 /*
1367 * Libwiretap must be initialized before libwireshark is, so that
1368 * dissection-time handlers for file-type-dependent blocks can
1369 * register using the file type/subtype value for the file type.
1370 */
1371 application_file_extensions(&file_extensions, &num_extensions);
1372 wtap_init(true1, application_configuration_environment_prefix(), file_extensions, num_extensions);
1373
1374 /* Register all dissectors; we must do this before checking for the
1375 "-G" flag, as the "-G" flag dumps information registered by the
1376 dissectors, and we must do it before we read the preferences, in
1377 case any dissectors register preferences. */
1378 app_data.env_var_prefix = application_configuration_environment_prefix();
1379 app_data.col_fmt = application_columns();
1380 app_data.num_cols = application_num_columns();
1381 app_data.register_func = register_all_protocols;
1382 app_data.handoff_func = register_all_protocol_handoffs;
1383 app_data.tap_reg_listeners = tap_reg_listener;
1384 if (!epan_init(NULL((void*)0), NULL((void*)0), true1, &app_data)) {
1385 exit_status = WS_EXIT_INIT_FAILED8;
1386 goto clean_exit;
1387 }
1388
1389 /* Register extcap preferences only when needed. */
1390 if (has_extcap_options || is_capturing) {
1391 /*
1392 * XXX - We don't properly handle the capture_no_extcap preference.
1393 * To make it work, before registering the extcap preferences we'd
1394 * have to read at least that preference for the chosen profile, and
1395 * also check to make sure an "-o" option didn't override it.
1396 * Then, after registering the extcap preferences, we'd have to
1397 * set the extcap preferences from the preferences file and "-o"
1398 * options on the command line.
1399 */
1400 extcap_register_preferences();
1401 }
1402
1403 conversation_table_set_gui_info(init_iousers);
1404 endpoint_table_set_gui_info(init_endpoints);
1405 srt_table_iterate_tables(register_srt_tables, NULL((void*)0));
1406 rtd_table_iterate_tables(register_rtd_tables, NULL((void*)0));
1407 stat_tap_iterate_tables(register_simple_stat_tables, NULL((void*)0));
1408
1409 ws_debug("tshark reading settings")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 1409, __func__, "tshark reading settings"); } } while (0)
;
1410
1411 /* Load libwireshark settings from the current profile. */
1412 prefs_p = epan_load_settings();
1413 prefs_loaded = true1;
1414
1415 cap_file_init(&cfile);
1416
1417 /* Print format defaults to this. */
1418 print_format = PR_FMT_TEXT;
1419 delimiter_char = " ";
1420
1421 output_fields = output_fields_new();
1422
1423 /*
1424 * To reset the options parser, set ws_optreset to 1 and set ws_optind to 1.
1425 *
1426 * Also reset ws_opterr to 1, so that error messages are printed by
1427 * getopt_long().
1428 */
1429 ws_optreset = 1;
1430 ws_optind = 1;
1431 ws_opterr = 1;
1432
1433 /* Now get our args */
1434 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL((void*)0))) != -1) {
1435 switch (opt) {
1436 case '2': /* Perform two-pass analysis */
1437 if(epan_auto_reset){
1438 cmdarg_err("-2 does not support auto session reset.");
1439 arg_error=true1;
1440 }
1441 perform_two_pass_analysis = true1;
1442 break;
1443 case 'M':
1444 if(perform_two_pass_analysis){
1445 cmdarg_err("-M does not support two-pass analysis.");
1446 arg_error=true1;
1447 }
1448 if (!get_uint32(ws_optarg, "epan reset count", &epan_auto_reset_count))
1449 arg_error = true1;
1450
1451 epan_auto_reset = true1;
1452 break;
1453 case 'a': /* autostop criteria */
1454 case 'b': /* Ringbuffer option */
1455 case 'f': /* capture filter */
1456 case 'g': /* enable group read access on file(s) */
1457 case 'i': /* Use interface x */
1458 case LONGOPT_SET_TSTAMP_TYPE1000 +2: /* Set capture timestamp type */
1459 case 'p': /* Don't capture in promiscuous mode */
1460#ifdef HAVE_PCAP_REMOTE
1461 case 'A': /* Authentication */
1462#endif
1463 case 'I': /* Capture in monitor mode, if available */
1464 case 's': /* Set the snapshot (capture) length */
1465 case 'y': /* Set the pcap data link type */
1466 case 'B': /* Buffer size */
1467 case LONGOPT_NO_OPTIMIZE1000 +6: /* Don't optimize capture filter */
1468 case LONGOPT_COMPRESS_TYPE1000 +3: /* compress type */
1469 case LONGOPT_CAPTURE_TMPDIR1000 +4: /* capture temp directory */
1470 case LONGOPT_UPDATE_INTERVAL1000 +5: /* sync pipe update interval */
1471 /* These are options only for packet capture. */
1472#ifdef HAVE_LIBPCAP1
1473 exit_status = capture_opts_add_opt(application_configuration_environment_prefix(), &global_capture_opts, opt, ws_optarg);
1474 if (exit_status != 0) {
1475 goto clean_exit;
1476 }
1477#else
1478 capture_option_specified = true1;
1479 arg_error = true1;
1480#endif
1481 break;
1482 case 'c': /* Stop after x packets */
1483#ifdef HAVE_LIBPCAP1
1484 exit_status = capture_opts_add_opt(application_configuration_environment_prefix(), &global_capture_opts, opt, ws_optarg);
1485 if (exit_status != 0) {
1486 goto clean_exit;
1487 }
1488#else
1489 if (!get_positive_int(ws_optarg, "packet count", &max_packet_count)) {
1490 exit_status = WS_EXIT_INVALID_OPTION1;
1491 goto clean_exit;
1492 }
1493#endif
1494 break;
1495 case 'w': /* Write to file x */
1496 output_file_name = g_strdup(ws_optarg)g_strdup_inline (ws_optarg);
1497#ifdef HAVE_LIBPCAP1
1498 exit_status = capture_opts_add_opt(application_configuration_environment_prefix(), &global_capture_opts, opt, ws_optarg);
1499 if (exit_status != 0) {
1500 goto clean_exit;
1501 }
1502#endif
1503 break;
1504 case 'C':
1505 /* already processed; just ignore it now */
1506 break;
1507 case 'D': /* Print a list of capture devices and exit */
1508#ifdef HAVE_LIBPCAP1
1509 exit_status = EXIT_SUCCESS0;
1510 if_list = capture_interface_list(global_capture_opts.app_name, &err, &err_str,NULL((void*)0));
1511 if (err != 0) {
1512 /*
1513 * An error occurred when fetching the local
1514 * interfaces. Report it.
1515 */
1516 cmdarg_err("%s", err_str);
1517 g_free(err_str);
1518 exit_status = WS_EXIT_PCAP_ERROR13;
1519 }
1520 if (if_list == NULL((void*)0)) {
1521 /*
1522 * No interfaces were found. If that's not the
1523 * result of an error when fetching the local
1524 * interfaces, let the user know.
1525 */
1526 if (err == 0) {
1527 cmdarg_err("There are no interfaces on which a capture can be done");
1528 exit_status = WS_EXIT_NO_INTERFACES12;
1529 }
1530 goto clean_exit;
1531 }
1532 capture_opts_print_interfaces(if_list);
1533 free_interface_list(if_list);
1534 goto clean_exit;
1535#else
1536 capture_option_specified = true1;
1537 arg_error = true1;
1538#endif
1539 break;
1540 case 'e':
1541 /* Field entry */
1542 {
1543 const char* col_field = try_convert_to_column_field(ws_optarg);
1544 if (col_field) {
1545 output_fields_add(output_fields, col_field);
1546 } else {
1547 header_field_info *hfi = proto_registrar_get_byalias(ws_optarg);
1548 if (hfi)
1549 output_fields_add(output_fields, hfi->abbrev);
1550 else
1551 output_fields_add(output_fields, ws_optarg);
1552 }
1553 }
1554 break;
1555 case 'E':
1556 /* Field option */
1557 if (!output_fields_set_option(output_fields, ws_optarg)) {
1558 cmdarg_err("\"%s\" is not a valid field output option=value pair.", ws_optarg);
1559 output_fields_list_options(stderrstderr);
1560 exit_status = WS_EXIT_INVALID_OPTION1;
1561 goto clean_exit;
1562 }
1563 break;
1564 case 'F':
1565 out_file_type = wtap_name_to_file_type_subtype(ws_optarg);
1566 if (out_file_type < 0) {
1567 cmdarg_err("\"%s\" isn't a valid capture file type", ws_optarg);
1568 list_capture_types();
1569 exit_status = WS_EXIT_INVALID_OPTION1;
1570 goto clean_exit;
1571 }
1572 break;
1573 case 'G':
1574 /* already processed; just ignore it now */
1575 break;
1576 case 'j':
1577 if (!protocolfilter_add_opt(ws_optarg, PF_NONE)) {
1578 exit_status = WS_EXIT_INVALID_OPTION1;
1579 goto clean_exit;
1580 }
1581 break;
1582 case 'J':
1583 if (!protocolfilter_add_opt(ws_optarg, PF_INCLUDE_CHILDREN)) {
1584 exit_status = WS_EXIT_INVALID_OPTION1;
1585 goto clean_exit;
1586 }
1587 break;
1588 case 'W': /* Select extra information to save in our capture file */
1589 /* This is patterned after the -N flag which may not be the best idea. */
1590 if (strchr(ws_optarg, 'n')) {
1591 out_file_name_res = true1;
1592 } else {
1593 cmdarg_err("Invalid -W argument \"%s\"; it must be one of:", ws_optarg);
1594 cmdarg_err_cont("\t'n' write network address resolution information (pcapng only)");
1595 exit_status = WS_EXIT_INVALID_OPTION1;
1596 goto clean_exit;
1597 }
1598 break;
1599 case 'H': /* Read address to name mappings from a hosts file */
1600 if (! add_hosts_file(ws_optarg))
1601 {
1602 cmdarg_err("Can't read host entries from \"%s\"", ws_optarg);
1603 exit_status = WS_EXIT_INVALID_OPTION1;
1604 goto clean_exit;
1605 }
1606 out_file_name_res = true1;
1607 break;
1608
1609 case 'h': /* Print help and exit */
1610 show_help_header("Dump and analyze network traffic.");
1611 print_usage(stdoutstdout);
1612 exit_status = EXIT_SUCCESS0;
1613 goto clean_exit;
1614 break;
1615 case 'l': /* "Line-buffer" standard output */
1616 /* The ANSI C standard does not appear to *require* that a line-buffered
1617 stream be flushed to the host environment whenever a newline is
1618 written, it just says that, on such a stream, characters "are
1619 intended to be transmitted to or from the host environment as a
1620 block when a new-line character is encountered".
1621
1622 The Visual C++ 6.0 C implementation doesn't do what is intended;
1623 even if you set a stream to be line-buffered, it still doesn't
1624 flush the buffer at the end of every line.
1625
1626 The whole reason for the "-l" flag in either tcpdump or TShark
1627 is to allow the output of a live capture to be piped to a program
1628 or script and to have that script see the information for the
1629 packet as soon as it's printed, rather than having to wait until
1630 a standard I/O buffer fills up.
1631
1632 So, if the "-l" flag is specified, we flush the standard output
1633 at the end of a packet. This will do the right thing if we're
1634 printing packet summary lines, and, as we print the entire protocol
1635 tree for a single packet without waiting for anything to happen,
1636 it should be as good as line-buffered mode if we're printing
1637 protocol trees - arguably even better, as it may do fewer
1638 writes. */
1639 line_buffered = true1;
1640#ifdef HAVE_LIBPCAP1
1641 /* Set the update-interval to 0 so that dumpcap reports packets
1642 * as soon as available instead of buffering them.
1643 */
1644 exit_status = capture_opts_add_opt(application_configuration_environment_prefix(), &global_capture_opts, opt, ws_optarg);
1645 if (exit_status != 0) {
1646 goto clean_exit;
1647 }
1648#endif
1649 break;
1650 case 'L': /* Print list of link-layer types and exit */
1651#ifdef HAVE_LIBPCAP1
1652 caps_queries |= CAPS_QUERY_LINK_TYPES;
1653#else
1654 capture_option_specified = true1;
1655 arg_error = true1;
1656#endif
1657 break;
1658 case LONGOPT_LIST_TSTAMP_TYPES1000 +1: /* List possible timestamp types */
1659#ifdef HAVE_LIBPCAP1
1660 caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES;
1661#else
1662 capture_option_specified = true1;
1663 arg_error = true1;
1664#endif
1665 break;
1666 case 'o': /* Override preference from command line */
1667 {
1668 char *errmsg = NULL((void*)0);
1669
1670 switch (prefs_set_pref(ws_optarg, &errmsg)) {
1671
1672 case PREFS_SET_OK:
1673 break;
1674
1675 case PREFS_SET_SYNTAX_ERR:
1676 cmdarg_err("Invalid -o flag \"%s\"%s%s", ws_optarg,
1677 errmsg ? ": " : "", errmsg ? errmsg : "");
1678 g_free(errmsg);
1679 exit_status = WS_EXIT_INVALID_OPTION1;
1680 goto clean_exit;
1681 break;
1682
1683 case PREFS_SET_NO_SUCH_PREF:
1684 cmdarg_err("-o flag \"%s\" specifies unknown preference", ws_optarg);
1685 exit_status = WS_EXIT_INVALID_OPTION1;
1686 goto clean_exit;
1687 break;
1688
1689 case PREFS_SET_OBSOLETE:
1690 cmdarg_err("-o flag \"%s\" specifies obsolete preference", ws_optarg);
1691 exit_status = WS_EXIT_INVALID_OPTION1;
1692 goto clean_exit;
1693 break;
1694 }
1695 break;
1696 }
1697 case 'q': /* Quiet */
1698 quiet = true1;
1699 break;
1700 case 'Q': /* Really quiet */
1701 quiet = true1;
1702 really_quiet = true1;
1703 break;
1704 case 'r':
1705 /* already processed; just ignore it now */
1706 break;
1707 case 'R': /* Read file filter */
1708 rfilter = ws_optarg;
1709 break;
1710 case 'P':
1711 /* already processed; just ignore it now */
1712 break;
1713 case 'S': /* Set the line Separator to be printed between packets */
1714 separator = ws_optarg;
1715 break;
1716 case 'T': /* printing Type */
1717 /* output_action has been already set. It means multiple -T. */
1718 if (output_action > WRITE_NONE) {
1719 cmdarg_err("Multiple -T parameters are unsupported");
1720 exit_status = WS_EXIT_INVALID_OPTION1;
1721 goto clean_exit;
1722 }
1723 print_packet_info = true1;
1724 if (strcmp(ws_optarg, "text") == 0) {
1725 output_action = WRITE_TEXT;
1726 print_format = PR_FMT_TEXT;
1727 } else if (strcmp(ws_optarg, "tabs") == 0) {
1728 output_action = WRITE_TEXT;
1729 print_format = PR_FMT_TEXT;
1730 delimiter_char = "\t";
1731 } else if (strcmp(ws_optarg, "ps") == 0) {
1732 output_action = WRITE_TEXT;
1733 print_format = PR_FMT_PS;
1734 } else if (strcmp(ws_optarg, "pdml") == 0) {
1735 output_action = WRITE_XML;
1736 print_details = true1; /* Need details */
1737 print_summary = false0; /* Don't allow summary */
1738 } else if (strcmp(ws_optarg, "psml") == 0) {
1739 output_action = WRITE_XML;
1740 print_details = false0; /* Don't allow details */
1741 print_summary = true1; /* Need summary */
1742 } else if (strcmp(ws_optarg, "fields") == 0) {
1743 output_action = WRITE_FIELDS;
1744 print_details = true1; /* Need full tree info */
1745 print_summary = false0; /* Don't allow summary */
1746 } else if (strcmp(ws_optarg, "json") == 0) {
1747 output_action = WRITE_JSON;
1748 print_details = true1; /* Need details */
1749 print_summary = false0; /* Don't allow summary */
1750 } else if (strcmp(ws_optarg, "ek") == 0) {
1751 output_action = WRITE_EK;
1752 if (!print_summary)
1753 print_details = true1;
1754 } else if (strcmp(ws_optarg, "jsonraw") == 0) {
1755 output_action = WRITE_JSON_RAW;
1756 print_details = true1; /* Need details */
1757 print_summary = false0; /* Don't allow summary */
1758 }
1759 else {
1760 cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", ws_optarg); /* x */
1761 cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
1762 "\t specified by the -E option.\n"
1763 "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
1764 "\t details of a decoded packet. This information is equivalent to\n"
1765 "\t the packet details printed with the -V flag.\n"
1766 "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
1767 "\t the packets, or a multi-line view of the details of each of\n"
1768 "\t the packets, depending on whether the -V flag was specified.\n"
1769 "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
1770 "\t summary information of a decoded packet. This information is\n"
1771 "\t equivalent to the information shown in the one-line summary\n"
1772 "\t printed by default.\n"
1773 "\t\"json\" Packet Summary, an JSON-based format for the details\n"
1774 "\t summary information of a decoded packet. This information is \n"
1775 "\t equivalent to the packet details printed with the -V flag.\n"
1776 "\t\"jsonraw\" Packet Details, a JSON-based format for machine parsing\n"
1777 "\t including only raw hex decoded fields (same as -T json -x but\n"
1778 "\t without text decoding, only raw fields included). \n"
1779 "\t\"ek\" Packet Details, an EK JSON-based format for the bulk insert \n"
1780 "\t into elastic search cluster. This information is \n"
1781 "\t equivalent to the packet details printed with the -V flag.\n"
1782 "\t\"text\" Text of a human-readable one-line summary of each of the\n"
1783 "\t packets, or a multi-line view of the details of each of the\n"
1784 "\t packets, depending on whether the -V flag was specified.\n"
1785 "\t This is the default.\n"
1786 "\t\"tabs\" Similar to the text report except that each column of the\n"
1787 "\t human-readable one-line summary is delimited with an ASCII\n"
1788 "\t horizontal tab character.");
1789 exit_status = WS_EXIT_INVALID_OPTION1;
1790 goto clean_exit;
1791 }
1792 break;
1793 case 'U': /* Export PDUs to file */
1794 if (strcmp(ws_optarg, "") == 0 || strcmp(ws_optarg, "?") == 0) {
1795 list_export_pdu_taps();
1796 exit_status = WS_EXIT_INVALID_OPTION1;
1797 goto clean_exit;
1798 }
1799 pdu_export_arg = g_strdup(ws_optarg)g_strdup_inline (ws_optarg);
1800 break;
1801 case 'v': /* Show version and exit */
1802#ifdef ENABLE_CHECK_FILTER
1803 /* If we're testing start-up of the epan library, go ahead and
1804 * load all the delayed initialization prefixes (e.g. Diameter)
1805 * so that they are reported on.
1806 */
1807 proto_initialize_all_prefixes();
1808#endif
1809 show_version();
1810 /* We don't really have to cleanup here, but it's a convenient way to test
1811 * start-up and shut-down of the epan library without any UI-specific
1812 * cruft getting in the way. Makes the results of running
1813 * $ ./tools/valgrind-wireshark -n
1814 * much more useful. */
1815 epan_cleanup();
1816 extcap_cleanup();
1817 exit_status = EXIT_SUCCESS0;
1818 goto clean_exit;
1819 case 'O': /* Only output these protocols */
1820 /* already processed; just ignore it now */
1821 break;
1822 case 'V': /* Verbose */
1823 /* already processed; just ignore it now */
1824 break;
1825 case 'x': /* Print packet data in hex (and ASCII) */
1826 /* already processed; just ignore it now */
1827 break;
1828 case 'X':
1829 /* already processed; just ignore it now */
1830 break;
1831 case 'Y':
1832 dfilter = g_strdup(ws_optarg)g_strdup_inline (ws_optarg);
1833 break;
1834 case 'z':
1835 /* We won't call the init function for the stat this soon
1836 as it would disallow MATE's fields (which are registered
1837 by the preferences set callback) from being used as
1838 part of a tap filter. Instead, we just add the argument
1839 to a list of stat arguments. */
1840 if (strcmp("help", ws_optarg) == 0) {
1841 fprintf(stderrstderr, "tshark: The available statistics for the \"-z\" option are:\n");
1842 list_stat_cmd_args();
1843 exit_status = EXIT_SUCCESS0;
1844 goto clean_exit;
1845 }
1846 if (!process_stat_cmd_arg(ws_optarg)) {
1847 cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", ws_optarg);
1848 list_stat_cmd_args();
1849 exit_status = WS_EXIT_INVALID_OPTION1;
1850 goto clean_exit;
1851 }
1852 break;
1853 case 'd': /* Decode as rule */
1854 case 'K': /* Kerberos keytab file */
1855 case 'n': /* No name resolution */
1856 case 'N': /* Select what types of addresses/port #s to resolve */
1857 case 't': /* Time stamp type */
1858 case 'u': /* Seconds type */
1859 case LONGOPT_DISABLE_PROTOCOL2000 +1: /* disable dissection of protocol */
1860 case LONGOPT_ENABLE_HEURISTIC2000 +2: /* enable heuristic dissection of protocol */
1861 case LONGOPT_DISABLE_HEURISTIC2000 +3: /* disable heuristic dissection of protocol */
1862 case LONGOPT_ENABLE_PROTOCOL2000 +4: /* enable dissection of protocol (that is disabled by default) */
1863 case LONGOPT_ONLY_PROTOCOLS2000 +5: /* enable dissection of only this comma separated list of protocols */
1864 case LONGOPT_DISABLE_ALL_PROTOCOLS2000 +6: /* enable dissection of protocol (that is disabled by default) */
1865 if (!dissect_opts_handle_opt(opt, ws_optarg)) {
1866 exit_status = WS_EXIT_INVALID_OPTION1;
1867 goto clean_exit;
1868 }
1869 break;
1870 case LONGOPT_EXPORT_OBJECTS3000 +1: /* --export-objects */
1871 if (strcmp("help", ws_optarg) == 0) {
1872 fprintf(stderrstderr, "tshark: The available export object types for the \"--export-objects\" option are:\n");
1873 eo_list_object_types();
1874 exit_status = EXIT_SUCCESS0;
1875 goto clean_exit;
1876 }
1877 if (!eo_tap_opt_add(ws_optarg)) {
1878 exit_status = WS_EXIT_INVALID_OPTION1;
1879 goto clean_exit;
1880 }
1881 break;
1882 case LONGOPT_EXPORT_TLS_SESSION_KEYS3000 +5: /* --export-tls-session-keys */
1883 tls_session_keys_file = ws_optarg;
1884 break;
1885 case LONGOPT_COLOR3000 +2: /* print in color where appropriate */
1886 dissect_color = true1;
1887 /* This has no effect if we don't print packet info or filter
1888 (we can filter on the coloring rules). Should we warn or
1889 error later if so, instead of silently ignoring it? */
1890 break;
1891 case LONGOPT_NO_DUPLICATE_KEYS3000 +3:
1892 no_duplicate_keys = true1;
1893 node_children_grouper = proto_node_group_children_by_json_key;
1894 break;
1895 case LONGOPT_ELASTIC_MAPPING_FILTER3000 +4:
1896 /*
1897 * XXX - A long option that exists to alter one other option
1898 * (-G elastic-mapping) and for no other reason seems verbose.
1899 * Deprecate in favor of -G elastic-mapping,<filter> ?
1900 */
1901 elastic_mapping_filter = ws_optarg;
1902 break;
1903 case LONGOPT_CAPTURE_COMMENT3000 +6: /* capture comment */
1904 if (capture_comments == NULL((void*)0)) {
1905 capture_comments = g_ptr_array_new_with_free_func(g_free);
1906 }
1907 g_ptr_array_add(capture_comments, g_strdup(ws_optarg)g_strdup_inline (ws_optarg));
1908 break;
1909 case LONGOPT_HEXDUMP3000 +7:
1910 print_hex = true1;
1911 print_packet_info = true1;
1912 if (strcmp(ws_optarg, "all") == 0)
1913 hexdump_source_option = HEXDUMP_SOURCE_MULTI(0x0000U);
1914 else if (strcmp(ws_optarg, "frames") == 0)
1915 hexdump_source_option = HEXDUMP_SOURCE_PRIMARY(0x0004U);
1916 else if (strcmp(ws_optarg, "ascii") == 0)
1917 hexdump_ascii_option = HEXDUMP_ASCII_INCLUDE(0x0000U);
1918 else if (strcmp(ws_optarg, "delimit") == 0)
1919 hexdump_ascii_option = HEXDUMP_ASCII_DELIMIT(0x0001U);
1920 else if (strcmp(ws_optarg, "noascii") == 0)
1921 hexdump_ascii_option = HEXDUMP_ASCII_EXCLUDE(0x0002U);
1922 else if (strcmp(ws_optarg, "time") == 0)
1923 hexdump_timestamp_option = HEXDUMP_TIMESTAMP(0x0008U);
1924 else if (strcmp(ws_optarg, "notime") == 0)
1925 hexdump_timestamp_option = HEXDUMP_TIMESTAMP_NONE(0x0000U);
1926 else if (strcmp("help", ws_optarg) == 0) {
1927 hexdump_option_help(stdoutstdout);
1928 exit_status = EXIT_SUCCESS0;
1929 goto clean_exit;
1930 } else {
1931 fprintf(stderrstderr, "tshark: \"%s\" is an invalid value for --hexdump <hexoption>\n", ws_optarg);
1932 fprintf(stderrstderr, "For valid <hexoption> values enter: tshark --hexdump help\n");
1933 exit_status = WS_EXIT_INVALID_OPTION1;
1934 goto clean_exit;
1935 }
1936 break;
1937 case LONGOPT_SELECTED_FRAME3000 +8:
1938 /* Hidden option to mark a frame as "selected". Used for testing and debugging.
1939 * Only active in two-pass mode. */
1940 if (!ws_strtou32(ws_optarg, NULL((void*)0), &selected_frame_number)) {
1941 fprintf(stderrstderr, "tshark: \"%s\" is not a valid frame number\n", ws_optarg);
1942 exit_status = WS_EXIT_INVALID_OPTION1;
1943 goto clean_exit;
1944 }
1945 break;
1946 case LONGOPT_PRINT_TIMERS3000 +9:
1947 opt_print_timers = true1;
1948 break;
1949 case LONGOPT_GLOBAL_PROFILE3000 +10:
1950 /* already processed; just ignore it now */
1951 break;
1952 case LONGOPT_COMPRESS3000 +11: /* compress type */
1953 compression_type = ws_name_to_compression_type(ws_optarg);
1954 if (compression_type == WS_FILE_UNKNOWN_COMPRESSION) {
1955 cmdarg_err("\"%s\" isn't a valid output compression mode",
1956 ws_optarg);
1957 list_output_compression_types();
1958 goto clean_exit;
1959 }
1960 break;
1961 case '?': /* Bad flag - print usage message */
1962 default:
1963 /* wslog arguments are okay */
1964 if (ws_log_is_wslog_arg(opt))
1965 break;
1966
1967 switch(ws_optopt) {
1968 case 'F':
1969 list_capture_types();
1970 break;
1971 case 'G':
1972 glossary_option_help();
1973 break;
1974 case LONGOPT_COMPRESS3000 +11:
1975 case LONGOPT_COMPRESS_TYPE1000 +3:
1976 list_output_compression_types();
1977 break;
1978 default:
1979 print_usage(stderrstderr);
1980 }
1981 exit_status = WS_EXIT_INVALID_OPTION1;
1982 goto clean_exit;
1983 break;
1984 }
1985 }
1986
1987 /* set the default output action to TEXT */
1988 if (output_action == WRITE_NONE)
1989 output_action = WRITE_TEXT;
1990
1991 /* set the default file type to pcapng */
1992 if (out_file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN-1)
1993 out_file_type = wtap_pcapng_file_type_subtype();
1994
1995 /*
1996 * Print packet summary information is the default if neither -V or -x
1997 * were specified. Note that this is new behavior, which allows for the
1998 * possibility of printing only hex/ascii output without necessarily
1999 * requiring that either the summary or details be printed too.
2000 */
2001 if (!print_summary && !print_details && !print_hex)
2002 print_summary = true1;
2003
2004 if (no_duplicate_keys && output_action != WRITE_JSON && output_action != WRITE_JSON_RAW) {
2005 cmdarg_err("--no-duplicate-keys can only be used with \"-T json\" and \"-T jsonraw\"");
2006 exit_status = WS_EXIT_INVALID_OPTION1;
2007 goto clean_exit;
2008 }
2009
2010 /* If we specified output fields, but not the output field type... */
2011 /* XXX: If we specified both output fields with -e *and* protocol filters
2012 * with -j/-J, only the former are used. Should we warn or abort?
2013 * This also doesn't distinguish PDML from PSML, but shouldn't allow the
2014 * latter.
2015 */
2016 if ((WRITE_FIELDS != output_action && WRITE_XML != output_action && WRITE_JSON != output_action && WRITE_EK != output_action) && 0 != output_fields_num_fields(output_fields)) {
2017 cmdarg_err("Output fields were specified with \"-e\", "
2018 "but \"-Tek, -Tfields, -Tjson or -Tpdml\" was not specified.");
2019 exit_status = WS_EXIT_INVALID_OPTION1;
2020 goto clean_exit;
2021 } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
2022 cmdarg_err("\"-Tfields\" was specified, but no fields were "
2023 "specified with \"-e\".");
2024
2025 exit_status = WS_EXIT_INVALID_OPTION1;
2026 goto clean_exit;
2027 }
2028
2029 if (dissect_color) {
2030 if (!color_filters_init(&err_msg, NULL((void*)0), application_configuration_environment_prefix())) {
2031 fprintf(stderrstderr, "%s\n", err_msg);
2032 g_free(err_msg);
2033 }
2034 }
2035
2036 /* If no capture filter or display filter has been specified, and there are
2037 still command-line arguments, treat them as the tokens of a capture
2038 filter (if no "-r" flag was specified) or a display filter (if a "-r"
2039 flag was specified. */
2040 if (ws_optind < argc) {
2041 if (cf_name != NULL((void*)0)) {
2042 if (dfilter != NULL((void*)0)) {
2043 cmdarg_err("Display filters were specified both with \"-Y\" "
2044 "and with additional command-line arguments.");
2045 exit_status = WS_EXIT_INVALID_OPTION1;
2046 goto clean_exit;
2047 }
2048 dfilter = get_args_as_string(argc, argv, ws_optind);
2049 } else {
2050#ifdef HAVE_LIBPCAP1
2051 unsigned i;
2052
2053 if (global_capture_opts.default_options.cfilter) {
2054 cmdarg_err("A default capture filter was specified both with \"-f\""
2055 " and with additional command-line arguments.");
2056 exit_status = WS_EXIT_INVALID_OPTION1;
2057 goto clean_exit;
2058 }
2059 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2060 interface_options *interface_opts;
2061 interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i)(((interface_options*) (void *) (global_capture_opts.ifaces)->
data) [(i)])
;
2062 if (interface_opts->cfilter == NULL((void*)0)) {
2063 interface_opts->cfilter = get_args_as_string(argc, argv, ws_optind);
2064 } else {
2065 cmdarg_err("A capture filter was specified both with \"-f\""
2066 " and with additional command-line arguments.");
2067 exit_status = WS_EXIT_INVALID_OPTION1;
2068 goto clean_exit;
2069 }
2070 }
2071 global_capture_opts.default_options.cfilter = get_args_as_string(argc, argv, ws_optind);
2072#else
2073 capture_option_specified = true1;
2074#endif
2075 }
2076 }
2077
2078 if (!output_file_name) {
2079 /* We're not saving the capture to a file; if "-q" wasn't specified,
2080 we should print packet information */
2081 if (!quiet)
2082 print_packet_info = true1;
2083 } else {
2084 const char *save_file = output_file_name;
2085 /* We're saving to a file; if we're writing to the standard output.
2086 and we'll also be writing dissected packets to the standard
2087 output, reject the request. At best, we could redirect that
2088 to the standard error; we *can't* write both to the standard
2089 output and have either of them be useful. */
2090 if (strcmp(save_file, "-") == 0 && print_packet_info) {
2091 cmdarg_err("You can't write both raw packet data and dissected packets"
2092 " to the standard output.");
2093 exit_status = WS_EXIT_INVALID_OPTION1;
2094 goto clean_exit;
2095 }
2096 if (compression_type == WS_FILE_UNKNOWN_COMPRESSION) {
2097 /* An explicitly specified compression type overrides filename
2098 * magic. (Should we allow a way to specify "no" compression
2099 * with, e.g. a ".gz" extension?) */
2100 const char *sfx = strrchr(save_file, '.');
2101 if (sfx) {
2102 compression_type = ws_extension_to_compression_type(sfx + 1);
2103 }
2104 }
2105 }
2106
2107 if (compression_type == WS_FILE_UNKNOWN_COMPRESSION) {
2108 compression_type = WS_FILE_UNCOMPRESSED;
2109 }
2110
2111 if (!ws_can_write_compression_type(compression_type)) {
2112 cmdarg_err("Output files can't be written as %s",
2113 ws_compression_type_description(compression_type));
2114 exit_status = WS_EXIT_INVALID_OPTION1;
2115 goto clean_exit;
2116 }
2117
2118 if (compression_type != WS_FILE_UNCOMPRESSED && !wtap_dump_can_compress(out_file_type)) {
2119 cmdarg_err("The file format %s can't be written to output compressed format",
2120 wtap_file_type_subtype_name(out_file_type));
2121 exit_status = WS_EXIT_INVALID_OPTION1;
2122 goto clean_exit;
2123 }
2124
2125 /* XXX - We have two different long options for compression type;
2126 * one (undocumented) for live capturing and one for not. That is confusing.
2127 * LONGOPT_COMPRESS doesn't set "capture_option_specified" because it can be
2128 * used when capturing or when not capturing.
2129 */
2130 if (compression_type != WS_FILE_UNCOMPRESSED && is_capturing) {
2131#ifdef HAVE_LIBPCAP1
2132 exit_status = capture_opts_add_opt(application_configuration_environment_prefix(), &global_capture_opts, LONGOPT_COMPRESS_TYPE1000 +3, ws_compression_type_name(compression_type));
2133 if (exit_status != 0) {
2134 goto clean_exit;
2135 }
2136#else
2137 capture_option_specified = true1;
2138 arg_error = true1;
2139#endif
2140 }
2141
2142#ifndef HAVE_LIBPCAP1
2143 if (capture_option_specified)
2144 cmdarg_err("This version of TShark was not built with support for capturing packets.");
2145#endif
2146 if (arg_error) {
2147 print_usage(stderrstderr);
2148 exit_status = WS_EXIT_INVALID_OPTION1;
2149 goto clean_exit;
2150 }
2151
2152 if (print_hex) {
2153 if (output_action != WRITE_TEXT && output_action != WRITE_JSON && output_action != WRITE_JSON_RAW && output_action != WRITE_EK) {
2154 cmdarg_err("Raw packet hex data can only be printed as text, PostScript, JSON, JSONRAW or EK JSON");
2155 exit_status = WS_EXIT_INVALID_OPTION1;
2156 goto clean_exit;
2157 }
2158 }
2159
2160 if (output_only != NULL((void*)0)) {
2161 char *ps;
2162
2163 if (!print_details) {
2164 cmdarg_err("-O requires -V");
2165 exit_status = WS_EXIT_INVALID_OPTION1;
2166 goto clean_exit;
2167 }
2168
2169 output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
2170 for (ps = strtok (output_only, ","); ps; ps = strtok (NULL((void*)0), ",")) {
2171 const char *name = ps;
2172 header_field_info *hfi = proto_registrar_get_byalias(name);
2173 if (hfi) {
2174 name = hfi->abbrev;
2175 }
2176 g_hash_table_insert(output_only_tables, (void *)name, (void *)name);
2177 }
2178 }
2179
2180 if (rfilter != NULL((void*)0) && !perform_two_pass_analysis) {
2181 cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
2182 exit_status = WS_EXIT_INVALID_OPTION1;
2183 goto clean_exit;
2184 }
2185
2186#ifdef HAVE_LIBPCAP1
2187 if (caps_queries) {
2188 /* We're supposed to list the link-layer/timestamp types for an interface;
2189 did the user also specify a capture file to be read? */
2190 if (cf_name) {
2191 /* Yes - that's bogus. */
2192 cmdarg_err("You can't specify %s and a capture file to be read.",
2193 caps_queries & CAPS_QUERY_LINK_TYPES ? "-L" : "--list-time-stamp-types");
2194 exit_status = WS_EXIT_INVALID_OPTION1;
2195 goto clean_exit;
2196 }
2197 /* No - did they specify a ring buffer option? */
2198 if (global_capture_opts.multi_files_on) {
2199 cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2200 exit_status = WS_EXIT_INVALID_OPTION1;
2201 goto clean_exit;
2202 }
2203 } else {
2204 if (cf_name) {
2205 /*
2206 * "-r" was specified, so we're reading a capture file.
2207 * Capture options don't apply here.
2208 */
2209
2210 /* We don't support capture filters when reading from a capture file
2211 (the BPF compiler doesn't support all link-layer types that we
2212 support in capture files we read). */
2213 if (global_capture_opts.default_options.cfilter) {
2214 cmdarg_err("Only read filters, not capture filters, "
2215 "can be specified when reading a capture file.");
2216 exit_status = WS_EXIT_INVALID_OPTION1;
2217 goto clean_exit;
2218 }
2219 if (global_capture_opts.multi_files_on) {
2220 cmdarg_err("Multiple capture files requested, but "
2221 "a capture isn't being done.");
2222 exit_status = WS_EXIT_INVALID_OPTION1;
2223 goto clean_exit;
2224 }
2225 if (global_capture_opts.has_file_duration) {
2226 cmdarg_err("Switching capture files after a time period was specified, but "
2227 "a capture isn't being done.");
2228 exit_status = WS_EXIT_INVALID_OPTION1;
2229 goto clean_exit;
2230 }
2231 if (global_capture_opts.has_file_interval) {
2232 cmdarg_err("Switching capture files after a time interval was specified, but "
2233 "a capture isn't being done.");
2234 exit_status = WS_EXIT_INVALID_OPTION1;
2235 goto clean_exit;
2236 }
2237 if (global_capture_opts.has_ring_num_files) {
2238 cmdarg_err("A ring buffer of capture files was specified, but "
2239 "a capture isn't being done.");
2240 exit_status = WS_EXIT_INVALID_OPTION1;
2241 goto clean_exit;
2242 }
2243 if (global_capture_opts.has_autostop_files) {
2244 cmdarg_err("A maximum number of capture files was specified, but "
2245 "a capture isn't being done.");
2246 exit_status = WS_EXIT_INVALID_OPTION1;
2247 goto clean_exit;
2248 }
2249
2250 /* Note: TShark now allows the restriction of a _read_ file by packet count
2251 * and byte count as well as a write file. Other autostop options remain valid
2252 * only for a write file.
2253 */
2254 if (global_capture_opts.has_autostop_duration) {
2255 cmdarg_err("A maximum capture time was specified, but "
2256 "a capture isn't being done.");
2257 exit_status = WS_EXIT_INVALID_OPTION1;
2258 goto clean_exit;
2259 }
2260 } else {
2261 /*
2262 * "-r" wasn't specified, so we're doing a live capture.
2263 */
2264 bool_Bool use_pcapng = true1;
2265
2266 if (perform_two_pass_analysis) {
2267 /* Two-pass analysis doesn't work with live capture since it requires us
2268 * to buffer packets until we've read all of them, but a live capture
2269 * has no useful/meaningful definition of "all" */
2270 cmdarg_err("Live captures do not support two-pass analysis.");
2271 exit_status = WS_EXIT_INVALID_OPTION1;
2272 goto clean_exit;
2273 }
2274
2275 if (global_capture_opts.saving_to_file) {
2276 /* They specified a "-w" flag, so we'll be saving to a capture file. */
2277
2278 /* When capturing, we only support writing pcap or pcapng format. */
2279 if (out_file_type == wtap_pcapng_file_type_subtype()) {
2280 use_pcapng = true1;
2281 } else if (out_file_type == wtap_pcap_file_type_subtype()) {
2282 use_pcapng = false0;
2283 } else if (out_file_type == wtap_pcap_nsec_file_type_subtype()) {
2284 /* XXX - We request nanosecond time resolution regardless.
2285 * In the future wiretap might treat the two pcap subtypes
2286 * the same.
2287 */
2288 use_pcapng = false0;
2289 } else {
2290 cmdarg_err("Live captures can only be saved in pcap or pcapng format.");
2291 capture_opts_list_file_types();
2292 exit_status = WS_EXIT_INVALID_OPTION1;
2293 goto clean_exit;
2294 }
2295 if (capture_comments != NULL((void*)0) && !use_pcapng) {
2296 cmdarg_err("Capture comments can only be written to a pcapng file.");
2297 exit_status = WS_EXIT_INVALID_OPTION1;
2298 goto clean_exit;
2299 }
2300 if (global_capture_opts.multi_files_on) {
2301 /* Multiple-file mode doesn't work under certain conditions:
2302 a) it doesn't work if you're writing to the standard output;
2303 b) it doesn't work if you're writing to a pipe;
2304 */
2305 if (strcmp(global_capture_opts.save_file, "-") == 0) {
2306 cmdarg_err("Multiple capture files requested, but "
2307 "the capture is being written to the standard output.");
2308 exit_status = WS_EXIT_INVALID_OPTION1;
2309 goto clean_exit;
2310 }
2311 if (global_capture_opts.output_to_pipe) {
2312 cmdarg_err("Multiple capture files requested, but "
2313 "the capture file is a pipe.");
2314 exit_status = WS_EXIT_INVALID_OPTION1;
2315 goto clean_exit;
2316 }
2317 if (!global_capture_opts.has_autostop_filesize &&
2318 !global_capture_opts.has_file_duration &&
2319 !global_capture_opts.has_file_interval &&
2320 !global_capture_opts.has_file_packets) {
2321 cmdarg_err("Multiple capture files requested, but "
2322 "no maximum capture file size, duration, interval or packets were specified.");
2323 exit_status = WS_EXIT_INVALID_OPTION1;
2324 goto clean_exit;
2325 }
2326 }
2327 /* Currently, we don't support read or display filters when capturing
2328 and saving the packets. */
2329 if (rfilter != NULL((void*)0)) {
2330 cmdarg_err("Read filters aren't supported when capturing and saving the captured packets.");
2331 exit_status = WS_EXIT_INVALID_OPTION1;
2332 goto clean_exit;
2333 }
2334 if (dfilter != NULL((void*)0)) {
2335 cmdarg_err("Display filters aren't supported when capturing and saving the captured packets.");
2336 exit_status = WS_EXIT_INVALID_OPTION1;
2337 goto clean_exit;
2338 }
2339 global_capture_opts.use_pcapng = use_pcapng;
2340 } else {
2341 /* They didn't specify a "-w" flag, so we won't be saving to a
2342 capture file. Check for options that only make sense if
2343 we're saving to a file. */
2344 if (global_capture_opts.has_autostop_filesize) {
2345 cmdarg_err("Maximum capture file size specified, but "
2346 "capture isn't being saved to a file.");
2347 exit_status = WS_EXIT_INVALID_OPTION1;
2348 goto clean_exit;
2349 }
2350 if (global_capture_opts.multi_files_on) {
2351 cmdarg_err("Multiple capture files requested, but "
2352 "the capture isn't being saved to a file.");
2353 exit_status = WS_EXIT_INVALID_OPTION1;
2354 goto clean_exit;
2355 }
2356 if (capture_comments != NULL((void*)0)) {
2357 cmdarg_err("Capture comments were specified, but "
2358 "the capture isn't being saved to a file.");
2359 exit_status = WS_EXIT_INVALID_OPTION1;
2360 goto clean_exit;
2361 }
2362 }
2363 }
2364 }
2365#endif
2366
2367 /*
2368 * If capture comments were specified, -w also has to have been specified.
2369 */
2370 if (capture_comments != NULL((void*)0)) {
2371 if (output_file_name) {
2372 /* They specified a "-w" flag, so we'll be saving to a capture file.
2373 * This is fine if they're writing in a format that supports
2374 * section block comments.
2375 */
2376 if (wtap_file_type_subtype_supports_option(out_file_type,
2377 WTAP_BLOCK_SECTION,
2378 OPT_COMMENT1) == OPTION_NOT_SUPPORTED) {
2379 GArray *writable_type_subtypes;
2380
2381 cmdarg_err("Capture comments can only be written to files of the following types:");
2382 writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME);
2383 for (unsigned i = 0; i < writable_type_subtypes->len; i++) {
2384 int ft = g_array_index(writable_type_subtypes, int, i)(((int*) (void *) (writable_type_subtypes)->data) [(i)]);
2385
2386 if (wtap_file_type_subtype_supports_option(ft, WTAP_BLOCK_SECTION,
2387 OPT_COMMENT1) != OPTION_NOT_SUPPORTED)
2388 cmdarg_err_cont(" %s - %s", wtap_file_type_subtype_name(ft),
2389 wtap_file_type_subtype_description(ft));
2390 }
2391 exit_status = WS_EXIT_INVALID_OPTION1;
2392 goto clean_exit;
2393 }
2394 }
2395 else {
2396 cmdarg_err("Capture comments were specified, but you aren't writing a capture file.");
2397 exit_status = WS_EXIT_INVALID_OPTION1;
2398 goto clean_exit;
2399 }
2400 }
2401
2402 err_msg = ws_init_sockets();
2403 if (err_msg != NULL((void*)0))
2404 {
2405 cmdarg_err("%s", err_msg);
2406 g_free(err_msg);
2407 cmdarg_err_cont("%s", please_report_bug());
2408 exit_status = WS_EXIT_INIT_FAILED8;
2409 goto clean_exit;
2410 }
2411
2412 /* Notify all registered modules that have had any of their preferences
2413 changed either from one of the preferences file or from the command
2414 line that their preferences have changed. */
2415 prefs_apply_all();
2416
2417 /* We can also enable specified taps for export object */
2418 start_exportobjects();
2419
2420 /* At this point MATE will have registered its field array so we can
2421 check if the fields specified by the user are all good.
2422 */
2423 {
2424 GSList* it = NULL((void*)0);
2425 GSList *invalid_fields = output_fields_valid(output_fields);
2426 if (invalid_fields != NULL((void*)0)) {
2427
2428 cmdarg_err("Some fields aren't valid:");
2429 for (it=invalid_fields; it != NULL((void*)0); it = g_slist_next(it)((it) ? (((GSList *)(it))->next) : ((void*)0))) {
2430 cmdarg_err_cont("\t%s", (char *)it->data);
2431 }
2432 g_slist_free(invalid_fields);
2433 exit_status = WS_EXIT_INVALID_OPTION1;
2434 goto clean_exit;
2435 }
2436 }
2437
2438 if (ex_opt_count("read_format") > 0) {
2439 char* name = ex_opt_get_next("read_format");
2440 in_file_type = open_info_name_to_type(name);
2441 if (in_file_type == WTAP_TYPE_AUTO0) {
2442 cmdarg_err("\"%s\" isn't a valid read file format type", name? name : "");
2443 g_free(name);
2444 list_read_capture_types();
2445 exit_status = WS_EXIT_INVALID_OPTION1;
2446 goto clean_exit;
2447 }
2448 g_free(name);
2449 }
2450
2451 if (global_dissect_options.time_format != TS_NOT_SET)
2452 timestamp_set_type(global_dissect_options.time_format);
2453 if (global_dissect_options.time_precision != TS_PREC_NOT_SET)
2454 timestamp_set_precision(global_dissect_options.time_precision);
2455
2456 /*
2457 * Enabled and disabled protocols and heuristic dissectors as per
2458 * command-line options.
2459 */
2460 if (!setup_enabled_and_disabled_protocols()) {
2461 exit_status = WS_EXIT_INVALID_OPTION1;
2462 goto clean_exit;
2463 }
2464
2465 /* Build the column format array */
2466 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, true1);
2467
2468 /* Everything is setup, dump glossaries now if that's what we're doing.
2469 * We want to do this after protocols and heuristic dissectors are
2470 * enabled and disabled. Doing it after building the column format
2471 * array might make it easier to add a report that describes the
2472 * current list of columns and how to add a new one (#17332).
2473 */
2474 if (glossary != NULL((void*)0)) {
2475 exit_status = dump_glossary(glossary, elastic_mapping_filter);
2476 goto clean_exit;
2477 }
2478
2479#ifdef HAVE_LIBPCAP1
2480 capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE1);
2481 capture_opts_trim_ring_num_files(&global_capture_opts);
2482#endif
2483
2484 if (rfilter != NULL((void*)0)) {
2485 ws_debug("Compiling read filter: '%s'", rfilter)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 2485, __func__, "Compiling read filter: '%s'", rfilter); } }
while (0)
;
2486 if (!compile_dfilter(rfilter, &rfcode)_compile_dfilter(rfilter, &rfcode, __func__)) {
2487 epan_cleanup();
2488 extcap_cleanup();
2489
2490#ifdef HAVE_LIBPCAP1
2491 warn_about_capture_filter(rfilter);
2492#endif
2493
2494 exit_status = WS_EXIT_INVALID_INTERFACE2;
2495 goto clean_exit;
2496 }
2497 }
2498 cfile.rfcode = rfcode;
2499
2500 if (dfilter != NULL((void*)0)) {
2501 ws_debug("Compiling display filter: '%s'", dfilter)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 2501, __func__, "Compiling display filter: '%s'", dfilter);
} } while (0)
;
2502 if (!compile_dfilter(dfilter, &dfcode)_compile_dfilter(dfilter, &dfcode, __func__)) {
2503 epan_cleanup();
2504 extcap_cleanup();
2505
2506#ifdef HAVE_LIBPCAP1
2507 warn_about_capture_filter(dfilter);
2508#endif
2509
2510 exit_status = WS_EXIT_INVALID_FILTER4;
2511 goto clean_exit;
2512 }
2513 }
2514 cfile.dfcode = dfcode;
2515 tap_load_main_filter(dfcode);
2516
2517 if (print_packet_info) {
2518 /* If we're printing as text or PostScript, we have
2519 to create a print stream. */
2520 if (output_action == WRITE_TEXT) {
2521 switch (print_format) {
2522
2523 case PR_FMT_TEXT:
2524 print_stream = print_stream_text_stdio_new(stdoutstdout);
2525 break;
2526
2527 case PR_FMT_PS:
2528 print_stream = print_stream_ps_stdio_new(stdoutstdout);
2529 break;
2530
2531 default:
2532 ws_assert_not_reached()ws_log_fatal_full("Main", LOG_LEVEL_ERROR, "tshark.c", 2532, __func__
, "assertion \"not reached\" failed")
;
2533 }
2534 }
2535 }
2536
2537 /* PDU export requested. Take the ownership of the '-w' file, apply tap
2538 * filters and start tapping. */
2539 if (pdu_export_arg) {
2540 const char *exp_pdu_tap_name = pdu_export_arg;
2541 const char *exp_pdu_filter = dfilter; /* may be NULL to disable filter */
2542 char *exp_pdu_error;
2543 int exp_fd;
2544 char *comment;
2545
2546 if (!cf_name) {
2547 cmdarg_err("PDUs export requires a capture file (specify with -r).");
2548 exit_status = WS_EXIT_INVALID_OPTION1;
2549 goto clean_exit;
2550 }
2551 /* Take ownership of the '-w' output file. */
2552 exp_pdu_filename = output_file_name;
2553 output_file_name = NULL((void*)0);
2554#ifdef HAVE_LIBPCAP1
2555 global_capture_opts.save_file = NULL((void*)0);
2556#endif
2557 if (exp_pdu_filename == NULL((void*)0)) {
2558 cmdarg_err("PDUs export requires an output file (-w).");
2559 exit_status = WS_EXIT_INVALID_OPTION1;
2560 goto clean_exit;
2561 }
2562
2563 exp_pdu_error = exp_pdu_pre_open(exp_pdu_tap_name, exp_pdu_filter,
2564 &exp_pdu_tap_data);
2565 if (exp_pdu_error) {
2566 cmdarg_err("Cannot register tap: %s", exp_pdu_error);
2567 g_free(exp_pdu_error);
2568 list_export_pdu_taps();
2569 exit_status = INVALID_TAP2;
2570 goto clean_exit;
2571 }
2572
2573 if (strcmp(exp_pdu_filename, "-") == 0) {
2574 /* Write to the standard output. */
2575 exp_fd = 1;
2576 } else {
2577 exp_fd = ws_openopen(exp_pdu_filename, O_WRONLY01 | O_CREAT0100 | O_TRUNC01000 | O_BINARY0, 0644);
2578 if (exp_fd == -1) {
2579 cmdarg_err("%s: %s", exp_pdu_filename, file_open_error_message(errno(*__errno_location ()), true1));
2580 exit_status = WS_EXIT_INVALID_FILE3;
2581 goto clean_exit;
2582 }
2583 }
2584
2585 /* Activate the export PDU tap */
2586 /* Write to our output file with this comment (if the type supports it,
2587 * otherwise exp_pdu_open() will ignore the comment) */
2588 comment = ws_strdup_printf("Dump of PDUs from %s", cf_name)wmem_strdup_printf(((void*)0), "Dump of PDUs from %s", cf_name
)
;
2589 exp_pdu_status = exp_pdu_open(&exp_pdu_tap_data, exp_pdu_filename,
2590 out_file_type, exp_fd, comment,
2591 &err, &err_info);
2592 g_free(comment);
2593 if (!exp_pdu_status) {
2594 report_cfile_dump_open_failure(exp_pdu_filename, err, err_info,
2595 out_file_type);
2596 exit_status = INVALID_EXPORT2;
2597 goto clean_exit;
2598 }
2599 }
2600
2601 if (cf_name) {
2602 ws_debug("tshark: Opening capture file: %s", cf_name)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 2602, __func__, "tshark: Opening capture file: %s", cf_name
); } } while (0)
;
2603 /*
2604 * We're reading a capture file.
2605 */
2606 if (cf_open(&cfile, cf_name, in_file_type, false0, &err) != CF_OK) {
2607 epan_cleanup();
2608 extcap_cleanup();
2609 exit_status = WS_EXIT_INVALID_FILE3;
2610 goto clean_exit;
2611 }
2612
2613 /* Start statistics taps; we do so after successfully opening the
2614 capture file, so we know we have something to compute stats
2615 on, and after registering all dissectors, so that MATE will
2616 have registered its field array so we can have a tap filter
2617 with one of MATE's late-registered fields as part of the
2618 filter. */
2619 if (!start_requested_stats()) {
2620 exit_status = WS_EXIT_INVALID_OPTION1;
2621 goto clean_exit;
2622 }
2623
2624 /* Do we need to do dissection of packets? That depends on, among
2625 other things, what taps are listening, so determine that after
2626 starting the statistics taps. */
2627 do_dissection = must_do_dissection(rfcode, dfcode, pdu_export_arg);
2628 ws_debug("tshark: do_dissection = %s", do_dissection ? "TRUE" : "FALSE")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 2628, __func__, "tshark: do_dissection = %s", do_dissection
? "TRUE" : "FALSE"); } } while (0)
;
2629
2630 /* Process the packets in the file */
2631 ws_debug("tshark: invoking process_cap_file() to process the packets")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 2631, __func__, "tshark: invoking process_cap_file() to process the packets"
); } } while (0)
;
2632 TRY{ except_t *volatile exc; volatile int except_state = 0; static
const except_id_t catch_spec[] = { { 1, 0 } }; { struct except_stacknode
except_sn; struct except_catch except_ch; except_setup_try(&
except_sn, &except_ch, catch_spec, 1); if (_setjmp (except_ch
.except_jmp)) *(&exc) = &except_ch.except_obj; else *
(&exc) = 0; if(except_state & 1) except_state |= 2; except_state
&= ~1; if (except_state == 0 && exc == 0)
{
2633 status = process_cap_file(&cfile, output_file_name, out_file_type, out_file_name_res,
2634#ifdef HAVE_LIBPCAP1
2635 global_capture_opts.has_autostop_packets ? global_capture_opts.autostop_packets : 0,
2636 global_capture_opts.has_autostop_filesize ? global_capture_opts.autostop_filesize : 0,
2637 global_capture_opts.has_autostop_written_packets ? global_capture_opts.autostop_written_packets : 0,
2638 compression_type);
2639#else
2640 max_packet_count,
2641 0,
2642 0,
2643 WS_FILE_UNCOMPRESSED);
2644#endif
2645 }
2646 CATCH(OutOfMemoryError)if (except_state == 0 && exc != 0 && exc->
except_id.except_code == (8) && (except_state |= 1))
{
2647 fprintf(stderrstderr,
2648 "Out Of Memory.\n"
2649 "\n"
2650 "Sorry, but TShark has to terminate now.\n"
2651 "\n"
2652 "More information and workarounds can be found at\n"
2653 WS_WIKI_URL("KnownBugs/OutOfMemory")"https://wiki.wireshark.org" "/" "KnownBugs/OutOfMemory" "\n");
2654 status = PROCESS_FILE_ERROR;
2655 }
2656 ENDTRYif(!(except_state&1) && exc != 0) except_rethrow(
exc); except_free(except_ch.except_obj.except_dyndata); except_pop
(); };}
;
2657
2658 switch (status) {
2659
2660 case PROCESS_FILE_SUCCEEDED:
2661 /* Everything worked OK; draw the taps. */
2662 draw_taps = true1;
2663 break;
2664
2665 case PROCESS_FILE_NO_FILE_PROCESSED:
2666 /* We never got to try to read the file, so there are no tap
2667 results to dump. Exit with an error status. */
2668 exit_status = 2;
2669 break;
2670
2671 case PROCESS_FILE_ERROR:
2672 /* We still dump out the results of taps, etc., as we might have
2673 read some packets; however, we exit with an error status. */
2674 draw_taps = true1;
2675 exit_status = 2;
2676 break;
2677
2678 case PROCESS_FILE_INTERRUPTED:
2679 /* The user interrupted the read process; Don't dump out the
2680 result of taps, etc., and exit with an error status. */
2681 exit_status = 2;
2682 break;
2683 }
2684
2685 if (pdu_export_arg) {
2686 if (!exp_pdu_close(&exp_pdu_tap_data, &err, &err_info)) {
2687 report_cfile_close_failure(exp_pdu_filename, err, err_info);
2688 exit_status = 2;
2689 }
2690 g_free(pdu_export_arg);
2691 g_free(exp_pdu_filename);
2692 }
2693 } else {
2694 ws_debug("tshark: no capture file specified")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 2694, __func__, "tshark: no capture file specified"); } } while
(0)
;
2695 /* No capture file specified, so we're supposed to do a live capture
2696 or get a list of link-layer types for a live capture device;
2697 do we have support for live captures? */
2698#ifdef HAVE_LIBPCAP1
2699#ifdef _WIN32
2700 /* Warn the user if npf.sys isn't loaded. */
2701 if (!npf_sys_is_running()) {
2702 fprintf(stderrstderr, "The NPF driver isn't running. You may have trouble "
2703 "capturing or\nlisting interfaces.\n");
2704 }
2705#endif /* _WIN32 */
2706
2707 /* if no interface was specified, pick a default */
2708 exit_status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2709 ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL((void*)0));
2710 if (exit_status != 0) {
2711 goto clean_exit;
2712 }
2713
2714 /*
2715 * If requested, list the link layer types and/or time stamp types
2716 * and exit.
2717 */
2718 if (caps_queries) {
2719 unsigned i;
2720
2721 /* Get the list of link-layer types for the capture devices. */
2722 exit_status = EXIT_SUCCESS0;
2723 GList *if_cap_queries = NULL((void*)0);
2724 if_cap_query_t *if_cap_query;
2725 GHashTable *capability_hash;
2726 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2727 interface_options *interface_opts;
2728 interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i)(((interface_options*) (void *) (global_capture_opts.ifaces)->
data) [(i)])
;
2729 if_cap_query = g_new(if_cap_query_t, 1)((if_cap_query_t *) g_malloc_n ((1), sizeof (if_cap_query_t))
)
;
2730 if_cap_query->name = interface_opts->name;
2731 if_cap_query->monitor_mode = interface_opts->monitor_mode;
2732 if_cap_query->auth_username = NULL((void*)0);
2733 if_cap_query->auth_password = NULL((void*)0);
2734#ifdef HAVE_PCAP_REMOTE
2735 if (interface_opts->auth_type == CAPTURE_AUTH_PWD) {
2736 if_cap_query->auth_username = interface_opts->auth_username;
2737 if_cap_query->auth_password = interface_opts->auth_password;
2738 }
2739#endif
2740 if_cap_queries = g_list_prepend(if_cap_queries, if_cap_query);
2741 }
2742 if_cap_queries = g_list_reverse(if_cap_queries);
2743 capability_hash = capture_get_if_list_capabilities(global_capture_opts.app_name, if_cap_queries, &err_str, &err_str_secondary, NULL((void*)0));
2744 g_list_free_full(if_cap_queries, g_free);
2745 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
2746 interface_options *interface_opts;
2747 interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i)(((interface_options*) (void *) (global_capture_opts.ifaces)->
data) [(i)])
;
2748 if_capabilities_t *caps;
2749 caps = g_hash_table_lookup(capability_hash, interface_opts->name);
2750 if (caps == NULL((void*)0)) {
2751 cmdarg_err("%s%s%s", err_str, err_str_secondary ? "\n" : "", err_str_secondary ? err_str_secondary : "");
2752 g_free(err_str);
2753 g_free(err_str_secondary);
2754 exit_status = WS_EXIT_INVALID_CAPABILITY5;
2755 break;
2756 }
2757 exit_status = capture_opts_print_if_capabilities(caps, interface_opts,
2758 caps_queries);
2759 if (exit_status != EXIT_SUCCESS0) {
2760 break;
2761 }
2762 }
2763 g_hash_table_destroy(capability_hash);
2764 goto clean_exit;
2765 }
2766
2767 /*
2768 * If the standard error isn't a terminal, don't print packet counts,
2769 * as they won't show up on the user's terminal and they'll get in
2770 * the way of error messages in the file (to which we assume the
2771 * standard error was redirected; if it's redirected to the null
2772 * device, there's no point in printing packet counts anyway).
2773 *
2774 * Otherwise, if we're printing packet information and the standard
2775 * output is a terminal (which we assume means the standard output and
2776 * error are going to the same terminal), don't print packet counts,
2777 * as they'll get in the way of the packet information.
2778 *
2779 * Otherwise, if the user specified -q, don't print packet counts.
2780 *
2781 * Otherwise, print packet counts.
2782 *
2783 * XXX - what if the user wants to do a live capture, doesn't want
2784 * to save it to a file, doesn't want information printed for each
2785 * packet, does want some "-z" statistic, and wants packet counts
2786 * so they know whether they're seeing any packets? -q will
2787 * suppress the information printed for each packet, but it'll
2788 * also suppress the packet counts.
2789 */
2790 if (!ws_isattyisatty(ws_filenofileno(stderrstderr)))
2791 print_packet_counts = false0;
2792 else if (print_packet_info && ws_isattyisatty(ws_filenofileno(stdoutstdout)))
2793 print_packet_counts = false0;
2794 else if (quiet)
2795 print_packet_counts = false0;
2796 else
2797 print_packet_counts = true1;
2798
2799 ws_debug("tshark: performing live capture")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 2799, __func__, "tshark: performing live capture"); } } while
(0)
;
2800
2801 /* Start statistics taps; we should only do so after the capture
2802 started successfully, so we know we have something to compute
2803 stats, but we currently don't check for that - see below.
2804
2805 We do so after registering all dissectors, so that MATE will
2806 have registered its field array so we can have a tap filter
2807 with one of MATE's late-registered fields as part of the
2808 filter. */
2809 if (!start_requested_stats()) {
2810 exit_status = WS_EXIT_INVALID_OPTION1;
2811 goto clean_exit;
2812 }
2813
2814 /* Do we need to do dissection of packets? That depends on, among
2815 other things, what taps are listening, so determine that after
2816 starting the statistics taps. */
2817 do_dissection = must_do_dissection(rfcode, dfcode, pdu_export_arg);
2818 ws_debug("tshark: do_dissection = %s", do_dissection ? "TRUE" : "FALSE")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 2818, __func__, "tshark: do_dissection = %s", do_dissection
? "TRUE" : "FALSE"); } } while (0)
;
2819
2820 /* We're doing live capture; if the capture child is writing to a pipe,
2821 we can't do dissection, because that would mean two readers for
2822 the pipe, tshark and whatever else. */
2823 if (do_dissection && global_capture_opts.output_to_pipe) {
2824 if (tap_listeners_require_dissection()) {
2825 cmdarg_err("Taps aren't supported when capturing and saving to a pipe.");
2826 exit_status = WS_EXIT_INVALID_OPTION1;
2827 goto clean_exit;
2828 }
2829 if (print_packet_info) {
2830 cmdarg_err("Printing dissected packets isn't supported when capturing and saving to a pipe.");
2831 exit_status = WS_EXIT_INVALID_OPTION1;
2832 goto clean_exit;
2833 }
2834 /* We already checked the next three reasons for supersets of
2835 capturing and saving to a pipe, but this doesn't hurt. */
2836 if (pdu_export_arg) {
2837 cmdarg_err("PDUs export isn't supported when capturing and saving to a pipe.");
2838 exit_status = WS_EXIT_INVALID_OPTION1;
2839 goto clean_exit;
2840 }
2841 if (rfcode != NULL((void*)0)) {
2842 cmdarg_err("Read filters aren't supported when capturing and saving to a pipe.");
2843 exit_status = WS_EXIT_INVALID_OPTION1;
2844 goto clean_exit;
2845 }
2846 if (dfcode != NULL((void*)0)) {
2847 cmdarg_err("Display filters aren't supported when capturing and saving to a pipe.");
2848 exit_status = WS_EXIT_INVALID_OPTION1;
2849 goto clean_exit;
2850 }
2851 /* There's some other reason we're dissecting. */
2852 cmdarg_err("Dissection isn't supported when capturing and saving to a pipe.");
2853 exit_status = WS_EXIT_INVALID_OPTION1;
2854 goto clean_exit;
2855 }
2856
2857 /* Write a preamble if we're printing one. Do this after all checking
2858 * for invalid options, so we don't print just a preamble and quit. */
2859 if (print_packet_info) {
2860 if (!write_preamble(&cfile)) {
2861 show_print_file_io_error();
2862 exit_status = WS_EXIT_INVALID_FILE3;
2863 goto clean_exit;
2864 }
2865 }
2866
2867 /*
2868 * XXX - this returns false if an error occurred, but it also
2869 * returns false if the capture stops because a time limit
2870 * was reached (and possibly other limits), so we can't assume
2871 * it means an error.
2872 *
2873 * The capture code is a bit twisty, so it doesn't appear to
2874 * be an easy fix. We just ignore the return value for now.
2875 * Instead, pass on the exit status from the capture child.
2876 */
2877 capture();
2878 exit_status = global_capture_session.fork_child_status;
2879
2880 if (print_packet_info) {
2881 if (!write_finale()) {
2882 show_print_file_io_error();
2883 }
2884 }
2885
2886 /*
2887 * If we never got a capture file, don't draw the taps; we not only
2888 * didn't capture any packets, we never even did any capturing.
2889 */
2890 if (cfile.filename != NULL((void*)0))
2891 draw_taps = true1;
2892#else
2893 /* No - complain. */
2894 cmdarg_err("This version of TShark was not built with support for capturing packets.");
2895 exit_status = INVALID_CAPTURE2;
2896 goto clean_exit;
2897#endif
2898 }
2899
2900 if (cfile.provider.frames != NULL((void*)0)) {
2901 free_frame_data_sequence(cfile.provider.frames);
2902 cfile.provider.frames = NULL((void*)0);
2903 }
2904
2905 if (draw_taps)
2906 draw_tap_listeners(true1);
2907
2908 if (tls_session_keys_file) {
2909 size_t keylist_length = 0;
2910 unsigned num_keys = 0;
2911 char* keylist = NULL((void*)0);
2912 secrets_export_values ret = secrets_export("TLS", &keylist, &keylist_length, &num_keys);
2913 if ((ret == SECRETS_EXPORT_SUCCESS) && (keylist_length > 0))
2914 write_file_binary_mode(tls_session_keys_file, keylist, keylist_length);
2915 g_free(keylist);
2916 }
2917
2918 if (opt_print_timers) {
2919 if (cf_name == NULL((void*)0)) {
2920 /* We're doing a live capture. That isn't currently supported
2921 * with timers. */
2922 ws_message("Ignoring option --print-timers because we are doing a live capture")do { if (1) { ws_log_full("Main", LOG_LEVEL_MESSAGE, ((void*)
0), -1, ((void*)0), "Ignoring option --print-timers because we are doing a live capture"
); } } while (0)
;
2923 }
2924 else {
2925 print_elapsed_json(cf_name, dfilter);
2926 }
2927 }
2928
2929 /* Memory cleanup */
2930 reset_tap_listeners();
2931 funnel_dump_all_text_windows();
2932 epan_free(cfile.epan);
2933 epan_cleanup();
2934 extcap_cleanup();
2935
2936 output_fields_free(output_fields);
2937 output_fields = NULL((void*)0);
2938
2939clean_exit:
2940 cf_close(&cfile);
2941 g_free(cf_name);
2942 destroy_print_stream(print_stream);
2943 g_free(output_file_name);
2944#ifdef HAVE_LIBPCAP1
2945 capture_opts_cleanup(&global_capture_opts);
2946 if (cached_if_list) {
2947 free_interface_list(cached_if_list);
2948 }
2949#endif
2950 col_cleanup(&cfile.cinfo);
2951 wtap_cleanup();
2952 free_progdirs();
2953 dfilter_free(dfcode);
2954 g_free(dfilter);
2955 return exit_status;
2956}
2957
2958bool_Bool loop_running;
2959uint32_t packet_count;
2960
2961static epan_t *
2962tshark_epan_new(capture_file *cf)
2963{
2964 static const struct packet_provider_funcs funcs = {
2965 cap_file_provider_get_frame_ts,
2966 cap_file_provider_get_start_ts,
2967 cap_file_provider_get_end_ts,
2968 cap_file_provider_get_interface_name,
2969 cap_file_provider_get_interface_description,
2970 NULL((void*)0),
2971 cap_file_provider_get_process_id,
2972 cap_file_provider_get_process_name,
2973 cap_file_provider_get_process_uuid,
2974 };
2975
2976 return epan_new(&cf->provider, &funcs);
2977}
2978
2979#ifdef HAVE_LIBPCAP1
2980static bool_Bool
2981capture(void)
2982{
2983 GString *str;
2984 GMainContext *ctx;
2985#ifndef _WIN32
2986 struct sigaction action, oldaction;
2987#endif
2988
2989 /* Create new dissection section. */
2990 epan_free(cfile.epan);
2991 cfile.epan = tshark_epan_new(&cfile);
2992
2993#ifdef _WIN32
2994 /* Catch a CTRL+C event and, if we get it, clean up and exit. */
2995 SetConsoleCtrlHandler(capture_cleanup, true1);
2996#else /* _WIN32 */
2997 /* Catch SIGINT and SIGTERM and, if we get either of them,
2998 clean up and exit. If SIGHUP isn't being ignored, catch
2999 it too and, if we get it, clean up and exit.
3000
3001 We restart any read that was in progress, so that it doesn't
3002 disrupt reading from the sync pipe. The signal handler tells
3003 the capture child to finish; it will report that it finished,
3004 or will exit abnormally, so we'll stop reading from the sync
3005 pipe, pick up the exit status, and quit. */
3006 memset(&action, 0, sizeof(action));
3007 action.sa_handler__sigaction_handler.sa_handler = capture_cleanup;
3008 action.sa_flags = SA_RESTART0x10000000;
3009 sigemptyset(&action.sa_mask);
3010 sigaction(SIGTERM15, &action, NULL((void*)0));
3011 sigaction(SIGINT2, &action, NULL((void*)0));
3012 sigaction(SIGHUP1, NULL((void*)0), &oldaction);
3013 if (oldaction.sa_handler__sigaction_handler.sa_handler == SIG_DFL((__sighandler_t) 0))
3014 sigaction(SIGHUP1, &action, NULL((void*)0));
3015
3016#ifdef SIGINFO
3017 /* Catch SIGINFO and, if we get it and we're capturing to a file in
3018 quiet mode, report the number of packets we've captured.
3019
3020 Again, restart any read that was in progress, so that it doesn't
3021 disrupt reading from the sync pipe. */
3022 action.sa_handler__sigaction_handler.sa_handler = report_counts_siginfo;
3023 action.sa_flags = SA_RESTART0x10000000;
3024 sigemptyset(&action.sa_mask);
3025 sigaction(SIGINFO, &action, NULL((void*)0));
3026#endif /* SIGINFO */
3027#endif /* _WIN32 */
3028
3029 global_capture_session.state = CAPTURE_PREPARING;
3030
3031 /* Let the user know which interfaces were chosen. */
3032 str = get_iface_list_string(&global_capture_opts, IFLIST_QUOTE_IF_DESCRIPTION0x00000001);
3033 if (really_quiet == false0)
3034 fprintf(stderrstderr, "Capturing on %s\n", str->str);
3035 fflush(stderrstderr);
3036 g_string_free(str, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(str), ((!(0)))) : g_string_free_and_steal (str)) : (g_string_free
) ((str), ((!(0)))))
;
3037
3038 if (!sync_pipe_start(&global_capture_opts, capture_comments,
3039 &global_capture_session, &global_info_data, NULL((void*)0)))
3040 return false0;
3041
3042 /*
3043 * Force synchronous resolution of IP addresses; we're doing only
3044 * one pass, so we can't do it in the background and fix up past
3045 * dissections.
3046 */
3047 set_resolution_synchrony(true1);
3048
3049 /* the actual capture loop */
3050 ctx = g_main_context_default();
3051 loop_running = true1;
3052
3053 TRY{ except_t *volatile exc; volatile int except_state = 0; static
const except_id_t catch_spec[] = { { 1, 0 } }; { struct except_stacknode
except_sn; struct except_catch except_ch; except_setup_try(&
except_sn, &except_ch, catch_spec, 1); if (_setjmp (except_ch
.except_jmp)) *(&exc) = &except_ch.except_obj; else *
(&exc) = 0; if(except_state & 1) except_state |= 2; except_state
&= ~1; if (except_state == 0 && exc == 0)
3054 {
3055 while (loop_running)
3056 {
3057 g_main_context_iteration(ctx, true1);
3058 }
3059 }
3060 CATCH(OutOfMemoryError)if (except_state == 0 && exc != 0 && exc->
except_id.except_code == (8) && (except_state |= 1))
{
3061 fprintf(stderrstderr,
3062 "Out Of Memory.\n"
3063 "\n"
3064 "Sorry, but TShark has to terminate now.\n"
3065 "\n"
3066 "More information and workarounds can be found at\n"
3067 WS_WIKI_URL("KnownBugs/OutOfMemory")"https://wiki.wireshark.org" "/" "KnownBugs/OutOfMemory" "\n");
3068 abort();
3069 }
3070 ENDTRYif(!(except_state&1) && exc != 0) except_rethrow(
exc); except_free(except_ch.except_obj.except_dyndata); except_pop
(); };}
;
3071 return true1;
3072}
3073
3074/* capture child detected an error */
3075static void
3076capture_input_error(capture_session *cap_session _U___attribute__((unused)), char *error_msg, char *secondary_error_msg)
3077{
3078 /* The primary message might be an empty string, e.g. when the error was
3079 * from extcap. (The extcap stderr is gathered when the session closes
3080 * and printed in capture_input_closed below.) */
3081 if (*error_msg != '\0') {
3082 cmdarg_err("%s", error_msg);
3083 if (secondary_error_msg != NULL((void*)0) && *secondary_error_msg != '\0') {
3084 /* We have both primary and secondary messages. */
3085 cmdarg_err_cont("%s", secondary_error_msg);
3086 }
3087 }
3088}
3089
3090
3091/* capture child detected an capture filter related error */
3092static void
3093capture_input_cfilter_error(capture_session *cap_session, unsigned i, const char *error_message)
3094{
3095 capture_options *capture_opts = cap_session->capture_opts;
3096 dfilter_t *rfcode = NULL((void*)0);
3097 interface_options *interface_opts;
3098
3099 ws_assert(i < capture_opts->ifaces->len)do { if ((1) && !(i < capture_opts->ifaces->
len)) ws_log_fatal_full("Main", LOG_LEVEL_ERROR, "tshark.c", 3099
, __func__, "assertion failed: %s", "i < capture_opts->ifaces->len"
); } while (0)
;
3100 interface_opts = &g_array_index(capture_opts->ifaces, interface_options, i)(((interface_options*) (void *) (capture_opts->ifaces)->
data) [(i)])
;
3101
3102 if (dfilter_compile(interface_opts->cfilter, &rfcode, NULL)dfilter_compile_full(interface_opts->cfilter, &rfcode,
((void*)0), (1U << 1)|(1U << 2), __func__)
&& rfcode != NULL((void*)0)) {
3103 cmdarg_err(
3104 "Invalid capture filter \"%s\" for interface '%s'.\n"
3105 "\n"
3106 "That string looks like a valid display filter; however, it isn't a valid\n"
3107 "capture filter (%s).\n"
3108 "\n"
3109 "Note that display filters and capture filters don't have the same syntax,\n"
3110 "so you can't use most display filter expressions as capture filters.\n"
3111 "\n"
3112 "See the User's Guide for a description of the capture filter syntax.",
3113 interface_opts->cfilter, interface_opts->descr, error_message);
3114 dfilter_free(rfcode);
3115 } else {
3116 cmdarg_err(
3117 "Invalid capture filter \"%s\" for interface '%s'.\n"
3118 "\n"
3119 "That string isn't a valid capture filter (%s).\n"
3120 "See the User's Guide for a description of the capture filter syntax.",
3121 interface_opts->cfilter, interface_opts->descr, error_message);
3122 }
3123}
3124
3125
3126/* capture child tells us we have a new (or the first) capture file */
3127static bool_Bool
3128capture_input_new_file(capture_session *cap_session, char *new_file)
3129{
3130 capture_options *capture_opts = cap_session->capture_opts;
3131 capture_file *cf = cap_session->cf;
3132 bool_Bool is_tempfile;
3133 int err;
3134
3135 if (really_quiet == false0) {
3136 if (cap_session->state == CAPTURE_PREPARING) {
3137 ws_info("Capture started.")do { if (1) { ws_log_full("Main", LOG_LEVEL_INFO, ((void*)0),
-1, ((void*)0), "Capture started."); } } while (0)
;
3138 }
3139 ws_info("File: \"%s\"", new_file)do { if (1) { ws_log_full("Main", LOG_LEVEL_INFO, ((void*)0),
-1, ((void*)0), "File: \"%s\"", new_file); } } while (0)
;
3140 }
3141
3142 ws_assert(cap_session->state == CAPTURE_PREPARING || cap_session->state == CAPTURE_RUNNING)do { if ((1) && !(cap_session->state == CAPTURE_PREPARING
|| cap_session->state == CAPTURE_RUNNING)) ws_log_fatal_full
("Main", LOG_LEVEL_ERROR, "tshark.c", 3142, __func__, "assertion failed: %s"
, "cap_session->state == CAPTURE_PREPARING || cap_session->state == CAPTURE_RUNNING"
); } while (0)
;
3143
3144 /* free the old filename */
3145 if (capture_opts->save_file != NULL((void*)0)) {
3146
3147 /* we start a new capture file, close the old one (if we had one before) */
3148 if (cf->state != FILE_CLOSED) {
3149 cf_close(cf);
3150 }
3151
3152 g_free(capture_opts->save_file);
3153 is_tempfile = false0;
3154
3155 epan_free(cf->epan);
3156 cf->epan = tshark_epan_new(cf);
3157 } else {
3158 /* we didn't had a save_file before, must be a tempfile */
3159 is_tempfile = true1;
3160 }
3161
3162 /* save the new filename */
3163 capture_opts->save_file = g_strdup(new_file)g_strdup_inline (new_file);
3164
3165 /* if we are in real-time mode, open the new file now */
3166 if (do_dissection) {
3167 /* this is probably unnecessary, but better safe than sorry */
3168 cap_session->cf->open_type = WTAP_TYPE_AUTO0;
3169 /* Attempt to open the capture file and set up to read from it. */
3170 switch(cf_open(cap_session->cf, capture_opts->save_file, WTAP_TYPE_AUTO0, is_tempfile, &err)) {
3171 case CF_OK:
3172 break;
3173 case CF_ERROR:
3174 /* Don't unlink (delete) the save file - leave it around,
3175 for debugging purposes. */
3176 g_free(capture_opts->save_file);
3177 capture_opts->save_file = NULL((void*)0);
3178 return false0;
3179 }
3180 } else if (quiet && is_tempfile) {
3181 cf->state = FILE_READ_ABORTED;
3182 cf->filename = g_strdup(new_file)g_strdup_inline (new_file);
3183 cf->is_tempfile = is_tempfile;
3184 }
3185
3186 cap_session->state = CAPTURE_RUNNING;
3187
3188 return true1;
3189}
3190
3191
3192/* capture child tells us we have new packets to read */
3193static void
3194capture_input_new_packets(capture_session *cap_session, int to_read)
3195{
3196 bool_Bool ret;
3197 int err;
3198 char *err_info;
3199 int64_t data_offset;
3200 capture_file *cf = cap_session->cf;
3201 bool_Bool filtering_tap_listeners;
3202 unsigned tap_flags;
3203
3204#ifdef SIGINFO
3205 /*
3206 * Prevent a SIGINFO handler from writing to the standard error while
3207 * we're doing so or writing to the standard output; instead, have it
3208 * just set a flag telling us to print that information when we're done.
3209 */
3210 infodelay = true1;
3211#endif /* SIGINFO */
3212
3213 /* Do we have any tap listeners with filters? */
3214 filtering_tap_listeners = have_filtering_tap_listeners();
3215
3216 /* Get the union of the flags for all tap listeners. */
3217 tap_flags = union_of_tap_listener_flags();
3218
3219 if (do_dissection) {
3220 bool_Bool create_proto_tree;
3221 epan_dissect_t *edt;
3222 wtap_rec rec;
3223
3224 /*
3225 * Determine whether we need to create a protocol tree.
3226 * We do if:
3227 *
3228 * we're going to apply a read filter;
3229 *
3230 * we're going to apply a display filter;
3231 *
3232 * we're going to print the protocol tree;
3233 *
3234 * one of the tap listeners is going to apply a filter;
3235 *
3236 * one of the tap listeners requires a protocol tree;
3237 *
3238 * a postdissector wants field values or protocols
3239 * on the first pass;
3240 *
3241 * we have custom columns (which require field values, which
3242 * currently requires that we build a protocol tree).
3243 */
3244 create_proto_tree =
3245 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
3246 (tap_flags & TL_REQUIRES_PROTO_TREE0x00000001) || postdissectors_want_hfids() ||
3247 have_custom_cols(&cf->cinfo) || dissect_color);
3248
3249 /* The protocol tree will be "visible", i.e., nothing faked, only if
3250 we're printing packet details, which is true if we're printing stuff
3251 ("print_packet_info" is true) and we're in verbose mode
3252 ("packet_details" is true). But if we specified certain fields with
3253 "-e", we'll prime those directly later. */
3254 bool_Bool visible = print_packet_info && print_details && output_fields_num_fields(output_fields) == 0;
3255 edt = epan_dissect_new(cf->epan, create_proto_tree, visible);
3256
3257 wtap_rec_init(&rec, DEFAULT_INIT_BUFFER_SIZE_2048(2 * 1024));
3258
3259 while (to_read-- && cf->provider.wth) {
3260 wtap_cleareof(cf->provider.wth);
3261 ret = wtap_read(cf->provider.wth, &rec, &err, &err_info, &data_offset);
3262 reset_epan_mem(cf, edt, create_proto_tree, print_packet_info && print_details);
3263 if (ret == false0) {
3264 /* Read from file failed; tell the capture child to stop.
3265 XXX - report this error? */
3266 sync_pipe_stop(cap_session);
3267 wtap_close(cf->provider.wth);
3268 cf->provider.wth = NULL((void*)0);
3269 } else {
3270 /*
3271 * The packet was successfully read; process it.
3272 */
3273 switch (process_packet_single_pass(cf, edt, data_offset, &rec,
3274 tap_flags)) {
3275
3276 case PROCESS_PACKET_PASSED:
3277 /* Either there's no read filtering or this packet
3278 passed the filter, and, if we were supposed to
3279 print dissection information, we did so successfully. */
3280 packet_count++;
3281 ret = true1;
Value stored to 'ret' is never read
3282 break;
3283
3284 case PROCESS_PACKET_DIDNT_PASS:
3285 /* There is read filtering and this packet didn't pass
3286 the filter. */
3287 ret = false0;
3288 break;
3289
3290 case PROCESS_PACKET_PRINT_ERROR:
3291 /* Either here's no read filtering or this packet passed
3292 the read filter, and we tried to print dissection
3293 informaion, but that failed. We've already reported
3294 the error, unless it was EPIPE, in which case we just
3295 silently quit; tell the capture child to stop. */
3296 sync_pipe_stop(cap_session);
3297 wtap_close(cf->provider.wth);
3298 cf->provider.wth = NULL((void*)0);
3299 }
3300 }
3301 wtap_rec_reset(&rec);
3302 }
3303
3304 epan_dissect_free(edt);
3305
3306 wtap_rec_cleanup(&rec);
3307
3308 } else {
3309 /*
3310 * Dumpcap's doing all the work; we're not doing any dissection.
3311 * Count all the packets it wrote.
3312 */
3313 packet_count += to_read;
3314 }
3315
3316 if (print_packet_counts) {
3317 /* We're printing packet counts. */
3318 if (packet_count != 0) {
3319 fprintf(stderrstderr, "\r%u ", packet_count);
3320 /* stderr could be line buffered */
3321 fflush(stderrstderr);
3322 }
3323 }
3324
3325#ifdef SIGINFO
3326 /*
3327 * Allow SIGINFO handlers to write.
3328 */
3329 infodelay = false0;
3330
3331 /*
3332 * If a SIGINFO handler asked us to write out capture counts, do so.
3333 */
3334 if (infoprint)
3335 report_counts();
3336#endif /* SIGINFO */
3337}
3338
3339static void
3340report_counts(void)
3341{
3342 if ((print_packet_counts == false0) && (really_quiet == false0)) {
3343 /* Report the count only if we aren't printing a packet count
3344 as packets arrive. */
3345 fprintf(stderrstderr, "%u packet%s captured\n", packet_count,
3346 plurality(packet_count, "", "s")((packet_count) == 1 ? ("") : ("s")));
3347 }
3348#ifdef SIGINFO
3349 infoprint = false0; /* we just reported it */
3350#endif /* SIGINFO */
3351}
3352
3353#ifdef SIGINFO
3354static void
3355report_counts_siginfo(int signum _U___attribute__((unused)))
3356{
3357 int sav_errno = errno(*__errno_location ());
3358 /* If we've been told to delay printing, just set a flag asking
3359 that we print counts (if we're supposed to), otherwise print
3360 the count of packets captured (if we're supposed to). */
3361 if (infodelay)
3362 infoprint = true1;
3363 else
3364 report_counts();
3365 errno(*__errno_location ()) = sav_errno;
3366}
3367#endif /* SIGINFO */
3368
3369
3370/* capture child detected any packet drops? */
3371static void
3372capture_input_drops(capture_session *cap_session _U___attribute__((unused)), uint32_t dropped, const char* interface_name)
3373{
3374 if (print_packet_counts) {
3375 /* We're printing packet counts to stderr.
3376 Send a newline so that we move to the line after the packet count. */
3377 fprintf(stderrstderr, "\n");
3378 }
3379
3380 if (dropped != 0) {
3381 /* We're printing packet counts to stderr.
3382 Send a newline so that we move to the line after the packet count. */
3383 if (interface_name != NULL((void*)0)) {
3384 fprintf(stderrstderr, "%u packet%s dropped from %s\n", dropped, plurality(dropped, "", "s")((dropped) == 1 ? ("") : ("s")), interface_name);
3385 } else {
3386 fprintf(stderrstderr, "%u packet%s dropped\n", dropped, plurality(dropped, "", "s")((dropped) == 1 ? ("") : ("s")));
3387 }
3388 }
3389}
3390
3391
3392/*
3393 * Capture child closed its side of the pipe, report any error and
3394 * do the required cleanup.
3395 */
3396static void
3397capture_input_closed(capture_session *cap_session _U___attribute__((unused)), char *msg)
3398{
3399 if (msg != NULL((void*)0) && *msg != '\0')
3400 fprintf(stderrstderr, "tshark: %s\n", msg);
3401
3402 report_counts();
3403
3404 loop_running = false0;
3405}
3406
3407#ifdef _WIN32
3408static BOOL WINAPI
3409capture_cleanup(DWORD ctrltype _U___attribute__((unused)))
3410{
3411 /* CTRL_C_EVENT is sort of like SIGINT, CTRL_BREAK_EVENT is unique to
3412 Windows, CTRL_CLOSE_EVENT is sort of like SIGHUP, CTRL_LOGOFF_EVENT
3413 is also sort of like SIGHUP, and CTRL_SHUTDOWN_EVENT is sort of
3414 like SIGTERM at least when the machine's shutting down.
3415
3416 For now, we handle them all as indications that we should clean up
3417 and quit, just as we handle SIGINT, SIGHUP, and SIGTERM in that
3418 way on UNIX.
3419
3420 We must return true so that no other handler - such as one that would
3421 terminate the process - gets called.
3422
3423 XXX - for some reason, typing ^C to TShark, if you run this in
3424 a Cygwin console window in at least some versions of Cygwin,
3425 causes TShark to terminate immediately; this routine gets
3426 called, but the main loop doesn't get a chance to run and
3427 exit cleanly, at least if this is compiled with Microsoft Visual
3428 C++ (i.e., it's a property of the Cygwin console window or Bash;
3429 it happens if TShark is not built with Cygwin - for all I know,
3430 building it with Cygwin may make the problem go away). */
3431
3432 /* tell the capture child to stop */
3433 sync_pipe_stop(&global_capture_session);
3434
3435 /* don't stop our own loop already here, otherwise status messages and
3436 * cleanup wouldn't be done properly. The child will indicate the stop of
3437 * everything by calling capture_input_closed() later */
3438
3439 return true1;
3440}
3441#else
3442static void
3443capture_cleanup(int signum _U___attribute__((unused)))
3444{
3445 /* tell the capture child to stop */
3446 sync_pipe_stop(&global_capture_session);
3447
3448 /* don't stop our own loop already here, otherwise status messages and
3449 * cleanup wouldn't be done properly. The child will indicate the stop of
3450 * everything by calling capture_input_closed() later */
3451}
3452#endif /* _WIN32 */
3453#endif /* HAVE_LIBPCAP */
3454
3455static bool_Bool
3456process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
3457 int64_t offset, wtap_rec *rec)
3458{
3459 frame_data fdlocal;
3460 uint32_t framenum;
3461 bool_Bool passed;
3462 int64_t elapsed_start;
3463
3464 /* The frame number of this packet is one more than the count of
3465 frames in this packet. */
3466 framenum = cf->count + 1;
3467
3468 /* If we're not running a display filter and we're not printing any
3469 packet information, we don't need to do a dissection. This means
3470 that all packets can be marked as 'passed'. */
3471 passed = true1;
3472
3473 frame_data_init(&fdlocal, framenum, rec, offset, cum_bytes);
3474
3475 /* If we're going to run a read filter or a display filter, set up to
3476 do a dissection and do so. (This is the first pass of two passes
3477 over the packets, so we will not be printing any information
3478 from the dissection or running taps on the packet; if we're doing
3479 any of that, we'll do it in the second pass.) */
3480 if (edt) {
3481 if (gbl_resolv_flags.network_name || gbl_resolv_flags.maxmind_geoip) {
3482 /* If we're doing async lookups, send any that are queued and
3483 * retrieve results.
3484 *
3485 * Ideally we'd force any lookups that need to happen on the second pass
3486 * to be sent asynchronously on this pass so the results would be ready.
3487 * That will happen if they're involved in a filter (because we prime the
3488 * tree below), but not currently for taps, if we're printing packet
3489 * summaries or details, etc.
3490 *
3491 * XXX - If we're running a read filter that depends on a resolved
3492 * name, we should be doing synchronous lookups in that case. Also
3493 * marking the dependent frames below might not work with a display
3494 * filter that depends on a resolved name.
3495 */
3496 host_name_lookup_process();
3497 }
3498
3499 column_info *cinfo = NULL((void*)0);
3500
3501 /* If we're running a read filter, prime the epan_dissect_t with that
3502 filter. */
3503 if (cf->rfcode)
3504 epan_dissect_prime_with_dfilter(edt, cf->rfcode);
3505
3506 if (cf->dfcode)
3507 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
3508
3509 frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
3510 &cf->provider.ref, cf->provider.prev_dis);
3511 if (cf->provider.ref == &fdlocal) {
3512 ref_frame = fdlocal;
3513 cf->provider.ref = &ref_frame;
3514 }
3515
3516 /* If we're applying a filter that needs the columns, construct them. */
3517 if (dfilter_requires_columns(cf->rfcode) || dfilter_requires_columns(cf->dfcode)) {
3518 cinfo = &cf->cinfo;
3519 }
3520
3521 elapsed_start = g_get_monotonic_time();
3522 epan_dissect_run(edt, cf->cd_t, rec, &fdlocal, cinfo);
3523 tshark_elapsed.first_pass.dissect += g_get_monotonic_time() - elapsed_start;
3524
3525 /* Run the read filter if we have one. */
3526 if (cf->rfcode) {
3527 elapsed_start = g_get_monotonic_time();
3528 passed = dfilter_apply_edt(cf->rfcode, edt);
3529 tshark_elapsed.first_pass.dfilter_read += g_get_monotonic_time() - elapsed_start;
3530 }
3531 }
3532
3533 if (passed) {
3534 frame_data_set_after_dissect(&fdlocal, &cum_bytes);
3535 cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
3536
3537 /* If we're not doing dissection then there won't be any dependent frames.
3538 * More importantly, edt.pi.fd.dependent_frames won't be initialized because
3539 * epan hasn't been initialized.
3540 * if we *are* doing dissection, then mark the dependent frames, but only
3541 * if a display filter was given and it matches this packet.
3542 */
3543 if (edt && cf->dfcode) {
3544 elapsed_start = g_get_monotonic_time();
3545 if (dfilter_apply_edt(cf->dfcode, edt) && edt->pi.fd->dependent_frames) {
3546 g_hash_table_foreach(edt->pi.fd->dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
3547 }
3548
3549 if (selected_frame_number != 0 && selected_frame_number == cf->count + 1) {
3550 /* If we are doing dissection and we have a "selected frame"
3551 * then load that frame's references (if any) onto the compiled
3552 * display filter. Selected frame number is ordinal, count is cardinal. */
3553 dfilter_load_field_references(cf->dfcode, edt->tree);
3554 }
3555 tshark_elapsed.first_pass.dfilter_filter += g_get_monotonic_time() - elapsed_start;
3556 }
3557
3558 cf->count++;
3559 } else {
3560 /* if we don't add it to the frame_data_sequence, clean it up right now
3561 * to avoid leaks */
3562 frame_data_destroy(&fdlocal);
3563 }
3564
3565 if (edt)
3566 epan_dissect_reset(edt);
3567
3568 return passed;
3569}
3570
3571/*
3572 * Set if reading a file was interrupted by a CTRL_ event on Windows or
3573 * a signal on UN*X.
3574 */
3575static bool_Bool read_interrupted;
3576
3577#ifdef _WIN32
3578static BOOL WINAPI
3579read_cleanup(DWORD ctrltype _U___attribute__((unused)))
3580{
3581 /* CTRL_C_EVENT is sort of like SIGINT, CTRL_BREAK_EVENT is unique to
3582 Windows, CTRL_CLOSE_EVENT is sort of like SIGHUP, CTRL_LOGOFF_EVENT
3583 is also sort of like SIGHUP, and CTRL_SHUTDOWN_EVENT is sort of
3584 like SIGTERM at least when the machine's shutting down.
3585
3586 For now, we handle them all as indications that we should clean up
3587 and quit, just as we handle SIGINT, SIGHUP, and SIGTERM in that
3588 way on UNIX.
3589
3590 We must return true so that no other handler - such as one that would
3591 terminate the process - gets called.
3592
3593 XXX - for some reason, typing ^C to TShark, if you run this in
3594 a Cygwin console window in at least some versions of Cygwin,
3595 causes TShark to terminate immediately; this routine gets
3596 called, but the main loop doesn't get a chance to run and
3597 exit cleanly, at least if this is compiled with Microsoft Visual
3598 C++ (i.e., it's a property of the Cygwin console window or Bash;
3599 it happens if TShark is not built with Cygwin - for all I know,
3600 building it with Cygwin may make the problem go away). */
3601
3602 /* tell the read to stop */
3603 read_interrupted = true1;
3604
3605 return true1;
3606}
3607#else
3608static void
3609read_cleanup(int signum _U___attribute__((unused)))
3610{
3611 /* tell the read to stop */
3612 read_interrupted = true1;
3613}
3614#endif /* _WIN32 */
3615
3616typedef enum {
3617 PASS_SUCCEEDED,
3618 PASS_READ_ERROR,
3619 PASS_WRITE_ERROR,
3620 PASS_PRINT_ERROR,
3621 PASS_INTERRUPTED
3622} pass_status_t;
3623
3624static pass_status_t
3625process_cap_file_first_pass(capture_file *cf, int max_packet_count,
3626 int64_t max_byte_count, int *err, char **err_info)
3627{
3628 wtap_rec rec;
3629 epan_dissect_t *edt = NULL((void*)0);
3630 int64_t data_offset;
3631 pass_status_t status = PASS_SUCCEEDED;
3632 int framenum = 0;
3633
3634 wtap_rec_init(&rec, DEFAULT_INIT_BUFFER_SIZE_2048(2 * 1024));
3635
3636 /* Allocate a frame_data_sequence for all the frames. */
3637 cf->provider.frames = new_frame_data_sequence();
3638
3639 if (do_dissection) {
3640 bool_Bool create_proto_tree;
3641
3642 /*
3643 * Determine whether we need to create a protocol tree.
3644 * We do if:
3645 *
3646 * we're going to apply a read filter;
3647 *
3648 * we're going to apply a display filter;
3649 *
3650 * a postdissector wants field values or protocols
3651 * on the first pass.
3652 */
3653 create_proto_tree =
3654 (cf->rfcode != NULL((void*)0) || cf->dfcode != NULL((void*)0) || postdissectors_want_hfids() || dissect_color);
3655
3656 ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 3656, __func__, "tshark: create_proto_tree = %s", create_proto_tree
? "TRUE" : "FALSE"); } } while (0)
;
3657
3658 /* We're not going to display the protocol tree on this pass,
3659 so it's not going to be "visible". */
3660 edt = epan_dissect_new(cf->epan, create_proto_tree, false0);
3661 }
3662
3663 ws_debug("tshark: reading records for first pass")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 3663, __func__, "tshark: reading records for first pass"); }
} while (0)
;
3664 *err = 0;
3665 while (wtap_read(cf->provider.wth, &rec, err, err_info, &data_offset)) {
3666 if (read_interrupted) {
3667 status = PASS_INTERRUPTED;
3668 break;
3669 }
3670 framenum++;
3671
3672 if (process_packet_first_pass(cf, edt, data_offset, &rec)) {
3673 /* Stop reading if we hit a stop condition */
3674 if (max_packet_count > 0 && framenum >= max_packet_count) {
3675 ws_debug("tshark: max_packet_count (%d) reached", max_packet_count)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 3675, __func__, "tshark: max_packet_count (%d) reached", max_packet_count
); } } while (0)
;
3676 *err = 0; /* This is not an error */
3677 break;
3678 }
3679 if (max_byte_count != 0 && data_offset >= max_byte_count) {
3680 ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached",do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 3681, __func__, "tshark: max_byte_count (%" "l" "d" "/%" "l"
"d" ") reached", data_offset, max_byte_count); } } while (0)
3681 data_offset, max_byte_count)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 3681, __func__, "tshark: max_byte_count (%" "l" "d" "/%" "l"
"d" ") reached", data_offset, max_byte_count); } } while (0)
;
3682 *err = 0; /* This is not an error */
3683 break;
3684 }
3685 }
3686 wtap_rec_reset(&rec);
3687 }
3688 if (*err != 0)
3689 status = PASS_READ_ERROR;
3690
3691 if (edt)
3692 epan_dissect_free(edt);
3693
3694 /* Close the sequential I/O side, to free up memory it requires. */
3695 wtap_sequential_close(cf->provider.wth);
3696
3697 /* Allow the protocol dissectors to free up memory that they
3698 * don't need after the sequential run-through of the packets. */
3699 postseq_cleanup_all_protocols();
3700
3701 cf->provider.prev_dis = NULL((void*)0);
3702 cf->provider.prev_cap = NULL((void*)0);
3703
3704 wtap_rec_cleanup(&rec);
3705
3706 return status;
3707}
3708
3709static process_packet_status_t
3710process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
3711 frame_data *fdata, wtap_rec *rec, unsigned tap_flags _U___attribute__((unused)))
3712{
3713 column_info *cinfo;
3714 bool_Bool passed;
3715 wtap_block_t block = NULL((void*)0);
3716 int64_t elapsed_start;
3717
3718 /* If we're not running a display filter and we're not printing any
3719 packet information, we don't need to do a dissection. This means
3720 that all packets can be marked as 'passed'. */
3721 passed = true1;
3722
3723 /* If we're going to print packet information, or we're going to
3724 run a read filter, or we're going to process taps, set up to
3725 do a dissection and do so. (This is the second pass of two
3726 passes over the packets; that's the pass where we print
3727 packet information or run taps.) */
3728 if (edt) {
3729 /* If we're running a display filter, prime the epan_dissect_t with that
3730 filter. */
3731 if (cf->dfcode)
3732 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
3733
3734 col_custom_prime_edt(edt, &cf->cinfo);
3735
3736 output_fields_prime_edt(edt, output_fields);
3737 /* The PDML spec requires a 'geninfo' pseudo-protocol that needs
3738 * information from our 'frame' protocol.
3739 */
3740 if (output_fields_num_fields(output_fields) != 0 &&
3741 output_action == WRITE_XML) {
3742 epan_dissect_prime_with_hfid(edt, proto_registrar_get_id_byname("frame"));
3743 }
3744
3745 /* We only need the columns if either
3746 1) some tap or filter needs the columns
3747 or
3748 2) we're printing packet info but we're *not* verbose; in verbose
3749 mode, we print the protocol tree, not the protocol summary.
3750 or
3751 3) there is a column mapped to an individual field
3752 */
3753 if ((tap_listeners_require_columns()) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields) || dfilter_requires_columns(cf->dfcode))
3754 cinfo = &cf->cinfo;
3755 else
3756 cinfo = NULL((void*)0);
3757
3758 frame_data_set_before_dissect(fdata, &cf->elapsed_time,
3759 &cf->provider.ref, cf->provider.prev_dis);
3760 if (cf->provider.ref == fdata) {
3761 ref_frame = *fdata;
3762 cf->provider.ref = &ref_frame;
3763 }
3764
3765 if (dissect_color) {
3766 color_filters_prime_edt(edt);
3767 fdata->need_colorize = 1;
3768 }
3769
3770 /* epan_dissect_run (and epan_dissect_reset) unref the block.
3771 * We need it later, e.g. in order to copy the options. */
3772 block = wtap_block_ref(rec->block);
3773 elapsed_start = g_get_monotonic_time();
3774 epan_dissect_run_with_taps(edt, cf->cd_t, rec, fdata, cinfo);
3775 tshark_elapsed.second_pass.dissect += g_get_monotonic_time() - elapsed_start;
3776
3777 /* Run the display filter if we have one. */
3778 if (cf->dfcode) {
3779 elapsed_start = g_get_monotonic_time();
3780 passed = dfilter_apply_edt(cf->dfcode, edt);
3781 tshark_elapsed.second_pass.dfilter_filter += g_get_monotonic_time() - elapsed_start;
3782 }
3783 }
3784
3785 if (passed) {
3786 frame_data_set_after_dissect(fdata, &cum_bytes);
3787 /* Process this packet. */
3788 if (print_packet_info) {
3789 /* We're printing packet information; print the information for
3790 this packet. */
3791 if (!print_packet(cf, edt)) {
3792 show_print_file_io_error();
3793 return PROCESS_PACKET_PRINT_ERROR;
3794 }
3795
3796 /* If we're doing "line-buffering", flush the standard output
3797 after every packet. See the comment above, for the "-l"
3798 option, for an explanation of why we do that. */
3799 if (line_buffered) {
3800 if (fflush(stdoutstdout) == EOF(-1)) {
3801 /* Report a write error; see above */
3802 show_print_file_io_error();
3803 return PROCESS_PACKET_PRINT_ERROR;
3804 }
3805 }
3806 }
3807 cf->provider.prev_dis = fdata;
3808 }
3809 cf->provider.prev_cap = fdata;
3810
3811 if (edt) {
3812 epan_dissect_reset(edt);
3813 rec->block = block;
3814 }
3815 return (passed || fdata->dependent_of_displayed) ? PROCESS_PACKET_PASSED : PROCESS_PACKET_DIDNT_PASS;
3816}
3817
3818static bool_Bool
3819process_new_idbs(wtap *wth, wtap_dumper *pdh, int *err, char **err_info)
3820{
3821 wtap_block_t if_data;
3822
3823 while ((if_data = wtap_get_next_interface_description(wth)) != NULL((void*)0)) {
3824 /*
3825 * Only add interface blocks if the output file supports (meaning
3826 * *requires*) them.
3827 *
3828 * That mean that the abstract interface provided by libwiretap
3829 * involves WTAP_BLOCK_IF_ID_AND_INFO blocks.
3830 */
3831 if (pdh != NULL((void*)0)) {
3832 if (wtap_file_type_subtype_supports_block(wtap_dump_file_type_subtype(pdh), WTAP_BLOCK_IF_ID_AND_INFO) != BLOCK_NOT_SUPPORTED) {
3833 if (!wtap_dump_add_idb(pdh, if_data, err, err_info))
3834 return false0;
3835 }
3836 }
3837 }
3838 return true1;
3839}
3840
3841static pass_status_t
3842process_cap_file_second_pass(capture_file *cf, wtap_dumper *pdh,
3843 int *err, char **err_info,
3844 volatile uint32_t *err_framenum,
3845 int max_write_packet_count)
3846{
3847 wtap_rec rec;
3848 int framenum;
3849 bool_Bool got_printing_error;
3850 int write_framenum = 0;
3851 frame_data *fdata;
3852 bool_Bool filtering_tap_listeners;
3853 unsigned tap_flags;
3854 epan_dissect_t *edt = NULL((void*)0);
3855 pass_status_t status = PASS_SUCCEEDED;
3856
3857 /*
3858 * Process whatever IDBs we haven't seen yet. This will be all
3859 * the IDBs in the file, as we've finished reading it; they'll
3860 * all be at the beginning of the output file.
3861 */
3862 if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
3863 *err_framenum = 0;
3864 return PASS_WRITE_ERROR;
3865 }
3866
3867 wtap_rec_init(&rec, DEFAULT_INIT_BUFFER_SIZE_2048(2 * 1024));
3868
3869 /* Do we have any tap listeners with filters? */
3870 filtering_tap_listeners = have_filtering_tap_listeners();
3871
3872 /* Get the union of the flags for all tap listeners. */
3873 tap_flags = union_of_tap_listener_flags();
3874
3875 if (do_dissection) {
3876 bool_Bool create_proto_tree;
3877
3878 /*
3879 * Determine whether we need to create a protocol tree.
3880 * We do if:
3881 *
3882 * we're going to apply a display filter;
3883 *
3884 * we're going to print the protocol tree;
3885 *
3886 * one of the tap listeners requires a protocol tree;
3887 *
3888 * we have custom columns (which require field values, which
3889 * currently requires that we build a protocol tree).
3890 */
3891 create_proto_tree =
3892 (cf->dfcode || print_details || filtering_tap_listeners ||
3893 (tap_flags & TL_REQUIRES_PROTO_TREE0x00000001) || have_custom_cols(&cf->cinfo) || dissect_color);
3894
3895 ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 3895, __func__, "tshark: create_proto_tree = %s", create_proto_tree
? "TRUE" : "FALSE"); } } while (0)
;
3896
3897 /* The protocol tree will be "visible", i.e., nothing faked, only if
3898 we're printing packet details, which is true if we're printing stuff
3899 ("print_packet_info" is true) and we're in verbose mode
3900 ("packet_details" is true). But if we specified certain fields with
3901 "-e", we'll prime those directly later. */
3902 bool_Bool visible = print_packet_info && print_details && output_fields_num_fields(output_fields) == 0;
3903 edt = epan_dissect_new(cf->epan, create_proto_tree, visible);
3904 }
3905
3906 /*
3907 * Force synchronous resolution of IP addresses; in this pass, we
3908 * can't do it in the background and fix up past dissections.
3909 */
3910 set_resolution_synchrony(true1);
3911
3912 for (framenum = 1, got_printing_error = false0;
3913 framenum <= (int)cf->count && !got_printing_error;
3914 framenum++) {
3915 if (read_interrupted) {
3916 status = PASS_INTERRUPTED;
3917 break;
3918 }
3919 fdata = frame_data_sequence_find(cf->provider.frames, framenum);
3920 if (!wtap_seek_read(cf->provider.wth, fdata->file_off, &rec, err,
3921 err_info)) {
3922 /* Error reading from the input file. */
3923 status = PASS_READ_ERROR;
3924 break;
3925 }
3926 ws_debug("tshark: invoking process_packet_second_pass() for frame #%d", framenum)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 3926, __func__, "tshark: invoking process_packet_second_pass() for frame #%d"
, framenum); } } while (0)
;
3927 switch (process_packet_second_pass(cf, edt, fdata, &rec, tap_flags)) {
3928
3929 case PROCESS_PACKET_PASSED:
3930 /* Either there's no read filtering or this packet passed the
3931 filter, so, if we're writing to a capture file, write
3932 this packet out. */
3933 /* XXX - With certain file types, time stamps are only available
3934 * from a sequential wtap_read but not wtap_seek_read, in which
3935 * case we could copy them from fdata when saving. */
3936 write_framenum++;
3937 if (pdh != NULL((void*)0)) {
3938 ws_debug("tshark: writing packet #%d to outfile packet #%d", framenum, write_framenum)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 3938, __func__, "tshark: writing packet #%d to outfile packet #%d"
, framenum, write_framenum); } } while (0)
;
3939 if (!wtap_dump(pdh, &rec, err, err_info)) {
3940 /* Error writing to the output file. */
3941 ws_debug("tshark: error writing to a capture file (%d)", *err)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 3941, __func__, "tshark: error writing to a capture file (%d)"
, *err); } } while (0)
;
3942 *err_framenum = framenum;
3943 status = PASS_WRITE_ERROR;
3944 break;
3945 }
3946 /* Stop reading if we hit a stop condition */
3947 if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) {
3948 ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 3948, __func__, "tshark: max_write_packet_count (%d) reached"
, max_write_packet_count); } } while (0)
;
3949 *err = 0; /* This is not an error */
3950 break;
3951 }
3952 }
3953 break;
3954
3955 case PROCESS_PACKET_DIDNT_PASS:
3956 /* There is read filtering and this packet didn't pass the filter. */
3957 break;
3958
3959 case PROCESS_PACKET_PRINT_ERROR:
3960 /* Either here's no read filtering or this packet passed
3961 the read filter, and we tried to print dissection
3962 informaion, but that failed. We've already reported
3963 the error, unless it was EPIPE, in which case we just
3964 silently quit; stop processing packes. */
3965 got_printing_error = true1;
3966 status = PASS_PRINT_ERROR;
3967 break;
3968 }
3969 wtap_rec_reset(&rec);
3970 }
3971
3972 if (edt)
3973 epan_dissect_free(edt);
3974
3975 wtap_rec_cleanup(&rec);
3976
3977 return status;
3978}
3979
3980static pass_status_t
3981process_cap_file_single_pass(capture_file *cf, wtap_dumper *pdh,
3982 int max_packet_count, int64_t max_byte_count,
3983 int max_write_packet_count,
3984 int *err, char **err_info,
3985 volatile uint32_t *err_framenum)
3986{
3987 wtap_rec rec;
3988 bool_Bool create_proto_tree = false0;
3989 bool_Bool filtering_tap_listeners;
3990 unsigned tap_flags;
3991 int framenum = 0;
3992 bool_Bool got_printing_error;
3993 int write_framenum = 0;
3994 epan_dissect_t *edt = NULL((void*)0);
3995 int64_t data_offset;
3996 pass_status_t status = PASS_SUCCEEDED;
3997 bool_Bool visible = false0;
3998
3999 wtap_rec_init(&rec, DEFAULT_INIT_BUFFER_SIZE_2048(2 * 1024));
4000
4001 /* Do we have any tap listeners with filters? */
4002 filtering_tap_listeners = have_filtering_tap_listeners();
4003
4004 /* Get the union of the flags for all tap listeners. */
4005 tap_flags = union_of_tap_listener_flags();
4006
4007 if (do_dissection) {
4008 /*
4009 * Determine whether we need to create a protocol tree.
4010 * We do if:
4011 *
4012 * we're going to apply a read filter;
4013 *
4014 * we're going to apply a display filter;
4015 *
4016 * we're going to print the protocol tree;
4017 *
4018 * one of the tap listeners is going to apply a filter;
4019 *
4020 * one of the tap listeners requires a protocol tree;
4021 *
4022 * a postdissector wants field values or protocols
4023 * on the first pass;
4024 *
4025 * we have custom columns (which require field values, which
4026 * currently requires that we build a protocol tree).
4027 */
4028 create_proto_tree =
4029 (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
4030 (tap_flags & TL_REQUIRES_PROTO_TREE0x00000001) || postdissectors_want_hfids() ||
4031 have_custom_cols(&cf->cinfo) || dissect_color);
4032
4033 ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4033, __func__, "tshark: create_proto_tree = %s", create_proto_tree
? "TRUE" : "FALSE"); } } while (0)
;
4034
4035 /* The protocol tree will be "visible", i.e., nothing faked, only if
4036 we're printing packet details, which is true if we're printing stuff
4037 ("print_packet_info" is true) and we're in verbose mode
4038 ("packet_details" is true). But if we specified certain fields with
4039 "-e", we'll prime those directly later. */
4040 visible = print_packet_info && print_details && output_fields_num_fields(output_fields) == 0;
4041 edt = epan_dissect_new(cf->epan, create_proto_tree, visible);
4042 }
4043
4044 /*
4045 * Force synchronous resolution of IP addresses; we're doing only
4046 * one pass, so we can't do it in the background and fix up past
4047 * dissections.
4048 */
4049 set_resolution_synchrony(true1);
4050
4051 *err = 0;
4052 got_printing_error = false0;
4053 while (wtap_read(cf->provider.wth, &rec, err, err_info, &data_offset) &&
4054 !got_printing_error) {
4055 if (read_interrupted) {
4056 status = PASS_INTERRUPTED;
4057 break;
4058 }
4059 framenum++;
4060
4061 /*
4062 * Process whatever IDBs we haven't seen yet.
4063 */
4064 if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
4065 *err_framenum = framenum;
4066 status = PASS_WRITE_ERROR;
4067 break;
4068 }
4069
4070 ws_debug("tshark: processing packet #%d", framenum)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4070, __func__, "tshark: processing packet #%d", framenum);
} } while (0)
;
4071
4072 reset_epan_mem(cf, edt, create_proto_tree, visible);
4073
4074 switch (process_packet_single_pass(cf, edt, data_offset, &rec,
4075 tap_flags)) {
4076 case PROCESS_PACKET_PASSED:
4077 /* Either there's no read filtering or this packet passed the
4078 filter, so, if we're writing to a capture file, write
4079 this packet out. */
4080 write_framenum++;
4081 if (pdh != NULL((void*)0)) {
4082 ws_debug("tshark: writing packet #%d to outfile as #%d",do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4083, __func__, "tshark: writing packet #%d to outfile as #%d"
, framenum, write_framenum); } } while (0)
4083 framenum, write_framenum)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4083, __func__, "tshark: writing packet #%d to outfile as #%d"
, framenum, write_framenum); } } while (0)
;
4084 if (!wtap_dump(pdh, &rec, err, err_info)) {
4085 /* Error writing to the output file. */
4086 ws_debug("tshark: error writing to a capture file (%d)", *err)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4086, __func__, "tshark: error writing to a capture file (%d)"
, *err); } } while (0)
;
4087 *err_framenum = framenum;
4088 status = PASS_WRITE_ERROR;
4089 break;
4090 }
4091 }
4092 break;
4093
4094 case PROCESS_PACKET_DIDNT_PASS:
4095 /* There is read filtering and this packet didn't pass the filter. */
4096 break;
4097
4098 case PROCESS_PACKET_PRINT_ERROR:
4099 /* Either here's no read filtering or this packet passed
4100 the read filter, and we tried to print dissection
4101 informaion, but that failed. We've already reported
4102 the error, unless it was EPIPE, in which case we just
4103 silently quit; tell the capture child to stop. */
4104 got_printing_error = true1;
4105 break;
4106 }
4107 /* Stop reading if we hit a stop condition */
4108 if (max_packet_count > 0 && framenum >= max_packet_count) {
4109 ws_debug("tshark: max_packet_count (%d) reached", max_packet_count)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4109, __func__, "tshark: max_packet_count (%d) reached", max_packet_count
); } } while (0)
;
4110 *err = 0; /* This is not a read error */
4111 break;
4112 }
4113 if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) {
4114 ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4114, __func__, "tshark: max_write_packet_count (%d) reached"
, max_write_packet_count); } } while (0)
;
4115 *err = 0; /* This is not a read error */
4116 break;
4117 }
4118 if (max_byte_count != 0 && data_offset >= max_byte_count) {
4119 ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached",do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4120, __func__, "tshark: max_byte_count (%" "l" "d" "/%" "l"
"d" ") reached", data_offset, max_byte_count); } } while (0)
4120 data_offset, max_byte_count)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4120, __func__, "tshark: max_byte_count (%" "l" "d" "/%" "l"
"d" ") reached", data_offset, max_byte_count); } } while (0)
;
4121 *err = 0; /* This is not a read error */
4122 break;
4123 }
4124 /* Stop reading if we got an error processing the packet. */
4125 if (got_printing_error) {
4126 *err = 0; /* This is not a read error */
4127 break;
4128 }
4129 wtap_rec_reset(&rec);
4130 }
4131 if (status == PASS_SUCCEEDED) {
4132 if (*err != 0) {
4133 /* Error reading from the input file. */
4134 status = PASS_READ_ERROR;
4135 } else {
4136 /*
4137 * Process whatever IDBs we haven't seen yet.
4138 */
4139 if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
4140 *err_framenum = framenum;
4141 status = PASS_WRITE_ERROR;
4142 }
4143
4144 /*
4145 * Did we get a printing error?
4146 */
4147 if (got_printing_error) {
4148 status = PASS_PRINT_ERROR;
4149 }
4150 }
4151 }
4152
4153 if (edt)
4154 epan_dissect_free(edt);
4155
4156 wtap_rec_cleanup(&rec);
4157
4158 return status;
4159}
4160
4161static process_file_status_t
4162process_cap_file(capture_file *cf, char *save_file, int out_file_type,
4163 bool_Bool out_file_name_res, int max_packet_count, int64_t max_byte_count,
4164 int max_write_packet_count, ws_compression_type compression_type)
4165{
4166 process_file_status_t status = PROCESS_FILE_SUCCEEDED;
4167 wtap_dumper *pdh;
4168#ifndef _WIN32
4169 struct sigaction action, oldaction;
4170#endif
4171 int err = 0, err_pass1 = 0;
4172 char *err_info = NULL((void*)0), *err_info_pass1 = NULL((void*)0);
4173 volatile uint32_t err_framenum;
4174 wtap_dump_params params = WTAP_DUMP_PARAMS_INIT{.snaplen=0};
4175 char *shb_user_appl;
4176 pass_status_t first_pass_status, second_pass_status;
4177 int64_t elapsed_start;
4178
4179 if (save_file != NULL((void*)0)) {
4180 /* Set up to write to the capture file. */
4181 wtap_dump_params_init_no_idbs(&params, cf->provider.wth);
4182
4183 /* If we don't have an application name add TShark */
4184 if (wtap_block_get_string_option_value(g_array_index(params.shb_hdrs, wtap_block_t, 0)(((wtap_block_t*) (void *) (params.shb_hdrs)->data) [(0)]), OPT_SHB_USERAPPL4, &shb_user_appl) != WTAP_OPTTYPE_SUCCESS) {
4185 /* this is free'd by wtap_block_unref() later */
4186 wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0)(((wtap_block_t*) (void *) (params.shb_hdrs)->data) [(0)]), OPT_SHB_USERAPPL4, "%s", get_appname_and_version());
4187 }
4188 if (capture_comments != NULL((void*)0)) {
4189 for (unsigned i = 0; i < capture_comments->len; i++) {
4190 wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0)(((wtap_block_t*) (void *) (params.shb_hdrs)->data) [(0)]),
4191 OPT_COMMENT1, "%s",
4192 (char *)g_ptr_array_index(capture_comments, i)((capture_comments)->pdata)[i]);
4193 }
4194 }
4195
4196 ws_debug("tshark: writing format type %d, to %s", out_file_type, save_file)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4196, __func__, "tshark: writing format type %d, to %s", out_file_type
, save_file); } } while (0)
;
4197 if (strcmp(save_file, "-") == 0) {
4198 /* Write to the standard output. */
4199 pdh = wtap_dump_open_stdout(out_file_type, compression_type, &params,
4200 &err, &err_info);
4201 } else {
4202 pdh = wtap_dump_open(save_file, out_file_type, compression_type, &params,
4203 &err, &err_info);
4204 }
4205
4206 g_free(params.idb_inf);
4207 params.idb_inf = NULL((void*)0);
4208
4209 if (pdh == NULL((void*)0)) {
4210 /* We couldn't set up to write to the capture file. */
4211 report_cfile_dump_open_failure(save_file, err, err_info,
4212 out_file_type);
4213 status = PROCESS_FILE_NO_FILE_PROCESSED;
4214 goto out;
4215 }
4216 } else {
4217 /* Set up to print packet information. */
4218 if (print_packet_info) {
4219 if (!write_preamble(cf)) {
4220 show_print_file_io_error();
4221 status = PROCESS_FILE_NO_FILE_PROCESSED;
4222 goto out;
4223 }
4224 }
4225 pdh = NULL((void*)0);
4226 }
4227
4228#ifdef _WIN32
4229 /* Catch a CTRL+C event and, if we get it, clean up and exit. */
4230 SetConsoleCtrlHandler(read_cleanup, true1);
4231#else /* _WIN32 */
4232 /* Catch SIGINT and SIGTERM and, if we get either of them,
4233 clean up and exit. If SIGHUP isn't being ignored, catch
4234 it too and, if we get it, clean up and exit.
4235
4236 We restart any read that was in progress, so that it doesn't
4237 disrupt reading from the sync pipe. The signal handler tells
4238 the capture child to finish; it will report that it finished,
4239 or will exit abnormally, so we'll stop reading from the sync
4240 pipe, pick up the exit status, and quit. */
4241 memset(&action, 0, sizeof(action));
4242 action.sa_handler__sigaction_handler.sa_handler = read_cleanup;
4243 action.sa_flags = SA_RESTART0x10000000;
4244 sigemptyset(&action.sa_mask);
4245 sigaction(SIGTERM15, &action, NULL((void*)0));
4246 sigaction(SIGINT2, &action, NULL((void*)0));
4247 sigaction(SIGHUP1, NULL((void*)0), &oldaction);
4248 if (oldaction.sa_handler__sigaction_handler.sa_handler == SIG_DFL((__sighandler_t) 0))
4249 sigaction(SIGHUP1, &action, NULL((void*)0));
4250#endif /* _WIN32 */
4251
4252 if (perform_two_pass_analysis) {
4253 ws_debug("tshark: perform_two_pass_analysis, do_dissection=%s", do_dissection ? "TRUE" : "FALSE")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4253, __func__, "tshark: perform_two_pass_analysis, do_dissection=%s"
, do_dissection ? "TRUE" : "FALSE"); } } while (0)
;
4254
4255 elapsed_start = g_get_monotonic_time();
4256 first_pass_status = process_cap_file_first_pass(cf, max_packet_count,
4257 max_byte_count,
4258 &err_pass1,
4259 &err_info_pass1);
4260 tshark_elapsed.elapsed_first_pass = g_get_monotonic_time() - elapsed_start;
4261
4262 ws_debug("tshark: done with first pass")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4262, __func__, "tshark: done with first pass"); } } while (
0)
;
4263
4264 if (first_pass_status == PASS_INTERRUPTED) {
4265 /* The first pass was interrupted; skip the second pass.
4266 It won't be run, so it won't get an error. */
4267 second_pass_status = PASS_SUCCEEDED;
4268 } else {
4269 /*
4270 * If we got a read error on the first pass, we still do the second
4271 * pass, so we can at least process the packets we read, and then
4272 * report the first-pass error after the second pass (and before
4273 * we report any second-pass errors), so all the errors show up
4274 * at the end.
4275 */
4276 elapsed_start = g_get_monotonic_time();
4277 second_pass_status = process_cap_file_second_pass(cf, pdh, &err, &err_info,
4278 &err_framenum,
4279 max_write_packet_count);
4280 tshark_elapsed.elapsed_second_pass = g_get_monotonic_time() - elapsed_start;
4281
4282 ws_debug("tshark: done with second pass")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4282, __func__, "tshark: done with second pass"); } } while
(0)
;
4283 }
4284 }
4285 else {
4286 /* !perform_two_pass_analysis */
4287 ws_debug("tshark: perform one pass analysis, do_dissection=%s", do_dissection ? "TRUE" : "FALSE")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4287, __func__, "tshark: perform one pass analysis, do_dissection=%s"
, do_dissection ? "TRUE" : "FALSE"); } } while (0)
;
4288
4289 first_pass_status = PASS_SUCCEEDED; /* There is no first pass */
4290
4291 elapsed_start = g_get_monotonic_time();
4292 second_pass_status = process_cap_file_single_pass(cf, pdh,
4293 max_packet_count,
4294 max_byte_count,
4295 max_write_packet_count,
4296 &err, &err_info,
4297 &err_framenum);
4298 tshark_elapsed.elapsed_first_pass = g_get_monotonic_time() - elapsed_start;
4299
4300 ws_debug("tshark: done with single pass")do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4300, __func__, "tshark: done with single pass"); } } while
(0)
;
4301 }
4302
4303 if (first_pass_status != PASS_SUCCEEDED ||
4304 second_pass_status != PASS_SUCCEEDED) {
4305 /*
4306 * At least one of the passes didn't succeed; either it got a failure
4307 * or it was interrupted.
4308 */
4309 if (first_pass_status != PASS_INTERRUPTED ||
4310 second_pass_status != PASS_INTERRUPTED) {
4311 /* At least one of the passes got an error. */
4312 ws_debug("tshark: something failed along the line (%d)", err)do { if (1) { ws_log_full("Main", LOG_LEVEL_DEBUG, "tshark.c"
, 4312, __func__, "tshark: something failed along the line (%d)"
, err); } } while (0)
;
4313 /*
4314 * If we're printing packet data, and the standard output and error
4315 * are going to the same place, flush the standard output, so everything
4316 * buffered up is written, and then print a newline to the standard
4317 * error before printing the error message, to separate it from the
4318 * packet data. (Alas, that only works on UN*X; st_dev is meaningless,
4319 * and the _fstat() documentation at Microsoft doesn't indicate whether
4320 * st_ino is even supported.)
4321 */
4322#ifndef _WIN32
4323 if (print_packet_info) {
4324 ws_statb64struct stat stat_stdout, stat_stderr;
4325
4326 if (ws_fstat64fstat(1, &stat_stdout) == 0 && ws_fstat64fstat(2, &stat_stderr) == 0) {
4327 if (stat_stdout.st_dev == stat_stderr.st_dev &&
4328 stat_stdout.st_ino == stat_stderr.st_ino) {
4329 fflush(stdoutstdout);
4330 fprintf(stderrstderr, "\n");
4331 }
4332 }
4333 }
4334#endif
4335 }
4336 /* Report status of pass 1 of two-pass processing. */
4337 switch (first_pass_status) {
4338
4339 case PASS_SUCCEEDED:
4340 /* No problem. */
4341 break;
4342
4343 case PASS_READ_ERROR:
4344 /* Read error. */
4345 report_cfile_read_failure(cf->filename, err_pass1, err_info_pass1);
4346 status = PROCESS_FILE_ERROR;
4347 break;
4348
4349 case PASS_WRITE_ERROR:
4350 /* Won't happen on the first pass. */
4351 break;
4352
4353 case PASS_PRINT_ERROR:
4354 /* Won't happen on the first pass. */
4355 break;
4356
4357 case PASS_INTERRUPTED:
4358 /* Not an error, so nothing to report. */
4359 status = PROCESS_FILE_INTERRUPTED;
4360 break;
4361 }
4362
4363 /* Report status of pass 2 of two-pass processing or the only pass
4364 of one-pass processing. */
4365 switch (second_pass_status) {
4366
4367 case PASS_SUCCEEDED:
4368 /* No problem. */
4369 break;
4370
4371 case PASS_READ_ERROR:
4372 /* Read error. */
4373 report_cfile_read_failure(cf->filename, err, err_info);
4374 status = PROCESS_FILE_ERROR;
4375 break;
4376
4377 case PASS_WRITE_ERROR:
4378 /* Write error.
4379 XXX - framenum is not necessarily the frame number in
4380 the input file if there was a read filter. */
4381 report_cfile_write_failure(cf->filename, save_file, err, err_info,
4382 err_framenum, out_file_type);
4383 status = PROCESS_FILE_ERROR;
4384 break;
4385
4386 case PASS_PRINT_ERROR:
4387 /* The print error has already been reported. */
4388 status = PROCESS_FILE_ERROR;
4389 break;
4390
4391 case PASS_INTERRUPTED:
4392 /* Not an error, so nothing to report. */
4393 status = PROCESS_FILE_INTERRUPTED;
4394 break;
4395 }
4396 }
4397 if (save_file != NULL((void*)0)) {
4398 if (second_pass_status != PASS_WRITE_ERROR) {
4399 if (pdh && out_file_name_res) {
4400 /* XXX: This doesn't work as expected. First, it should be
4401 * moved to between the first and second passes (if doing
4402 * two-pass mode), so that the new NRB appears before packets,
4403 * which is better for subsequent one-pass mode. It never works
4404 * well in one-pass mode.
4405 *
4406 * Second, it only writes hosts that we've done lookups for,
4407 * which means unless packet details are printed (or there's
4408 * a display filter that matches something that will do a host
4409 * lookup, e.g. -Y "ip") it doesn't actually have anything
4410 * in the list to save. Notably, that includes the case of
4411 * "tshark [-2] -H hosts.txt -r <infile> -w <outfile>",
4412 * which a user would certainly expect to dissect packets,
4413 * lookup hostnames, and add them to an NRB for later use.
4414 * A workaround is if "-V > /dev/null" is added, but who
4415 * expects that?
4416 *
4417 * A third issue is that name resolution blocks aren't
4418 * written for live captures.
4419 */
4420 if (!wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list())) {
4421 cmdarg_err("The file format \"%s\" doesn't support name resolution information.",
4422 wtap_file_type_subtype_name(out_file_type));
4423 }
4424 }
4425 /* Now close the capture file. */
4426 if (!wtap_dump_close(pdh, NULL((void*)0), &err, &err_info)) {
4427 report_cfile_close_failure(save_file, err, err_info);
4428 status = PROCESS_FILE_ERROR;
4429 }
4430 } else {
4431 /* We got a write error; it was reported, so just close the dump file
4432 without bothering to check for further errors. */
4433 wtap_dump_close(pdh, NULL((void*)0), &err, &err_info);
4434 g_free(err_info);
4435 status = PROCESS_FILE_ERROR;
4436 }
4437 } else {
4438 if (print_packet_info) {
4439 if (!write_finale()) {
4440 show_print_file_io_error();
4441 status = PROCESS_FILE_ERROR;
4442 }
4443 }
4444 }
4445
4446out:
4447 wtap_close(cf->provider.wth);
4448 cf->provider.wth = NULL((void*)0);
4449
4450 wtap_dump_params_cleanup(&params);
4451
4452 return status;
4453}
4454
4455static process_packet_status_t
4456process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, int64_t offset,
4457 wtap_rec *rec, unsigned tap_flags _U___attribute__((unused)))
4458{
4459 frame_data fdata;
4460 column_info *cinfo;
4461 bool_Bool passed;
4462 wtap_block_t block = NULL((void*)0);
4463 int64_t elapsed_start;
4464
4465 /* Count this packet. */
4466 cf->count++;
4467
4468 /* If we're not running a display filter and we're not printing any
4469 packet information, we don't need to do a dissection. This means
4470 that all packets can be marked as 'passed'. */
4471 passed = true1;
4472
4473 frame_data_init(&fdata, cf->count, rec, offset, cum_bytes);
4474
4475 /* If we're going to print packet information, or we're going to
4476 run a read filter, or we're going to process taps, set up to
4477 do a dissection and do so. (This is the one and only pass
4478 over the packets, so, if we'll be printing packet information
4479 or running taps, we'll be doing it here.) */
4480 if (edt) {
4481 /* If we're running a filter, prime the epan_dissect_t with that
4482 filter. */
4483 if (cf->dfcode)
4484 epan_dissect_prime_with_dfilter(edt, cf->dfcode);
4485
4486 col_custom_prime_edt(edt, &cf->cinfo);
4487
4488 output_fields_prime_edt(edt, output_fields);
4489 /* The PDML spec requires a 'geninfo' pseudo-protocol that needs
4490 * information from our 'frame' protocol.
4491 */
4492 if (output_fields_num_fields(output_fields) != 0 &&
4493 output_action == WRITE_XML) {
4494 epan_dissect_prime_with_hfid(edt, proto_registrar_get_id_byname("frame"));
4495 }
4496
4497 /* We only need the columns if either
4498 1) some tap or filter needs the columns
4499 or
4500 2) we're printing packet info but we're *not* verbose; in verbose
4501 mode, we print the protocol tree, not the protocol summary.
4502 or
4503 3) there is a column mapped as an individual field */
4504 if ((tap_listeners_require_columns()) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields) || dfilter_requires_columns(cf->dfcode))
4505 cinfo = &cf->cinfo;
4506 else
4507 cinfo = NULL((void*)0);
4508
4509 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
4510 &cf->provider.ref, cf->provider.prev_dis);
4511 if (cf->provider.ref == &fdata) {
4512 ref_frame = fdata;
4513 cf->provider.ref = &ref_frame;
4514 }
4515
4516 if (dissect_color) {
4517 color_filters_prime_edt(edt);
4518 fdata.need_colorize = 1;
4519 }
4520
4521 /* epan_dissect_run (and epan_dissect_reset) unref the block.
4522 * We need it later, e.g. in order to copy the options. */
4523 block = wtap_block_ref(rec->block);
4524 elapsed_start = g_get_monotonic_time();
4525 epan_dissect_run_with_taps(edt, cf->cd_t, rec, &fdata, cinfo);
4526 tshark_elapsed.first_pass.dissect += g_get_monotonic_time() - elapsed_start;
4527
4528 /* Run the filter if we have it. */
4529 if (cf->dfcode) {
4530 elapsed_start = g_get_monotonic_time();
4531 passed = dfilter_apply_edt(cf->dfcode, edt);
4532 tshark_elapsed.first_pass.dfilter_filter += g_get_monotonic_time() - elapsed_start;
4533 }
4534 }
4535
4536 if (passed) {
4537 frame_data_set_after_dissect(&fdata, &cum_bytes);
4538
4539 /* Process this packet. */
4540 if (print_packet_info) {
4541 /* We're printing packet information; print the information for
4542 this packet. */
4543 ws_assert(edt)do { if ((1) && !(edt)) ws_log_fatal_full("Main", LOG_LEVEL_ERROR
, "tshark.c", 4543, __func__, "assertion failed: %s", "edt");
} while (0)
;
4544 if (!print_packet(cf, edt)) {
4545 show_print_file_io_error();
4546 return PROCESS_PACKET_PRINT_ERROR;
4547 }
4548
4549 /* If we're doing "line-buffering", flush the standard output
4550 after every packet. See the comment above, for the "-l"
4551 option, for an explanation of why we do that. */
4552 if (line_buffered) {
4553 if (fflush(stdoutstdout) == EOF(-1)) {
4554 /* Report a write error; see above */
4555 show_print_file_io_error();
4556 return PROCESS_PACKET_PRINT_ERROR;
4557 }
4558 }
4559 }
4560
4561 /* this must be set after print_packet() [bug #8160] */
4562 prev_dis_frame = fdata;
4563 cf->provider.prev_dis = &prev_dis_frame;
4564 }
4565
4566 prev_cap_frame = fdata;
4567 cf->provider.prev_cap = &prev_cap_frame;
4568
4569 if (edt) {
4570 epan_dissect_reset(edt);
4571 frame_data_destroy(&fdata);
4572 rec->block = block;
4573 }
4574 return passed ? PROCESS_PACKET_PASSED : PROCESS_PACKET_DIDNT_PASS;
4575}
4576
4577static bool_Bool
4578write_preamble(capture_file *cf)
4579{
4580 switch (output_action) {
4581
4582 case WRITE_TEXT:
4583 return print_preamble(print_stream, cf->filename, application_get_vcs_version_info());
4584
4585 case WRITE_XML:
4586 if (print_details)
4587 write_pdml_preamble(stdoutstdout, cf->filename, get_doc_dir(application_configuration_environment_prefix()));
4588 else
4589 write_psml_preamble(&cf->cinfo, stdoutstdout);
4590 return !ferror(stdoutstdout);
4591
4592 case WRITE_FIELDS:
4593 write_fields_preamble(output_fields, stdoutstdout);
4594 return !ferror(stdoutstdout);
4595
4596 case WRITE_JSON:
4597 case WRITE_JSON_RAW:
4598 jdumper = write_json_preamble(stdoutstdout);
4599 return !ferror(stdoutstdout);
4600
4601 case WRITE_EK:
4602 return true1;
4603
4604 default:
4605 ws_assert_not_reached()ws_log_fatal_full("Main", LOG_LEVEL_ERROR, "tshark.c", 4605, __func__
, "assertion \"not reached\" failed")
;
4606 return false0;
4607 }
4608}
4609
4610static char *
4611get_line_buf(size_t len)
4612{
4613 static char *line_bufp = NULL((void*)0);
4614 static size_t line_buf_len = 256;
4615 size_t new_line_buf_len;
4616
4617 for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
4618 new_line_buf_len *= 2)
4619 ;
4620 if (line_bufp == NULL((void*)0)) {
4621 line_buf_len = new_line_buf_len;
4622 line_bufp = (char *)g_malloc(line_buf_len + 1);
4623 } else {
4624 if (new_line_buf_len > line_buf_len) {
4625 line_buf_len = new_line_buf_len;
4626 line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
4627 }
4628 }
4629 return line_bufp;
4630}
4631
4632static inline void
4633put_string(char *dest, const char *str, size_t str_len)
4634{
4635 memcpy(dest, str, str_len);
4636 dest[str_len] = '\0';
4637}
4638
4639static inline void
4640put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
4641{
4642 size_t i;
4643
4644 for (i = str_len; i < str_with_spaces; i++)
4645 *dest++ = ' ';
4646
4647 put_string(dest, str, str_len);
4648}
4649
4650static inline void
4651put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
4652{
4653 size_t i;
4654
4655 memcpy(dest, str, str_len);
4656 for (i = str_len; i < str_with_spaces; i++)
4657 dest[i] = ' ';
4658
4659 dest[str_with_spaces] = '\0';
4660}
4661
4662static bool_Bool
4663print_columns(capture_file *cf, const epan_dissect_t *edt)
4664{
4665 char *line_bufp;
4666 unsigned i;
4667 size_t buf_offset;
4668 size_t column_len;
4669 size_t col_len;
4670 col_item_t* col_item;
4671 char str_format[11];
4672 const color_filter_t *color_filter = NULL((void*)0);
4673
4674 line_bufp = get_line_buf(256);
4675 buf_offset = 0;
4676 *line_bufp = '\0';
4677
4678 if (dissect_color)
4679 color_filter = edt->pi.fd->color_filter;
4680
4681 for (i = 0; i < cf->cinfo.num_cols; i++) {
4682 col_item = &cf->cinfo.columns[i];
4683 /* Skip columns not marked as visible. */
4684 if (!get_column_visible(i))
4685 continue;
4686 const char* col_text = get_column_text(&cf->cinfo, i);
4687 switch (col_item->col_fmt) {
4688 case COL_NUMBER:
4689 case COL_NUMBER_DIS:
4690 column_len = col_len = strlen(col_text);
4691 if (column_len < 5)
4692 column_len = 5;
4693 line_bufp = get_line_buf(buf_offset + column_len);
4694 put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
4695 break;
4696
4697 case COL_CLS_TIME:
4698 case COL_REL_TIME:
4699 case COL_ABS_TIME:
4700 case COL_ABS_YMD_TIME: /* XXX - wider */
4701 case COL_ABS_YDOY_TIME: /* XXX - wider */
4702 case COL_UTC_TIME:
4703 case COL_UTC_YMD_TIME: /* XXX - wider */
4704 case COL_UTC_YDOY_TIME: /* XXX - wider */
4705 column_len = col_len = strlen(col_text);
4706 if (column_len < 10)
4707 column_len = 10;
4708 line_bufp = get_line_buf(buf_offset + column_len);
4709 put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
4710 break;
4711
4712 case COL_DEF_SRC:
4713 case COL_RES_SRC:
4714 case COL_UNRES_SRC:
4715 case COL_DEF_DL_SRC:
4716 case COL_RES_DL_SRC:
4717 case COL_UNRES_DL_SRC:
4718 case COL_DEF_NET_SRC:
4719 case COL_RES_NET_SRC:
4720 case COL_UNRES_NET_SRC:
4721 column_len = col_len = strlen(col_text);
4722 if (column_len < 12)
4723 column_len = 12;
4724 line_bufp = get_line_buf(buf_offset + column_len);
4725 put_spaces_string(line_bufp + buf_offset, col_text, col_len, column_len);
4726 break;
4727
4728 case COL_DEF_DST:
4729 case COL_RES_DST:
4730 case COL_UNRES_DST:
4731 case COL_DEF_DL_DST:
4732 case COL_RES_DL_DST:
4733 case COL_UNRES_DL_DST:
4734 case COL_DEF_NET_DST:
4735 case COL_RES_NET_DST:
4736 case COL_UNRES_NET_DST:
4737 column_len = col_len = strlen(col_text);
4738 if (column_len < 12)
4739 column_len = 12;
4740 line_bufp = get_line_buf(buf_offset + column_len);
4741 put_string_spaces(line_bufp + buf_offset, col_text, col_len, column_len);
4742 break;
4743
4744 default:
4745 column_len = strlen(col_text);
4746 line_bufp = get_line_buf(buf_offset + column_len);
4747 put_string(line_bufp + buf_offset, col_text, column_len);
4748 break;
4749 }
4750 buf_offset += column_len;
4751 if (i != cf->cinfo.num_cols - 1) {
4752 /*
4753 * This isn't the last column, so we need to print a
4754 * separator between this column and the next.
4755 *
4756 * If we printed a network source and are printing a
4757 * network destination of the same type next, separate
4758 * them with a UTF-8 right arrow; if we printed a network
4759 * destination and are printing a network source of the same
4760 * type next, separate them with a UTF-8 left arrow;
4761 * otherwise separate them with a space.
4762 *
4763 * We add enough space to the buffer for " \xe2\x86\x90 "
4764 * or " \xe2\x86\x92 ", even if we're only adding " ".
4765 */
4766 line_bufp = get_line_buf(buf_offset + 5);
4767 switch (col_item->col_fmt) {
4768
4769 case COL_DEF_SRC:
4770 case COL_RES_SRC:
4771 case COL_UNRES_SRC:
4772 switch (cf->cinfo.columns[i+1].col_fmt) {
4773
4774 case COL_DEF_DST:
4775 case COL_RES_DST:
4776 case COL_UNRES_DST:
4777 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW"\u2192", delimiter_char);
4778 put_string(line_bufp + buf_offset, str_format, 5);
4779 buf_offset += 5;
4780 break;
4781
4782 default:
4783 put_string(line_bufp + buf_offset, delimiter_char, 1);
4784 buf_offset += 1;
4785 break;
4786 }
4787 break;
4788
4789 case COL_DEF_DL_SRC:
4790 case COL_RES_DL_SRC:
4791 case COL_UNRES_DL_SRC:
4792 switch (cf->cinfo.columns[i+1].col_fmt) {
4793
4794 case COL_DEF_DL_DST:
4795 case COL_RES_DL_DST:
4796 case COL_UNRES_DL_DST:
4797 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW"\u2192", delimiter_char);
4798 put_string(line_bufp + buf_offset, str_format, 5);
4799 buf_offset += 5;
4800 break;
4801
4802 default:
4803 put_string(line_bufp + buf_offset, delimiter_char, 1);
4804 buf_offset += 1;
4805 break;
4806 }
4807 break;
4808
4809 case COL_DEF_NET_SRC:
4810 case COL_RES_NET_SRC:
4811 case COL_UNRES_NET_SRC:
4812 switch (cf->cinfo.columns[i+1].col_fmt) {
4813
4814 case COL_DEF_NET_DST:
4815 case COL_RES_NET_DST:
4816 case COL_UNRES_NET_DST:
4817 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW"\u2192", delimiter_char);
4818 put_string(line_bufp + buf_offset, str_format, 5);
4819 buf_offset += 5;
4820 break;
4821
4822 default:
4823 put_string(line_bufp + buf_offset, delimiter_char, 1);
4824 buf_offset += 1;
4825 break;
4826 }
4827 break;
4828
4829 case COL_DEF_DST:
4830 case COL_RES_DST:
4831 case COL_UNRES_DST:
4832 switch (cf->cinfo.columns[i+1].col_fmt) {
4833
4834 case COL_DEF_SRC:
4835 case COL_RES_SRC:
4836 case COL_UNRES_SRC:
4837 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW"\u2190", delimiter_char);
4838 put_string(line_bufp + buf_offset, str_format, 5);
4839 buf_offset += 5;
4840 break;
4841
4842 default:
4843 put_string(line_bufp + buf_offset, delimiter_char, 1);
4844 buf_offset += 1;
4845 break;
4846 }
4847 break;
4848
4849 case COL_DEF_DL_DST:
4850 case COL_RES_DL_DST:
4851 case COL_UNRES_DL_DST:
4852 switch (cf->cinfo.columns[i+1].col_fmt) {
4853
4854 case COL_DEF_DL_SRC:
4855 case COL_RES_DL_SRC:
4856 case COL_UNRES_DL_SRC:
4857 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW"\u2190", delimiter_char);
4858 put_string(line_bufp + buf_offset, str_format, 5);
4859 buf_offset += 5;
4860 break;
4861
4862 default:
4863 put_string(line_bufp + buf_offset, delimiter_char, 1);
4864 buf_offset += 1;
4865 break;
4866 }
4867 break;
4868
4869 case COL_DEF_NET_DST:
4870 case COL_RES_NET_DST:
4871 case COL_UNRES_NET_DST:
4872 switch (cf->cinfo.columns[i+1].col_fmt) {
4873
4874 case COL_DEF_NET_SRC:
4875 case COL_RES_NET_SRC:
4876 case COL_UNRES_NET_SRC:
4877 snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW"\u2190", delimiter_char);
4878 put_string(line_bufp + buf_offset, str_format, 5);
4879 buf_offset += 5;
4880 break;
4881
4882 default:
4883 put_string(line_bufp + buf_offset, delimiter_char, 1);
4884 buf_offset += 1;
4885 break;
4886 }
4887 break;
4888
4889 default:
4890 put_string(line_bufp + buf_offset, delimiter_char, 1);
4891 buf_offset += 1;
4892 break;
4893 }
4894 }
4895 }
4896
4897 if (dissect_color && color_filter != NULL((void*)0))
4898 return print_line_color(print_stream, 0, line_bufp, &color_filter->fg_color, &color_filter->bg_color);
4899 else
4900 return print_line(print_stream, 0, line_bufp);
4901}
4902
4903static bool_Bool
4904print_packet(capture_file *cf, epan_dissect_t *edt)
4905{
4906 if (print_summary || output_fields_has_cols(output_fields))
4907 /* Just fill in the columns. */
4908 epan_dissect_fill_in_columns(edt, false0, true1);
4909
4910 /* Print summary columns and/or protocol tree */
4911 switch (output_action) {
4912
4913 case WRITE_TEXT:
4914 if (print_summary && !print_columns(cf, edt))
4915 return false0;
4916 if (print_details) {
4917 if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
4918 print_hex, edt, output_only_tables, print_stream))
4919 return false0;
4920 if (!print_hex) {
4921 if (!print_line(print_stream, 0, separator))
4922 return false0;
4923 }
4924 }
4925 break;
4926
4927 case WRITE_XML:
4928 if (print_summary) {
4929 write_psml_columns(edt, stdoutstdout, dissect_color);
4930 return !ferror(stdoutstdout);
4931 }
4932 if (print_details) {
4933 write_pdml_proto_tree(output_fields, edt, &cf->cinfo, stdoutstdout, dissect_color);
4934 printf("\n");
4935 return !ferror(stdoutstdout);
4936 }
4937 break;
4938
4939 case WRITE_FIELDS:
4940 if (print_summary) {
4941 /*No non-verbose "fields" format */
4942 ws_assert_not_reached()ws_log_fatal_full("Main", LOG_LEVEL_ERROR, "tshark.c", 4942, __func__
, "assertion \"not reached\" failed")
;
4943 }
4944 if (print_details) {
4945 write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdoutstdout);
4946 printf("\n");
4947 return !ferror(stdoutstdout);
4948 }
4949 break;
4950
4951 case WRITE_JSON:
4952 if (print_summary)
4953 ws_assert_not_reached()ws_log_fatal_full("Main", LOG_LEVEL_ERROR, "tshark.c", 4953, __func__
, "assertion \"not reached\" failed")
;
4954 if (print_details) {
4955 write_json_proto_tree(output_fields, print_dissections_expanded,
4956 print_hex, edt, &cf->cinfo, node_children_grouper, &jdumper);
4957 return !ferror(stdoutstdout);
4958 }
4959 break;
4960
4961 case WRITE_JSON_RAW:
4962 if (print_summary)
4963 ws_assert_not_reached()ws_log_fatal_full("Main", LOG_LEVEL_ERROR, "tshark.c", 4963, __func__
, "assertion \"not reached\" failed")
;
4964 if (print_details) {
4965 write_json_proto_tree(output_fields, print_dissections_none,
4966 true1, edt, &cf->cinfo, node_children_grouper, &jdumper);
4967 return !ferror(stdoutstdout);
4968 }
4969 break;
4970
4971 case WRITE_EK:
4972 write_ek_proto_tree(output_fields, print_summary, print_hex,
4973 edt, &cf->cinfo, stdoutstdout);
4974 return !ferror(stdoutstdout);
4975
4976 default:
4977 ws_assert_not_reached()ws_log_fatal_full("Main", LOG_LEVEL_ERROR, "tshark.c", 4977, __func__
, "assertion \"not reached\" failed")
;
4978 }
4979
4980 if (print_hex) {
4981 if (print_summary || print_details) {
4982 if (!print_line(print_stream, 0, ""))
4983 return false0;
4984 }
4985 if (!print_hex_data(print_stream, edt, hexdump_source_option | hexdump_ascii_option | hexdump_timestamp_option))
4986 return false0;
4987 if (!print_line(print_stream, 0, separator))
4988 return false0;
4989 }
4990 return true1;
4991}
4992
4993static bool_Bool
4994write_finale(void)
4995{
4996 switch (output_action) {
4997
4998 case WRITE_TEXT:
4999 return print_finale(print_stream);
5000
5001 case WRITE_XML:
5002 if (print_details)
5003 write_pdml_finale(stdoutstdout);
5004 else
5005 write_psml_finale(stdoutstdout);
5006 return !ferror(stdoutstdout);
5007
5008 case WRITE_FIELDS:
5009 write_fields_finale(output_fields, stdoutstdout);
5010 return !ferror(stdoutstdout);
5011
5012 case WRITE_JSON:
5013 case WRITE_JSON_RAW:
5014 write_json_finale(&jdumper);
5015 return !ferror(stdoutstdout);
5016
5017 case WRITE_EK:
5018 return true1;
5019
5020 default:
5021 ws_assert_not_reached()ws_log_fatal_full("Main", LOG_LEVEL_ERROR, "tshark.c", 5021, __func__
, "assertion \"not reached\" failed")
;
5022 return false0;
5023 }
5024}
5025
5026void
5027cf_close(capture_file *cf)
5028{
5029 if (cf->state == FILE_CLOSED)
5030 return; /* Nothing to do */
5031
5032 if (cf->provider.wth != NULL((void*)0)) {
5033 wtap_close(cf->provider.wth);
5034 cf->provider.wth = NULL((void*)0);
5035 }
5036 /* We have no file open... */
5037 if (cf->filename != NULL((void*)0)) {
5038 /* If it's a temporary file, remove it. */
5039 if (cf->is_tempfile)
5040 ws_unlinkunlink(cf->filename);
5041 g_free(cf->filename);
5042 cf->filename = NULL((void*)0);
5043 }
5044
5045 /* We have no file open. */
5046 cf->state = FILE_CLOSED;
5047}
5048
5049cf_status_t
5050cf_open(capture_file *cf, const char *fname, unsigned int type, bool_Bool is_tempfile, int *err)
5051{
5052 wtap *wth;
5053 char *err_info;
5054
5055 wth = wtap_open_offline(fname, type, err, &err_info, perform_two_pass_analysis, application_configuration_environment_prefix());
5056 if (wth == NULL((void*)0))
5057 goto fail;
5058
5059 /* The open succeeded. Fill in the information for this file. */
5060
5061 cf->provider.wth = wth;
5062 cf->f_datalen = 0; /* not used, but set it anyway */
5063
5064 /* Set the file name because we need it to set the follow stream filter.
5065 XXX - is that still true? We need it for other reasons, though,
5066 in any case. */
5067 cf->filename = g_strdup(fname)g_strdup_inline (fname);
5068
5069 /* Indicate whether it's a permanent or temporary file. */
5070 cf->is_tempfile = is_tempfile;
5071
5072 /* No user changes yet. */
5073 cf->unsaved_changes = false0;
5074
5075 cf->cd_t = wtap_file_type_subtype(cf->provider.wth);
5076 cf->open_type = type;
5077 cf->count = 0;
5078 cf->drops_known = false0;
5079 cf->drops = 0;
5080 cf->snap = wtap_snapshot_length(cf->provider.wth);
5081 nstime_set_zero(&cf->elapsed_time);
5082 cf->provider.ref = NULL((void*)0);
5083 cf->provider.prev_dis = NULL((void*)0);
5084 cf->provider.prev_cap = NULL((void*)0);
5085
5086 cf->state = FILE_READ_IN_PROGRESS;
5087
5088 /* Create new epan session for dissection. */
5089 epan_free(cf->epan);
5090 cf->epan = tshark_epan_new(cf);
5091
5092 wtap_set_cb_new_ipv4(cf->provider.wth, add_ipv4_name);
5093 wtap_set_cb_new_ipv6(cf->provider.wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
5094 wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
5095
5096 return CF_OK;
5097
5098fail:
5099 report_cfile_open_failure(fname, *err, err_info);
5100 return CF_ERROR;
5101}
5102
5103static void
5104show_print_file_io_error(void)
5105{
5106 switch (errno(*__errno_location ())) {
5107
5108 case ENOSPC28:
5109 cmdarg_err("Not all the packets could be printed because there is "
5110 "no space left on the file system.");
5111 break;
5112
5113#ifdef EDQUOT122
5114 case EDQUOT122:
5115 cmdarg_err("Not all the packets could be printed because you are "
5116 "too close to, or over your disk quota.");
5117 break;
5118#endif
5119
5120 case EPIPE32:
5121 /*
5122 * This almost certainly means "the next program after us in
5123 * the pipeline exited before we were finished writing", so
5124 * this isn't a real error, it just means we're done. (We
5125 * don't get SIGPIPE because libwireshark ignores SIGPIPE
5126 * to avoid getting killed if writing to the MaxMind process
5127 * gets SIGPIPE because that process died.)
5128 *
5129 * Presumably either that program exited deliberately (for
5130 * example, "head -N" read N lines and printed them), in
5131 * which case there's no error to report, or it terminated
5132 * due to an error or a signal, in which case *that's* the
5133 * error and that error has been reported.
5134 */
5135 break;
5136
5137 default:
5138#ifdef _WIN32
5139 if (errno(*__errno_location ()) == EINVAL22 && _doserrno == ERROR_NO_DATA) {
5140 /*
5141 * XXX - on Windows, a write to a pipe where the read side
5142 * has been closed apparently may return the Windows error
5143 * ERROR_BROKEN_PIPE, which the Visual Studio C library maps
5144 * to EPIPE, or may return the Windows error ERROR_NO_DATA,
5145 * which the Visual Studio C library maps to EINVAL.
5146 *
5147 * Either of those almost certainly means "the next program
5148 * after us in the pipeline exited before we were finished
5149 * writing", so, if _doserrno is ERROR_NO_DATA, this isn't
5150 * a real error, it just means we're done. (Windows doesn't
5151 * SIGPIPE.)
5152 *
5153 * Presumably either that program exited deliberately (for
5154 * example, "head -N" read N lines and printed them), in
5155 * which case there's no error to report, or it terminated
5156 * due to an error or a signal, in which case *that's* the
5157 * error and that error has been reported.
5158 */
5159 break;
5160 }
5161
5162 /*
5163 * It's a different error; report it, but with the error
5164 * message for _doserrno, which will give more detail
5165 * than just "Invalid argument".
5166 */
5167 cmdarg_err("An error occurred while printing packets: %s.",
5168 win32strerror(_doserrno));
5169#else
5170 cmdarg_err("An error occurred while printing packets: %s.",
5171 g_strerror(errno(*__errno_location ())));
5172#endif
5173 break;
5174 }
5175}
5176
5177static void
5178reset_epan_mem(capture_file *cf,epan_dissect_t *edt, bool_Bool tree, bool_Bool visual)
5179{
5180 if (!epan_auto_reset || (cf->count < epan_auto_reset_count) || !edt)
5181 return;
5182
5183 fprintf(stderrstderr, "resetting session.\n");
5184
5185 epan_dissect_cleanup(edt);
5186 epan_free(cf->epan);
5187
5188 cf->epan = tshark_epan_new(cf);
5189 epan_dissect_init(edt, cf->epan, tree, visual);
5190 cf->count = 0;
5191}