diff options
author | AndersBroman <anders.broman@ericsson.com> | 2016-04-29 15:23:28 +0200 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2016-05-03 10:17:46 +0000 |
commit | 6d2ea733ddedf9850883a2dbec43069b92e129bf (patch) | |
tree | d72fb4c216433f40fad65b22dc54a7dbac69f62c /tshark.c | |
parent | 1489c9e6ff1b98bee792c0cb98eb9e1dc1c1e875 (diff) |
Implement Export PDU for tshark
This patch introduces the "-U tap_name[,filter]" tshark option and
is similar to the "Export PDUs as file" option in Wireshark.
Wireshark implements this feature by reopening a capture file, applying
a tap and finally opening the temporary file. Since tshark knows
in advance that a PDU export is needed, it can optimize by not creating
the temporary file and perform the export at the first opportunity.
This patch splits the opening/tapping functionality from error reporting
since tshark does not need a temp file and has no dialogs.
The capture file comment is now specified explicitly as there is no
"current file" anymore if the tap is running without active file.
TODO:
- Review whether it is acceptable to overwrite save_file in tshark.
- Add documentation (tshark manpage).
Bug: 3444
Change-Id: Ie159495d42c32c2ba7400f2991b7b8185b3fda09
Reviewed-on: https://code.wireshark.org/review/5890
Petri-Dish: Anders Broman <a.broman58@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'tshark.c')
-rw-r--r-- | tshark.c | 76 |
1 files changed, 74 insertions, 2 deletions
@@ -84,6 +84,7 @@ #include "ui/ui_util.h" #include "ui/decode_as_utils.h" #include "ui/cli/tshark-tap.h" +#include "ui/tap_export_pdu.h" #include "register.h" #include "filter_files.h" #include <epan/epan_dissect.h> @@ -390,6 +391,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"); @@ -993,6 +995,8 @@ main(int argc, char *argv[]) GSList *disable_protocol_slist = NULL; GSList *enable_heur_slist = NULL; GSList *disable_heur_slist = NULL; + gchar **volatile pdu_export_args = NULL; + exp_pdu_t exp_pdu_tap_data; /* * The leading + ensures that getopt_long() does not permute the argv[] @@ -1013,7 +1017,7 @@ main(int argc, char *argv[]) * We do *not* use a leading - because the behavior of a leading - is * platform-dependent. */ -#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; @@ -1665,6 +1669,13 @@ main(int argc, char *argv[]) return 1; } break; + 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 'v': /* Show version and exit */ comp_info_str = get_compiled_version_info(get_tshark_compiled_version_info, epan_get_compiled_version_info); @@ -2163,6 +2174,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; @@ -2171,8 +2231,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(); tshark_debug("tshark: do_dissection = %s", do_dissection ? "TRUE" : "FALSE"); if (cf_name) { @@ -2212,6 +2275,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 { tshark_debug("tshark: no capture file specified"); /* No capture file specified, so we're supposed to do a live capture |