diff options
Diffstat (limited to 'tshark.c')
-rw-r--r-- | tshark.c | 76 |
1 files changed, 74 insertions, 2 deletions
@@ -98,6 +98,7 @@ #include "ui/util.h" #include "ui/ui_util.h" #include "ui/cli/tshark-tap.h" +#include "ui/tap_export_pdu.h" #include "version_info.h" #include "register.h" #include <epan/epan_dissect.h> @@ -380,6 +381,7 @@ print_usage(FILE *output) fprintf(output, " -W n Save extra information in the file, if supported.\n"); fprintf(output, " n = write network address resolution information\n"); fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n"); + fprintf(output, " -U tap_name[,filter] PDUs export mode, see the man page for details\n"); fprintf(output, " -z <statistics> various statistics, see the man page for details\n"); fprintf(output, " --capture-comment <comment>\n"); fprintf(output, " add a capture comment to the newly created\n"); @@ -1009,11 +1011,13 @@ main(int argc, char *argv[]) int log_flags; int optind_initial; gchar *output_only = NULL; + gchar **pdu_export_args = NULL; + exp_pdu_t exp_pdu_tap_data; /* the leading - ensures that getopt() does not permute the argv[] entries we have to make sure that the first getopt() preserves the content of argv[] for the subsequent getopt_long() call */ -#define OPTSTRING "-2" OPTSTRING_CAPTURE_COMMON "C:d:e:E:F:gG:hH:" "K:lnN:o:O:PqQr:R:S:t:T:u:vVw:W:xX:Y:z:" +#define OPTSTRING "-2" OPTSTRING_CAPTURE_COMMON "C:d:e:E:F:gG:hH:" "K:lnN:o:O:PqQr:R:S:t:T:u:U:vVw:W:xX:Y:z:" static const char optstring[] = OPTSTRING; @@ -1630,6 +1634,13 @@ main(int argc, char *argv[]) epan_cleanup(); return 0; } + case 'U': /* Export PDUs to file */ + if (!*optarg) { + cmdarg_err("Tap name is required!"); + return 1; + } + pdu_export_args = g_strsplit(optarg, ",", 2); + break; case 'O': /* Only output these protocols */ /* already processed; just ignore it now */ break; @@ -2066,6 +2077,55 @@ main(int argc, char *argv[]) } } + /* PDU export requested. Take the ownership of the '-w' file, apply tap + * filters and start tapping. */ + if (pdu_export_args) { + const char *exp_pdu_filename; + const char *exp_pdu_tap_name = pdu_export_args[0]; + const char *exp_pdu_filter = pdu_export_args[1]; /* may be NULL to disable filter */ + char *exp_pdu_error; + int exp_fd; + + if (!cf_name) { + cmdarg_err("PDUs export requires a capture file (specify with -r)."); + return 1; + } + /* Take ownership of the '-w' output file. */ +#ifdef HAVE_LIBPCAP + exp_pdu_filename = global_capture_opts.save_file; + global_capture_opts.save_file = NULL; +#else + exp_pdu_filename = output_file_name; + output_file_name = NULL; +#endif + if (exp_pdu_filename == NULL) { + cmdarg_err("PDUs export requires an output file (-w)."); + return 1; + } + + exp_pdu_error = exp_pdu_pre_open(exp_pdu_tap_name, exp_pdu_filter, + &exp_pdu_tap_data); + if (exp_pdu_error) { + cmdarg_err("Cannot register tap: %s", exp_pdu_error); + g_free(exp_pdu_error); + return 2; + } + + exp_fd = ws_open(exp_pdu_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); + if (exp_fd == -1) { + cmdarg_err("%s: %s", exp_pdu_filename, file_open_error_message(errno, TRUE)); + return 2; + } + + /* Activate the export PDU tap */ + err = exp_pdu_open(&exp_pdu_tap_data, exp_fd, + g_strdup_printf("Dump of PDUs from %s", cf_name)); + if (err != 0) { + cmdarg_err("Failed to start the PDU export: %s", g_strerror(err)); + return 2; + } + } + /* We have to dissect each packet if: we're printing information about each packet; @@ -2074,8 +2134,11 @@ main(int argc, char *argv[]) we're using a display filter on the packets; + we're exporting PDUs; + we're using any taps that need dissection. */ - do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection(); + do_dissection = print_packet_info || rfcode || dfcode || pdu_export_args || + tap_listeners_require_dissection(); if (cf_name) { /* @@ -2112,6 +2175,15 @@ main(int argc, char *argv[]) read some packets; however, we exit with an error status. */ exit_status = 2; } + + if (pdu_export_args) { + err = exp_pdu_close(&exp_pdu_tap_data); + if (err) { + cmdarg_err("%s", wtap_strerror(err)); + exit_status = 2; + } + g_strfreev(pdu_export_args); + } } else { /* No capture file specified, so we're supposed to do a live capture or get a list of link-layer types for a live capture device; |