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 /ui | |
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 'ui')
-rw-r--r-- | ui/CMakeLists.txt | 1 | ||||
-rw-r--r-- | ui/Makefile.common | 2 | ||||
-rw-r--r-- | ui/export_pdu_ui_utils.c | 112 | ||||
-rw-r--r-- | ui/export_pdu_ui_utils.h | 43 | ||||
-rw-r--r-- | ui/gtk/export_pdu_dlg.c | 1 | ||||
-rw-r--r-- | ui/qt/export_pdu_dialog.cpp | 1 | ||||
-rw-r--r-- | ui/tap_export_pdu.c | 87 | ||||
-rw-r--r-- | ui/tap_export_pdu.h | 24 |
8 files changed, 212 insertions, 59 deletions
diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt index f7842b8ce7..28d1ab00cf 100644 --- a/ui/CMakeLists.txt +++ b/ui/CMakeLists.txt @@ -31,6 +31,7 @@ set(COMMON_UI_SRC export_object_http.c export_object_smb.c export_object_tftp.c + export_pdu_ui_utils.c help_url.c iface_lists.c io_graph_item.c diff --git a/ui/Makefile.common b/ui/Makefile.common index 05f738f41b..0cd6da548b 100644 --- a/ui/Makefile.common +++ b/ui/Makefile.common @@ -52,6 +52,7 @@ WIRESHARK_UI_SRC = \ export_object_http.c \ export_object_smb.c \ export_object_tftp.c \ + export_pdu_ui_utils.c \ iface_lists.c \ io_graph_item.c \ language.c \ @@ -90,6 +91,7 @@ noinst_HEADERS = \ console.h \ decode_as_utils.h \ export_object.h \ + export_pdu_ui_utils.h \ last_open_dir.h \ file_dialog.h \ help_url.h \ diff --git a/ui/export_pdu_ui_utils.c b/ui/export_pdu_ui_utils.c new file mode 100644 index 0000000000..1a907ab8df --- /dev/null +++ b/ui/export_pdu_ui_utils.c @@ -0,0 +1,112 @@ +/* +* export_pdu_ui_utils.c +* Routines for exported_pdu dissection +* Copyright 2013, Anders Broman <anders-broman@ericsson.com> +* +* Wireshark - Network traffic analyzer +* By Gerald Combs <gerald@wireshark.org> +* Copyright 1998 Gerald Combs +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License along +* with this program; if not, write to the Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "config.h" + +#include "globals.h" +#include "wiretap/pcap-encap.h" +#include "wsutil/os_version_info.h" +#include "wsutil/tempfile.h" +#include "ws_version_info.h" + +#include <epan/tap.h> +#include <epan/exported_pdu.h> +#include <epan/epan_dissect.h> +#include <wiretap/wtap.h> +#include <wiretap/wtap_opttypes.h> +#include <wiretap/pcapng.h> + +#include "ui/alert_box.h" +#include "ui/simple_dialog.h" +#include "tap_export_pdu.h" +#include "export_pdu_ui_utils.h" + +static void +exp_pdu_file_open(exp_pdu_t *exp_pdu_tap_data) +{ + int import_file_fd; + char *tmpname, *capfile_name; + int err; + + /* Choose a random name for the temporary import buffer */ + import_file_fd = create_tempfile(&tmpname, "Wireshark_PDU_"); + capfile_name = g_strdup(tmpname); + + err = exp_pdu_open(exp_pdu_tap_data, import_file_fd, + g_strdup_printf("Dump of PDUs from %s", cfile.filename)); + if (err != 0) { + open_failure_alert_box(capfile_name ? capfile_name : "temporary file", err, TRUE); + goto end; + } + + /* Run the tap */ + cf_retap_packets(&cfile); + + err = exp_pdu_close(exp_pdu_tap_data); + if (err!= 0) { + write_failure_alert_box(capfile_name, err); + } + + /* XXX: should this use the open_routine type in the cfile instead of WTAP_TYPE_AUTO? */ + if (cf_open(&cfile, capfile_name, WTAP_TYPE_AUTO, TRUE /* temporary file */, &err) != CF_OK) { + open_failure_alert_box(capfile_name, err, FALSE); + goto end; + } + + switch (cf_read(&cfile, FALSE)) { + case CF_READ_OK: + case CF_READ_ERROR: + /* Just because we got an error, that doesn't mean we were unable + to read any of the file; we handle what we could get from the + file. */ + break; + + case CF_READ_ABORTED: + /* The user bailed out of re-reading the capture file; the + capture file has been closed - just free the capture file name + string and return (without changing the last containing + directory). */ + break; + } + +end: + g_free(capfile_name); +} + +gboolean +do_export_pdu(const char *filter, gchar *tap_name, exp_pdu_t *exp_pdu_tap_data) +{ + char *error; + error = exp_pdu_pre_open(tap_name, filter, exp_pdu_tap_data); + if (error) { + /* Error. We failed to attach to the tap. Clean up */ + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error); + g_free(error); + return FALSE; + } + + exp_pdu_file_open(exp_pdu_tap_data); + + return TRUE; +}
\ No newline at end of file diff --git a/ui/export_pdu_ui_utils.h b/ui/export_pdu_ui_utils.h new file mode 100644 index 0000000000..54cbd13063 --- /dev/null +++ b/ui/export_pdu_ui_utils.h @@ -0,0 +1,43 @@ +/* +* export_pdu_ui_utils.h +* Routines for exported_pdu dissection +* Copyright 2013, Anders Broman <anders-broman@ericsson.com> +* +* Wireshark - Network traffic analyzer +* By Gerald Combs <gerald@wireshark.org> +* Copyright 1998 Gerald Combs +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License along +* with this program; if not, write to the Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef EXPORT_PDU_UI_UTILS_H +#define EXPORT_PDU_UI_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** +* Filters the current opened capture file into a temporary file. On success, +* TRUE is returned and the filtered file is opened into the UI. +*/ +gboolean do_export_pdu(const char *filter, gchar *tap_name, exp_pdu_t *data); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* EXPORT_PDU_UI_UTILS_H */ diff --git a/ui/gtk/export_pdu_dlg.c b/ui/gtk/export_pdu_dlg.c index 1bc5be7b32..929cce92d4 100644 --- a/ui/gtk/export_pdu_dlg.c +++ b/ui/gtk/export_pdu_dlg.c @@ -41,6 +41,7 @@ #include "ui/tap_export_pdu.h" +#include "ui/export_pdu_ui_utils.h" #include "ui/gtk/export_pdu_dlg.h" static GtkWidget *export_pdu_dlg = NULL; diff --git a/ui/qt/export_pdu_dialog.cpp b/ui/qt/export_pdu_dialog.cpp index d1f9c30120..7316c680a7 100644 --- a/ui/qt/export_pdu_dialog.cpp +++ b/ui/qt/export_pdu_dialog.cpp @@ -32,6 +32,7 @@ #include <epan/exported_pdu.h> #include "ui/tap_export_pdu.h" +#include "ui/export_pdu_ui_utils.h" ExportPDUDialog::ExportPDUDialog(QWidget *parent) : QDialog(parent), diff --git a/ui/tap_export_pdu.c b/ui/tap_export_pdu.c index 608e4a1acb..3131973ed2 100644 --- a/ui/tap_export_pdu.c +++ b/ui/tap_export_pdu.c @@ -25,18 +25,16 @@ #include "globals.h" #include "wiretap/pcap-encap.h" -#include "wsutil/tempfile.h" #include "wsutil/os_version_info.h" #include "ws_version_info.h" #include <epan/tap.h> #include <epan/exported_pdu.h> #include <epan/epan_dissect.h> +#include <wiretap/wtap.h> #include <wiretap/wtap_opttypes.h> #include <wiretap/pcapng.h> -#include "ui/alert_box.h" -#include "ui/simple_dialog.h" #include "tap_export_pdu.h" /* Main entry point to the tap */ @@ -97,10 +95,10 @@ export_pdu_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt, const return FALSE; /* Do not redraw */ } -static void -exp_pdu_file_open(exp_pdu_t *exp_pdu_tap_data) +int +exp_pdu_open(exp_pdu_t *exp_pdu_tap_data, int fd, char *comment) { - char *tmpname, *capfile_name; + int err; /* pcapng defs */ @@ -118,7 +116,7 @@ exp_pdu_file_open(exp_pdu_t *exp_pdu_tap_data) shb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION); /* options */ - opt_comment = g_strdup_printf("Dump of PDUs from %s", cfile.filename); + opt_comment = comment; wtap_optionblock_set_option_string(shb_hdr, OPT_COMMENT, opt_comment); g_free(opt_comment); @@ -153,79 +151,52 @@ exp_pdu_file_open(exp_pdu_t *exp_pdu_tap_data) g_array_append_val(idb_inf->interface_data, int_data); /* Use a random name for the temporary import buffer */ - exp_pdu_tap_data->wdh = wtap_dump_open_tempfile_ng(&tmpname, "Wireshark_PDU_", - WTAP_FILE_TYPE_SUBTYPE_PCAPNG, - WTAP_ENCAP_WIRESHARK_UPPER_PDU, WTAP_MAX_PACKET_SIZE, - FALSE, shb_hdr, idb_inf, NULL, &err); - capfile_name = g_strdup(tmpname); + exp_pdu_tap_data->wdh = wtap_dump_fdopen_ng(fd, WTAP_FILE_TYPE_SUBTYPE_PCAPNG, WTAP_ENCAP_WIRESHARK_UPPER_PDU, WTAP_MAX_PACKET_SIZE, FALSE, + shb_hdr, idb_inf, NULL, &err); if (exp_pdu_tap_data->wdh == NULL) { - open_failure_alert_box(capfile_name ? capfile_name : "temporary file", err, TRUE); - goto end; + g_assert(err != 0); + return err; } - /* Run the tap */ - cf_retap_packets(&cfile); - + return 0; +} - if (!wtap_dump_close(exp_pdu_tap_data->wdh, &err)) { - write_failure_alert_box(capfile_name, err); - } +int +exp_pdu_close(exp_pdu_t *exp_pdu_tap_data) +{ + int err = 0; + if (!wtap_dump_close(exp_pdu_tap_data->wdh, &err)) + g_assert(err != 0); remove_tap_listener(exp_pdu_tap_data); - - /* XXX: should this use the open_routine type in the cfile instead of WTAP_TYPE_AUTO? */ - if (cf_open(&cfile, capfile_name, WTAP_TYPE_AUTO, TRUE /* temporary file */, &err) != CF_OK) { - open_failure_alert_box(capfile_name, err, FALSE); - goto end; - } - - switch (cf_read(&cfile, FALSE)) { - case CF_READ_OK: - case CF_READ_ERROR: - /* Just because we got an error, that doesn't mean we were unable - to read any of the file; we handle what we could get from the - file. */ - break; - - case CF_READ_ABORTED: - /* The user bailed out of re-reading the capture file; the - capture file has been closed - just free the capture file name - string and return (without changing the last containing - directory). */ - break; - } - -end: - g_free(capfile_name); - wtap_optionblock_free(shb_hdr); - wtap_free_idb_info(idb_inf); + return err; } -gboolean -do_export_pdu(const char *filter, gchar *tap_name, exp_pdu_t *exp_pdu_tap_data) + +char * +exp_pdu_pre_open(const char *tap_name, const char *filter, exp_pdu_t *exp_pdu_tap_data) { GString *error_string; + /* XXX: can we always assume WTAP_ENCAP_WIRESHARK_UPPER_PDU? */ + exp_pdu_tap_data->pkt_encap = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU); + /* Register this tap listener now */ error_string = register_tap_listener(tap_name, /* The name of the tap we want to listen to */ exp_pdu_tap_data, /* instance identifier/pointer to a struct holding * all state variables */ filter, /* pointer to a filter string */ - TL_REQUIRES_NOTHING, /* flags for the tap listener */ + TL_REQUIRES_PROTO_TREE, /* flags for the tap listener */ NULL, export_pdu_packet, NULL); - if (error_string){ - /* Error. We failed to attach to the tap. Clean up */ - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str); - g_string_free(error_string, TRUE); - return FALSE; - } + if (error_string != NULL) + return g_string_free(error_string, FALSE); - exp_pdu_file_open(exp_pdu_tap_data); - return TRUE; + return NULL; } + /* * Editor modelines * diff --git a/ui/tap_export_pdu.h b/ui/tap_export_pdu.h index df6b5bad45..49e46ebeff 100644 --- a/ui/tap_export_pdu.h +++ b/ui/tap_export_pdu.h @@ -32,7 +32,29 @@ typedef struct _exp_pdu_t { wtap_dumper* wdh; } exp_pdu_t; -gboolean do_export_pdu(const char *filter, gchar *tap_name, exp_pdu_t *data); +/** +* Registers the tap listener which will add matching packets to the exported +* file. Must be called before exp_pdu_open. +* +* @param tap_name One of the names registered with register_export_pdu_tap(). +* @param filter An tap filter, may be NULL to disable filtering which +* improves performance if you do not need a filter. +* @return NULL on success or an error string on failure which must be freed +* with g_free(). Failure could occur when the filter or tap_name are invalid. +*/ +char *exp_pdu_pre_open(const char *tap_name, const char *filter, + exp_pdu_t *exp_pdu_tap_data); + +/** +* Use the given file descriptor for writing an output file. Can only be called +* once and exp_pdu_pre_open() must be called before. +* +* @return 0 on success or a wtap error code. +*/ +int exp_pdu_open(exp_pdu_t *data, int fd, char *comment); + +/* Stops the PDUs export. */ +int exp_pdu_close(exp_pdu_t *exp_pdu_tap_data); #ifdef __cplusplus } |