diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/CMakeLists.txt | 7 | ||||
-rw-r--r-- | ui/Makefile.am | 9 | ||||
-rw-r--r-- | ui/cli/Makefile.am | 2 | ||||
-rw-r--r-- | ui/cli/tap-exportobject.c | 279 | ||||
-rw-r--r-- | ui/cli/tap-exportobject.h | 55 | ||||
-rw-r--r-- | ui/export_object.h | 89 | ||||
-rw-r--r-- | ui/export_object_dicom.c | 78 | ||||
-rw-r--r-- | ui/export_object_http.c | 75 | ||||
-rw-r--r-- | ui/export_object_imf.c | 75 | ||||
-rw-r--r-- | ui/export_object_smb.c | 470 | ||||
-rw-r--r-- | ui/export_object_tftp.c | 138 | ||||
-rw-r--r-- | ui/export_object_ui.c (renamed from ui/export_object.c) | 87 | ||||
-rw-r--r-- | ui/export_object_ui.h | 55 | ||||
-rw-r--r-- | ui/gtk/export_object_dlg.c | 115 | ||||
-rw-r--r-- | ui/gtk/export_object_dlg.h | 8 | ||||
-rw-r--r-- | ui/gtk/main_menubar.c | 86 | ||||
-rw-r--r-- | ui/qt/CMakeLists.txt | 2 | ||||
-rw-r--r-- | ui/qt/Makefile.am | 2 | ||||
-rw-r--r-- | ui/qt/export_object_action.cpp | 65 | ||||
-rw-r--r-- | ui/qt/export_object_action.h | 64 | ||||
-rw-r--r-- | ui/qt/export_object_dialog.cpp | 209 | ||||
-rw-r--r-- | ui/qt/export_object_dialog.h | 28 | ||||
-rw-r--r-- | ui/qt/main_window.cpp | 24 | ||||
-rw-r--r-- | ui/qt/main_window.h | 8 | ||||
-rw-r--r-- | ui/qt/main_window.ui | 30 | ||||
-rw-r--r-- | ui/qt/main_window_slots.cpp | 36 |
26 files changed, 836 insertions, 1260 deletions
diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt index 9b38bf9c93..5bd5ec051c 100644 --- a/ui/CMakeLists.txt +++ b/ui/CMakeLists.txt @@ -28,12 +28,7 @@ set(COMMON_UI_SRC console.c decode_as_utils.c dissect_opts.c - export_object.c - export_object_dicom.c - export_object_http.c - export_object_imf.c - export_object_smb.c - export_object_tftp.c + export_object_ui.c export_pdu_ui_utils.c help_url.c firewall_rules.c diff --git a/ui/Makefile.am b/ui/Makefile.am index 8359bf7358..3507f9acbd 100644 --- a/ui/Makefile.am +++ b/ui/Makefile.am @@ -55,12 +55,7 @@ WIRESHARK_UI_SRC = \ console.c \ decode_as_utils.c \ dissect_opts.c \ - export_object.c \ - export_object_dicom.c \ - export_object_http.c \ - export_object_imf.c \ - export_object_smb.c \ - export_object_tftp.c \ + export_object_ui.c \ export_pdu_ui_utils.c \ firewall_rules.c \ iface_lists.c \ @@ -102,7 +97,7 @@ WIRESHARK_UI_INCLUDES = \ console.h \ decode_as_utils.h \ dissect_opts.h \ - export_object.h \ + export_object_ui.h \ export_pdu_ui_utils.h \ last_open_dir.h \ file_dialog.h \ diff --git a/ui/cli/Makefile.am b/ui/cli/Makefile.am index e5414985e4..a9f1c3aa32 100644 --- a/ui/cli/Makefile.am +++ b/ui/cli/Makefile.am @@ -47,7 +47,9 @@ TSHARK_TAP_SRC = \ tap-comparestat.c \ tap-diameter-avp.c \ tap-endpoints.c \ + tap-endpoints.c \ tap-expert.c \ + tap-exportobject.c \ tap-follow.c \ tap-funnel.c \ tap-gsm_astat.c \ diff --git a/ui/cli/tap-exportobject.c b/ui/cli/tap-exportobject.c new file mode 100644 index 0000000000..7ea0f207b4 --- /dev/null +++ b/ui/cli/tap-exportobject.c @@ -0,0 +1,279 @@ +/* tap-exportobject.c + * + * 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 <glib.h> + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +#include <string.h> + +#include <wsutil/file_util.h> + +#include <epan/packet_info.h> +#include <epan/packet.h> +#include <epan/export_object.h> +#include <ui/export_object_ui.h> +#include "tap-exportobject.h" + +/* XXX - This is effectively a copy of eo_save_entry with the "GUI alerts" + * removed to accomodate tshark + */ +static gboolean +local_eo_save_entry(const gchar *save_as_filename, export_object_entry_t *entry) +{ + int to_fd; + gint64 bytes_left; + int bytes_to_write; + ssize_t bytes_written; + guint8 *ptr; + + to_fd = ws_open(save_as_filename, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0644); + if(to_fd == -1) { /* An error occurred */ + return FALSE; + } + + /* + * The third argument to _write() on Windows is an unsigned int, + * so, on Windows, that's the size of the third argument to + * ws_write(). + * + * The third argument to write() on UN*X is a size_t, although + * the return value is an ssize_t, so one probably shouldn't + * write more than the max value of an ssize_t. + * + * In either case, there's no guarantee that a gint64 such as + * payload_len can be passed to ws_write(), so we write in + * chunks of, at most 2^31 bytes. + */ + ptr = entry->payload_data; + bytes_left = entry->payload_len; + while (bytes_left != 0) { + if (bytes_left > 0x40000000) + bytes_to_write = 0x40000000; + else + bytes_to_write = (int)bytes_left; + bytes_written = ws_write(to_fd, ptr, bytes_to_write); + if(bytes_written <= 0) { + ws_close(to_fd); + return FALSE; + } + bytes_left -= bytes_written; + ptr += bytes_written; + } + if (ws_close(to_fd) < 0) { + return FALSE; + } + + return TRUE; +} + +typedef struct _export_object_list_gui_t { + GSList *entries; + register_eo_t* eo; +} export_object_list_gui_t; + +static GHashTable* eo_opts = NULL; + +static void +list_exportobject_protocol(gpointer data, gpointer user_data _U_) +{ + register_eo_t *eo = (register_eo_t*)data; + + fprintf(stderr, " %s\n", proto_get_protocol_filter_name(get_eo_proto_id(eo))); +} + +void eo_list_object_types(void) +{ + eo_iterate_tables(list_exportobject_protocol, NULL); +} + +gboolean eo_tap_opt_add(const char *option_string) +{ + gchar** splitted; + + if (!eo_opts) + eo_opts = g_hash_table_new(g_str_hash,g_str_equal); + + splitted = g_strsplit(option_string, ",", 2); + + if ((splitted[0] == NULL) || (splitted[1] == NULL) || (get_eo_by_name(splitted[0]) == NULL)) + { + fprintf(stderr, "tshark: \"--export-objects\" are specified as: <protocol>,<destdir>\n"); + fprintf(stderr, "tshark: The available export object types for the \"--export-objects\" option are:\n"); + eo_list_object_types(); + } + else + { + gchar* dir = (gchar*)g_hash_table_lookup(eo_opts, splitted[0]); + + /* Since we're saving all objects from a protocol, + it can only be listed once */ + if (dir == NULL) { + g_hash_table_insert(eo_opts, splitted[0], splitted[1]); + + g_free(splitted); + return TRUE; + } + else + { + fprintf(stderr, "tshark: \"--export-objects\" already specified protocol '%s'\n", splitted[0]); + } + } + + g_strfreev(splitted); + return FALSE; +} + +static void +object_list_add_entry(void *gui_data, export_object_entry_t *entry) +{ + export_object_list_gui_t *object_list = (export_object_list_gui_t*)gui_data; + + object_list->entries = g_slist_append(object_list->entries, entry); +} + +static export_object_entry_t* +object_list_get_entry(void *gui_data, int row) { + export_object_list_gui_t *object_list = (export_object_list_gui_t*)gui_data; + + return (export_object_entry_t *)g_slist_nth_data(object_list->entries, row); +} + +/* This is just for writing Exported Objects to a file */ +static void +eo_draw(void *tapdata) +{ + export_object_list_t *tap_object = (export_object_list_t *)tapdata; + export_object_list_gui_t *object_list = (export_object_list_gui_t*)tap_object->gui_data; + GSList *slist = object_list->entries; + export_object_entry_t *entry; + gboolean all_saved = TRUE; + gchar* save_in_path = (gchar*)g_hash_table_lookup(eo_opts, proto_get_protocol_filter_name(get_eo_proto_id(object_list->eo))); + GString *safe_filename = NULL; + gchar *save_as_fullpath = NULL; + int count = 0; + + if (!g_file_test(save_in_path, G_FILE_TEST_IS_DIR)) { + /* If the destination directory (or its parents) do not exist, create them. */ + if (g_mkdir_with_parents(save_in_path, 0755) == -1) { + fprintf(stderr, "Failed to create export objects output directory \"%s\": %s\n", + save_in_path, g_strerror(errno)); + return; + } + } + + if ((strlen(save_in_path) < EXPORT_OBJECT_MAXFILELEN)) { + while (slist) { + entry = (export_object_entry_t *)slist->data; + do { + g_free(save_as_fullpath); + if (entry->filename) { + safe_filename = eo_massage_str(entry->filename, + EXPORT_OBJECT_MAXFILELEN - strlen(save_in_path), count); + } else { + char generic_name[EXPORT_OBJECT_MAXFILELEN+1]; + const char *ext; + ext = eo_ct2ext(entry->content_type); + g_snprintf(generic_name, sizeof(generic_name), + "object%u%s%s", entry->pkt_num, ext ? "." : "", ext ? ext : ""); + safe_filename = eo_massage_str(generic_name, + EXPORT_OBJECT_MAXFILELEN - strlen(save_in_path), count); + } + save_as_fullpath = g_build_filename(save_in_path, safe_filename->str, NULL); + g_string_free(safe_filename, TRUE); + } while (g_file_test(save_as_fullpath, G_FILE_TEST_EXISTS) && ++count < 1000); + count = 0; + if (!local_eo_save_entry(save_as_fullpath, entry)) + all_saved = FALSE; + g_free(save_as_fullpath); + save_as_fullpath = NULL; + slist = slist->next; + } + } + else + { + all_saved = FALSE; + } + + if (!all_saved) + fprintf(stderr, "Export objects (%s): Some files could not be saved.\n", + proto_get_protocol_filter_name(get_eo_proto_id(object_list->eo))); +} + +static void +exportobject_handler(gpointer key, gpointer value _U_, gpointer user_data _U_) +{ + GString *error_msg; + export_object_list_t *tap_data; + export_object_list_gui_t *object_list; + register_eo_t* eo; + + eo = get_eo_by_name((const char*)key); + if (eo == NULL) + { + fprintf(stderr, "tshark: \"--export-objects\" INTERNAL ERROR '%s' protocol not found\n", (const char*)key); + return; + } + + tap_data = g_new0(export_object_list_t,1); + object_list = g_new0(export_object_list_gui_t,1); + + tap_data->add_entry = object_list_add_entry; + tap_data->get_entry = object_list_get_entry; + tap_data->gui_data = (void*)object_list; + + object_list->eo = eo; + + /* Data will be gathered via a tap callback */ + error_msg = register_tap_listener(get_eo_tap_listener_name(eo), tap_data, NULL, 0, + NULL, get_eo_packet_func(eo), eo_draw); + + if (error_msg) { + fprintf(stderr, "tshark: Can't register %s tap: %s\n", (const char*)key, error_msg->str); + g_string_free(error_msg, TRUE); + g_free(tap_data); + g_free(object_list); + return; + } +} + +void start_exportobjects(void) +{ + if (eo_opts != NULL) + g_hash_table_foreach(eo_opts, exportobject_handler, NULL); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/cli/tap-exportobject.h b/ui/cli/tap-exportobject.h new file mode 100644 index 0000000000..25cfa333e3 --- /dev/null +++ b/ui/cli/tap-exportobject.h @@ -0,0 +1,55 @@ +/* tap-exportobject.h + * + * 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 __TAP_EXPORT_OBJECT_H__ +#define __TAP_EXPORT_OBJECT_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define LONGOPT_EXPORT_OBJECTS 5001 + +void eo_list_object_types(void); + +/* will be called by main each time a --export-objects option is found */ +gboolean eo_tap_opt_add(const char *optarg); + +void start_exportobjects(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __TAP_EXPORT_OBJECT_H__ */ + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: t + * End: + * + * vi: set shiftwidth=8 tabstop=8 noexpandtab: + * :indentSize=8:tabSize=8:noTabs=false: + */ diff --git a/ui/export_object.h b/ui/export_object.h deleted file mode 100644 index af71eedbde..0000000000 --- a/ui/export_object.h +++ /dev/null @@ -1,89 +0,0 @@ -/* export_object.h - * Common routines for tracking & saving objects found in streams of data - * Copyright 2007, Stephen Fisher (see AUTHORS file) - * - * 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_OBJECT_H__ -#define __EXPORT_OBJECT_H__ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Common between protocols */ - -struct _export_object_list_t; -typedef struct _export_object_list_t export_object_list_t; - -typedef struct _export_object_entry_t { - guint32 pkt_num; - gchar *hostname; - gchar *content_type; - gchar *filename; - /* We need to store a 64 bit integer to hold a file length - (was guint payload_len;) */ - gint64 payload_len; - guint8 *payload_data; -} export_object_entry_t; - -void object_list_add_entry(export_object_list_t *object_list, export_object_entry_t *entry); -export_object_entry_t *object_list_get_entry(export_object_list_t *object_list, int row); - -gboolean eo_save_entry(const gchar *save_as_filename, export_object_entry_t *entry, gboolean show_err); -GString *eo_massage_str(const gchar *in_str, gsize maxlen, int dup); -const char *ct2ext(const char *content_type); - - -/* Protocol specific */ -gboolean eo_dicom_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, - const void *data); -gboolean eo_http_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, - const void *data); -gboolean eo_imf_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, - const void *data); -gboolean eo_smb_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, - const void *data); -gboolean eo_tftp_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, - const void *data); - -void eo_smb_cleanup(void); -void eo_tftp_cleanup(void); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __EXPORT_OBJECT_H__ */ - -/* - * Editor modelines - * - * Local Variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * ex: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ diff --git a/ui/export_object_dicom.c b/ui/export_object_dicom.c deleted file mode 100644 index 5404abb54f..0000000000 --- a/ui/export_object_dicom.c +++ /dev/null @@ -1,78 +0,0 @@ -/* export_object_dicom.c - * Routines for tracking & saving objects found in DICOM streams - * See also: export_object.c / export_object.h for common code - * Copyright 2008, David Aggeler <david_aggeler@hispeed.ch> - * - * 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 <glib.h> - -#include <epan/dissectors/packet-dcm.h> - -#include <epan/packet.h> -#include <epan/tap.h> - -#include "export_object.h" - -gboolean -eo_dicom_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, - const void *data) -{ - export_object_list_t *object_list = (export_object_list_t *)tapdata; - const dicom_eo_t *eo_info = (const dicom_eo_t *)data; - export_object_entry_t *entry; - - if (eo_info) { /* We have data waiting for us */ - /* - Don't copy any data. dcm_export_create_object() is already g_malloc() the items - Still, the values will be freed when the export Object window is closed. - Therefore, strings and buffers must be copied - */ - entry = (export_object_entry_t *)g_malloc(sizeof(export_object_entry_t)); - - entry->pkt_num = pinfo->num; - entry->hostname = eo_info->hostname; - entry->content_type = eo_info->content_type; - entry->filename = g_strdup(g_path_get_basename(eo_info->filename)); - entry->payload_len = eo_info->payload_len; - entry->payload_data = eo_info->payload_data; - - object_list_add_entry(object_list, entry); - - return TRUE; /* State changed - window should be redrawn */ - } else { - return FALSE; /* State unchanged - no window updates needed */ - } -} -/* - * Editor modelines - * - * Local Variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * ex: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ diff --git a/ui/export_object_http.c b/ui/export_object_http.c deleted file mode 100644 index 3b314c4fb5..0000000000 --- a/ui/export_object_http.c +++ /dev/null @@ -1,75 +0,0 @@ -/* export_object_http.c - * Routines for tracking & saving objects found in HTTP streams - * See also: export_object.c / export_object.h for common code - * Copyright 2007, Stephen Fisher (see AUTHORS file) - * - * 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 <epan/dissectors/packet-http.h> -#include <epan/tap.h> - -#include "export_object.h" - - -gboolean -eo_http_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, - const void *data) -{ - export_object_list_t *object_list = (export_object_list_t *)tapdata; - const http_eo_t *eo_info = (const http_eo_t *)data; - export_object_entry_t *entry; - - if(eo_info) { /* We have data waiting for us */ - /* These values will be freed when the Export Object window - * is closed. */ - entry = (export_object_entry_t *)g_malloc(sizeof(export_object_entry_t)); - - entry->pkt_num = pinfo->num; - entry->hostname = g_strdup(eo_info->hostname); - entry->content_type = g_strdup(eo_info->content_type); - entry->filename = g_strdup(g_path_get_basename(eo_info->filename)); - entry->payload_len = eo_info->payload_len; - entry->payload_data = (guint8 *)g_memdup(eo_info->payload_data, - eo_info->payload_len); - - object_list_add_entry(object_list, entry); - - return TRUE; /* State changed - window should be redrawn */ - } else { - return FALSE; /* State unchanged - no window updates needed */ - } -} - -/* - * Editor modelines - * - * Local Variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * ex: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ diff --git a/ui/export_object_imf.c b/ui/export_object_imf.c deleted file mode 100644 index 5e4e275691..0000000000 --- a/ui/export_object_imf.c +++ /dev/null @@ -1,75 +0,0 @@ -/* export_object_imf.c - * Routines for tracking & saving objects found in IMF streams - * See also: export_object.c / export_object.h for common code - * Copyright 2016, Moshe Kaplan - * - * 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 <epan/dissectors/packet-imf.h> -#include <epan/tap.h> - -#include "export_object.h" - - -gboolean -eo_imf_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, - const void *data) -{ - export_object_list_t *object_list = (export_object_list_t *)tapdata; - const imf_eo_t *eo_info = (const imf_eo_t *)data; - export_object_entry_t *entry; - - if(eo_info) { /* We have data waiting for us */ - /* These values will be freed when the Export Object window - * is closed. */ - entry = (export_object_entry_t *)g_malloc(sizeof(export_object_entry_t)); - - entry->pkt_num = pinfo->num; - entry->hostname = NULL; - entry->content_type = g_strdup("EML file"); - entry->filename = g_strdup_printf("from_%s_subject_%s.eml", eo_info->sender_data, eo_info->subject_data); - entry->payload_len = eo_info->payload_len; - entry->payload_data = (guint8 *)g_memdup(eo_info->payload_data, - eo_info->payload_len); - - object_list_add_entry(object_list, entry); - - return TRUE; /* State changed - window should be redrawn */ - } else { - return FALSE; /* State unchanged - no window updates needed */ - } -} - -/* - * Editor modelines - * - * Local Variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * ex: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ diff --git a/ui/export_object_smb.c b/ui/export_object_smb.c deleted file mode 100644 index 4ccd1c07f2..0000000000 --- a/ui/export_object_smb.c +++ /dev/null @@ -1,470 +0,0 @@ -/* export_object_smb.c - * Routines for tracking & saving objects (files) found in SMB streams - * See also: export_object.c / export_object.h for common code - * Initial file, prototypes and general structure initially copied - * from export_object_http.c - * - * Copyright 2010, David Perez & Jose Pico from TADDONG S.L. - * - * 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 <epan/packet.h> -#include <epan/dissectors/packet-smb2.h> -#include <epan/tap.h> - -#include "export_object.h" - - -/* These flags show what kind of data the object contains - (designed to be or'ed) */ -#define SMB_EO_CONTAINS_NOTHING 0x00 -#define SMB_EO_CONTAINS_READS 0x01 -#define SMB_EO_CONTAINS_WRITES 0x02 -#define SMB_EO_CONTAINS_READSANDWRITES 0x03 -#define LEGAL_FILENAME_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_.- /\\{}[]=()&%$!,;.+&%$~#@" - -static const value_string smb_eo_contains_string[] = { - {SMB_EO_CONTAINS_NOTHING, "" }, - {SMB_EO_CONTAINS_READS, "R" }, - {SMB_EO_CONTAINS_WRITES, "W" }, - {SMB_EO_CONTAINS_READSANDWRITES, "R&W"}, - {0, NULL} -}; - -/* Strings that describes the SMB object type */ -static const value_string smb_fid_types[] = { - {SMB_FID_TYPE_UNKNOWN,"UNKNOWN"}, - {SMB_FID_TYPE_FILE,"FILE"}, - {SMB_FID_TYPE_DIR,"DIRECTORY (Not Implemented)"}, - {SMB_FID_TYPE_PIPE,"PIPE (Not Implemented)"}, - {0, NULL} -}; - -static const value_string smb2_fid_types[] = { - {SMB2_FID_TYPE_UNKNOWN,"UNKNOWN"}, - {SMB2_FID_TYPE_FILE,"FILE"}, - {SMB2_FID_TYPE_DIR,"DIRECTORY (Not Implemented)"}, - {SMB2_FID_TYPE_PIPE,"PIPE (Not Implemented)"}, - {SMB2_FID_TYPE_OTHER,"OTHER (Not Implemented)"}, - {0, NULL} -}; - -/* This struct contains the relationship between - the row# in the export_object window and the file being captured; - the row# in this GSList will match the row# in the entry list */ - -typedef struct _active_file { - guint16 tid, uid, fid; - guint64 file_length; /* The last free reported offset */ - /* We treat it as the file length */ - guint64 data_gathered; /* The actual total of data gathered */ - guint8 flag_contains; /* What kind of data it contains */ - GSList *free_chunk_list; /* A list of virtual "holes" in the */ - /* file stream stored in memory */ - gboolean is_out_of_memory; /* TRUE if we cannot allocate memory */ - /* memory for this file */ - } active_file ; - -/* This is the GSList that will contain all the files that we are tracking */ -static GSList *GSL_active_files = NULL; - -/* We define a free chunk in a file as an start offset and end offset - Consider a free chunk as a "hole" in a file that we are capturing */ -typedef struct _free_chunk { - guint64 start_offset; - guint64 end_offset; -} free_chunk; - -/* insert_chunk function will recalculate the free_chunk_list, the data_size, - the end_of_file, and the data_gathered as appropriate. - It will also insert the data chunk that is coming in the right - place of the file in memory. - HINTS: - file->data_gathered contains the real data gathered independently - from the file length - file->file_length contains the length of the file in memory, i.e., - the last offset captured. In most cases, the real - file length would be different. -*/ -static void -insert_chunk(active_file *file, export_object_entry_t *entry, const smb_eo_t *eo_info) -{ - gint nfreechunks = g_slist_length(file->free_chunk_list); - gint i; - free_chunk *current_free_chunk; - free_chunk *new_free_chunk; - guint64 chunk_offset = eo_info->smb_file_offset; - guint64 chunk_length = eo_info->payload_len; - guint64 chunk_end_offset = chunk_offset + chunk_length-1; -/* Size of file in memory */ - guint64 calculated_size = chunk_offset + chunk_length; - gpointer dest_memory_addr; - - /* Let's recalculate the file length and data gathered */ - if ((file->data_gathered == 0) && (nfreechunks == 0)) { - /* If this is the first entry for this file, we first - create an initial free chunk */ - new_free_chunk = (free_chunk *)g_malloc(sizeof(free_chunk)); - new_free_chunk->start_offset = 0; - new_free_chunk->end_offset = MAX(file->file_length, chunk_end_offset+1) - 1; - file->free_chunk_list = NULL; - file->free_chunk_list = g_slist_append(file->free_chunk_list, new_free_chunk); - nfreechunks += 1; - } else { - if (chunk_end_offset > file->file_length-1) { - new_free_chunk = (free_chunk *)g_malloc(sizeof(free_chunk)); - new_free_chunk->start_offset = file->file_length; - new_free_chunk->end_offset = chunk_end_offset; - file->free_chunk_list = g_slist_append(file->free_chunk_list, new_free_chunk); - nfreechunks += 1; - } - } - file->file_length = MAX(file->file_length, chunk_end_offset+1); - - /* Recalculate each free chunk according with the incoming data chunk */ - for (i=0; i<nfreechunks; i++) { - current_free_chunk = (free_chunk *)g_slist_nth_data(file->free_chunk_list, i); - /* 1. data chunk before the free chunk? */ - /* -> free chunk is not altered and no new data gathered */ - if (chunk_end_offset<current_free_chunk->start_offset) { - continue; - } - /* 2. data chunk overlaps the first part of free_chunk */ - /* -> free chunk shrinks from the beginning */ - if (chunk_offset<=current_free_chunk->start_offset && chunk_end_offset>=current_free_chunk->start_offset && chunk_end_offset<current_free_chunk->end_offset) { - file->data_gathered += chunk_end_offset-current_free_chunk->start_offset+1; - current_free_chunk->start_offset=chunk_end_offset+1; - continue; - } - /* 3. data chunk overlaps completely the free chunk */ - /* -> free chunk is removed */ - if (chunk_offset<=current_free_chunk->start_offset && chunk_end_offset>=current_free_chunk->end_offset) { - file->data_gathered += current_free_chunk->end_offset-current_free_chunk->start_offset+1; - file->free_chunk_list = g_slist_remove(file->free_chunk_list, current_free_chunk); - nfreechunks -= 1; - if (nfreechunks == 0) { /* The free chunk list is empty */ - g_slist_free(file->free_chunk_list); - file->free_chunk_list = NULL; - break; - } - i--; - continue; - } - /* 4. data chunk is inside the free chunk */ - /* -> free chunk is split into two */ - if (chunk_offset>current_free_chunk->start_offset && chunk_end_offset<current_free_chunk->end_offset) { - new_free_chunk = (free_chunk *)g_malloc(sizeof(free_chunk)); - new_free_chunk->start_offset = chunk_end_offset + 1; - new_free_chunk->end_offset = current_free_chunk->end_offset; - current_free_chunk->end_offset = chunk_offset-1; - file->free_chunk_list = g_slist_insert(file->free_chunk_list, new_free_chunk, i + 1); - file->data_gathered += chunk_length; - continue; - } - /* 5.- data chunk overlaps the end part of free chunk */ - /* -> free chunk shrinks from the end */ - if (chunk_offset>current_free_chunk->start_offset && chunk_offset<=current_free_chunk->end_offset && chunk_end_offset>=current_free_chunk->end_offset) { - file->data_gathered += current_free_chunk->end_offset-chunk_offset+1; - current_free_chunk->end_offset = chunk_offset-1; - continue; - } - /* 6.- data chunk is after the free chunk */ - /* -> free chunk is not altered and no new data gathered */ - if (chunk_offset>current_free_chunk->end_offset) { - continue; - } - } - - /* Now, let's insert the data chunk into memory - ...first, we shall be able to allocate the memory */ - if (!entry->payload_data) { - /* This is a New file */ - if (calculated_size > G_MAXSIZE) { - /* - * The argument to g_try_malloc() is - * a gsize, the maximum value of which is - * G_MAXSIZE. If the calculated size is - * bigger than that, we just say the attempt - * to allocate memory failed. - */ - entry->payload_data = NULL; - } else { - entry->payload_data = (guint8 *)g_try_malloc((gsize)calculated_size); - entry->payload_len = calculated_size; - } - if (!entry->payload_data) { - /* Memory error */ - file->is_out_of_memory = TRUE; - } - } else { - /* This is an existing file in memory */ - if (calculated_size > (guint64) entry->payload_len && - !file->is_out_of_memory) { - /* We need more memory */ - if (calculated_size > G_MAXSIZE) { - /* - * As for g_try_malloc(), so for - * g_try_realloc(). - */ - dest_memory_addr = NULL; - } else { - dest_memory_addr = g_try_realloc( - entry->payload_data, - (gsize)calculated_size); - } - if (!dest_memory_addr) { - /* Memory error */ - file->is_out_of_memory = TRUE; - /* We don't have memory for this file. - Free the current file content from memory */ - g_free(entry->payload_data); - entry->payload_data = NULL; - entry->payload_len = 0; - } else { - entry->payload_data = (guint8 *)dest_memory_addr; - entry->payload_len = calculated_size; - } - } - } - /* ...then, put the chunk of the file in the right place */ - if (!file->is_out_of_memory) { - dest_memory_addr = entry->payload_data + chunk_offset; - memmove(dest_memory_addr, eo_info->payload_data, eo_info->payload_len); - } -} - -/* We use this function to obtain the index in the GSL of a given file */ -static int -find_incoming_file(GSList *GSL_active_files_p, active_file *incoming_file) -{ - int i, row, last; - active_file *in_list_file; - - row = -1; - last = g_slist_length(GSL_active_files_p) - 1; - - /* We lookup in reverse order because it is more likely that the file - is one of the latest */ - for (i=last; i>=0; i--) { - in_list_file = (active_file *)g_slist_nth_data(GSL_active_files_p, i); - /* The best-working criteria of two identical files is that the file - that is the same of the file that we are analyzing is the last one - in the list that has the same tid and the same fid */ - /* note that we have excluded in_list_file->uid == incoming_file->uid - from the comparison, because a file can be opened by different - SMB users and it is still the same file */ - if (in_list_file->tid == incoming_file->tid && - in_list_file->fid == incoming_file->fid) { - row = i; - break; - } - } - - return row; -} - -/* This is the function answering to the registered tap listener call */ -gboolean -eo_smb_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data) -{ - export_object_list_t *object_list = (export_object_list_t *)tapdata; - const smb_eo_t *eo_info = (const smb_eo_t *)data; - - export_object_entry_t *entry; - export_object_entry_t *current_entry; - active_file incoming_file; - gint active_row; - active_file *new_file; - active_file *current_file; - guint8 contains; - gboolean is_supported_filetype; - gfloat percent; - - gchar *aux_smb_fid_type_string; - - if (eo_info->smbversion==1) { - /* Is this an eo_smb supported file_type? (right now we only support FILE) */ - is_supported_filetype = (eo_info->fid_type == SMB_FID_TYPE_FILE); - aux_smb_fid_type_string=g_strdup(try_val_to_str(eo_info->fid_type, smb_fid_types)); - - /* What kind of data this packet contains? */ - switch(eo_info->cmd) { - case SMB_COM_READ_ANDX: - case SMB_COM_READ: - contains = SMB_EO_CONTAINS_READS; - break; - case SMB_COM_WRITE_ANDX: - case SMB_COM_WRITE: - contains = SMB_EO_CONTAINS_WRITES; - break; - default: - contains = SMB_EO_CONTAINS_NOTHING; - break; - } - } else { - /* Is this an eo_smb supported file_type? (right now we only support FILE) */ - is_supported_filetype = (eo_info->fid_type == SMB2_FID_TYPE_FILE ); - aux_smb_fid_type_string=g_strdup(try_val_to_str(eo_info->fid_type, smb2_fid_types)); - - /* What kind of data this packet contains? */ - switch(eo_info->cmd) { - case SMB2_COM_READ: - contains = SMB_EO_CONTAINS_READS; - break; - case SMB2_COM_WRITE: - contains = SMB_EO_CONTAINS_WRITES; - break; - default: - contains = SMB_EO_CONTAINS_NOTHING; - break; - } - } - - - /* Is this data from an already tracked file or not? */ - incoming_file.tid = eo_info->tid; - incoming_file.uid = eo_info->uid; - incoming_file.fid = eo_info->fid; - active_row = find_incoming_file(GSL_active_files, &incoming_file); - - if (active_row == -1) { /* This is a new-tracked file */ - /* Construct the entry in the list of active files */ - entry = (export_object_entry_t *)g_malloc(sizeof(export_object_entry_t)); - entry->payload_data = NULL; - entry->payload_len = 0; - new_file = (active_file *)g_malloc(sizeof(active_file)); - new_file->tid = incoming_file.tid; - new_file->uid = incoming_file.uid; - new_file->fid = incoming_file.fid; - new_file->file_length = eo_info->end_of_file; - new_file->flag_contains = contains; - new_file->free_chunk_list = NULL; - new_file->data_gathered = 0; - new_file->is_out_of_memory = FALSE; - entry->pkt_num = pinfo->num; - - entry->hostname=g_filename_display_name(g_strcanon(eo_info->hostname,LEGAL_FILENAME_CHARS,'?')); - entry->filename=g_filename_display_name(g_strcanon(eo_info->filename,LEGAL_FILENAME_CHARS,'?')); - - /* Insert the first chunk in the chunk list of this file */ - if (is_supported_filetype) { - insert_chunk(new_file, entry, eo_info); - } - - if (new_file->is_out_of_memory) { - entry->content_type = - g_strdup_printf("%s (%"G_GUINT64_FORMAT"?/%"G_GUINT64_FORMAT") %s [mem!!]", - aux_smb_fid_type_string, - new_file->data_gathered, - new_file->file_length, - try_val_to_str(contains, smb_eo_contains_string)); - } else { - if (new_file->file_length > 0) { - percent = (gfloat) (100*new_file->data_gathered/new_file->file_length); - } else { - percent = 0.0f; - } - - entry->content_type = - g_strdup_printf("%s (%"G_GUINT64_FORMAT"/%"G_GUINT64_FORMAT") %s [%5.2f%%]", - aux_smb_fid_type_string, - new_file->data_gathered, - new_file->file_length, - try_val_to_str(contains, smb_eo_contains_string), - percent); - } - - object_list_add_entry(object_list, entry); - GSL_active_files = g_slist_append(GSL_active_files, new_file); - } - else if (is_supported_filetype) { - current_file = (active_file *)g_slist_nth_data(GSL_active_files, active_row); - /* Recalculate the current file flags */ - current_file->flag_contains = current_file->flag_contains|contains; - current_entry = object_list_get_entry(object_list, active_row); - - insert_chunk(current_file, current_entry, eo_info); - - /* Modify the current_entry object_type string */ - if (current_file->is_out_of_memory) { - current_entry->content_type = - g_strdup_printf("%s (%"G_GUINT64_FORMAT"?/%"G_GUINT64_FORMAT") %s [mem!!]", - aux_smb_fid_type_string, - current_file->data_gathered, - current_file->file_length, - try_val_to_str(current_file->flag_contains, smb_eo_contains_string)); - } else { - percent = (gfloat) (100*current_file->data_gathered/current_file->file_length); - current_entry->content_type = - g_strdup_printf("%s (%"G_GUINT64_FORMAT"/%"G_GUINT64_FORMAT") %s [%5.2f%%]", - aux_smb_fid_type_string, - current_file->data_gathered, - current_file->file_length, - try_val_to_str(current_file->flag_contains, smb_eo_contains_string), - percent); - } - } - - return TRUE; /* State changed - window should be redrawn */ -} - - -/* This is the eo_protocoldata_reset function that is used in the export_object module - to cleanup any previous private data of the export object functionality before perform - the eo_reset function or when the window closes */ -void -eo_smb_cleanup(void) -{ - int i, last; - active_file *in_list_file; - - /* Free any previous data structures used in previous invocation to the - export_object_smb function */ - last = g_slist_length(GSL_active_files); - if (GSL_active_files) { - for (i=last-1; i>=0; i--) { - in_list_file = (active_file *)g_slist_nth_data(GSL_active_files, i); - if (in_list_file->free_chunk_list) { - g_slist_free(in_list_file->free_chunk_list); - in_list_file->free_chunk_list = NULL; - } - g_free(in_list_file); - } - g_slist_free(GSL_active_files); - GSL_active_files = NULL; - } -} - -/* - * Editor modelines - * - * Local Variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * ex: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ diff --git a/ui/export_object_tftp.c b/ui/export_object_tftp.c deleted file mode 100644 index 11547aca38..0000000000 --- a/ui/export_object_tftp.c +++ /dev/null @@ -1,138 +0,0 @@ -/* export_object_tftp.c - * Routines for aving objects (files) found in TFTP sessions - * See also: export_object.c / export_object.h for common code - * Initial file, prototypes and general structure initially copied - * from export_object_smb.c - * - * Martin Mathieson - * - * 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 <epan/packet.h> -#include <epan/dissectors/packet-tftp.h> -#include <epan/tap.h> - -#include "export_object.h" - -/* A list of block list entries to delete from cleanup callback when window is closed. */ -typedef struct eo_info_dynamic_t { - gchar *filename; - GSList *block_list; -} eo_info_dynamic_t; -static GSList *s_dynamic_info_list = NULL; - -/* Tap function */ -gboolean -eo_tftp_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, - const void *data) -{ - export_object_list_t *object_list = (export_object_list_t *)tapdata; - const tftp_eo_t *eo_info = (const tftp_eo_t *)data; - export_object_entry_t *entry; - - GSList *block_iterator; - guint payload_data_offset = 0; - eo_info_dynamic_t *dynamic_info; - - /* These values will be freed when the Export Object window is closed. */ - entry = (export_object_entry_t*)g_malloc(sizeof(export_object_entry_t)); - - /* Remember which frame had the last block of the file */ - entry->pkt_num = pinfo->num; - - /* Copy filename */ - entry->filename = g_strdup(g_path_get_basename(eo_info->filename)); - - /* Iterate over list of blocks and concatenate into contiguous memory */ - entry->payload_len = eo_info->payload_len; - entry->payload_data = (guint8 *)g_try_malloc((gsize)entry->payload_len); - for (block_iterator = eo_info->block_list; block_iterator; block_iterator = block_iterator->next) { - file_block_t *block = (file_block_t*)block_iterator->data; - memcpy(entry->payload_data + payload_data_offset, - block->data, - block->length); - payload_data_offset += block->length; - } - - /* These 2 fields not used */ - entry->hostname = NULL; - entry->content_type = NULL; - - /* Add to list of entries to be cleaned up. eo_info is only packet scope, so - need to make list only of block list now */ - dynamic_info = (eo_info_dynamic_t*)g_malloc(sizeof(eo_info_dynamic_t)); - dynamic_info->filename = eo_info->filename; - dynamic_info->block_list = eo_info->block_list; - s_dynamic_info_list = g_slist_append(s_dynamic_info_list, (eo_info_dynamic_t*)dynamic_info); - - /* Pass out entry to the GUI */ - object_list_add_entry(object_list, entry); - - return TRUE; /* State changed - window should be redrawn */ -} - -/* Clean up the stored parts of a single tapped entry */ -static void cleanup_tftp_eo(eo_info_dynamic_t *dynamic_info) -{ - GSList *block_iterator; - /* Free the filename */ - g_free(dynamic_info->filename); - - /* Walk list of block items */ - for (block_iterator = dynamic_info->block_list; block_iterator; block_iterator = block_iterator->next) { - file_block_t *block = (file_block_t*)(block_iterator->data); - /* Free block data */ - wmem_free(NULL, block->data); - - /* Free block itself */ - g_free(block); - } -} - -/* Callback for freeing up data supplied with taps. The taps themselves only have - packet scope, so only store/free dynamic memory pointers */ -void eo_tftp_cleanup(void) -{ - /* Cleanup each entry in the global list */ - GSList *dynamic_iterator; - for (dynamic_iterator = s_dynamic_info_list; dynamic_iterator; dynamic_iterator = dynamic_iterator->next) { - eo_info_dynamic_t *dynamic_info = (eo_info_dynamic_t*)dynamic_iterator->data; - cleanup_tftp_eo(dynamic_info); - } - /* List is empty again */ - s_dynamic_info_list = NULL; -} - -/* - * Editor modelines - * - * Local Variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * ex: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ diff --git a/ui/export_object.c b/ui/export_object_ui.c index 67e883f056..2db2fe5516 100644 --- a/ui/export_object.c +++ b/ui/export_object_ui.c @@ -1,4 +1,4 @@ -/* export_object.c +/* export_object_ui.c * Common routines for tracking & saving objects found in streams of data * Copyright 2007, Stephen Fisher (see AUTHORS file) * @@ -39,7 +39,7 @@ #include <ui/alert_box.h> -#include "export_object.h" +#include "export_object_ui.h" gboolean eo_save_entry(const gchar *save_as_filename, export_object_entry_t *entry, gboolean show_err) @@ -102,89 +102,6 @@ eo_save_entry(const gchar *save_as_filename, export_object_entry_t *entry, gbool return TRUE; } - -#define HINIBBLE(x) (((x) >> 4) & 0xf) -#define LONIBBLE(x) ((x) & 0xf) -#define HEXTOASCII(x) (((x) < 10) ? ((x) + '0') : ((x) - 10 + 'a')) -#define MAXFILELEN 255 - -static GString *eo_rename(GString *gstr, int dupn) -{ - GString *gstr_tmp; - gchar *tmp_ptr; - GString *ext_str; - - gstr_tmp = g_string_new("("); - g_string_append_printf (gstr_tmp, "%d)", dupn); - if ( (tmp_ptr = strrchr(gstr->str, '.')) != NULL ) { - /* Retain the extension */ - ext_str = g_string_new(tmp_ptr); - gstr = g_string_truncate(gstr, gstr->len - ext_str->len); - if ( gstr->len >= (MAXFILELEN - (strlen(gstr_tmp->str) + ext_str->len)) ) - gstr = g_string_truncate(gstr, MAXFILELEN - (strlen(gstr_tmp->str) + ext_str->len)); - gstr = g_string_append(gstr, gstr_tmp->str); - gstr = g_string_append(gstr, ext_str->str); - g_string_free(ext_str, TRUE); - } - else { - if ( gstr->len >= (MAXFILELEN - strlen(gstr_tmp->str)) ) - gstr = g_string_truncate(gstr, MAXFILELEN - strlen(gstr_tmp->str)); - gstr = g_string_append(gstr, gstr_tmp->str); - } - g_string_free(gstr_tmp, TRUE); - return gstr; -} - -GString * -eo_massage_str(const gchar *in_str, gsize maxlen, int dupn) -{ - gchar *tmp_ptr; - /* The characters in "reject" come from: - * http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx. - * Add to the list as necessary for other OS's. - */ - const gchar *reject = "<>:\"/\\|?*" - "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a" - "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" - "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"; - GString *out_str; - GString *ext_str; - - out_str = g_string_new(""); - - /* Find all disallowed characters/bytes and replace them with %xx */ - while ( (tmp_ptr = strpbrk(in_str, reject)) != NULL ) { - out_str = g_string_append_len(out_str, in_str, tmp_ptr - in_str); - out_str = g_string_append_c(out_str, '%'); - out_str = g_string_append_c(out_str, HEXTOASCII(HINIBBLE(*tmp_ptr))); - out_str = g_string_append_c(out_str, HEXTOASCII(LONIBBLE(*tmp_ptr))); - in_str = tmp_ptr + 1; - } - out_str = g_string_append(out_str, in_str); - if ( out_str->len > maxlen ) { - if ( (tmp_ptr = strrchr(out_str->str, '.')) != NULL ) { - /* Retain the extension */ - ext_str = g_string_new(tmp_ptr); - out_str = g_string_truncate(out_str, maxlen - ext_str->len); - out_str = g_string_append(out_str, ext_str->str); - g_string_free(ext_str, TRUE); - } - else - out_str = g_string_truncate(out_str, maxlen); - } - if ( dupn != 0 ) - out_str = eo_rename(out_str, dupn); - return out_str; -} - -const char * -ct2ext(const char *content_type) -{ - /* TODO: Map the content type string to an extension string. If no match, - * return NULL. */ - return content_type; -} - /* * Editor modelines * diff --git a/ui/export_object_ui.h b/ui/export_object_ui.h new file mode 100644 index 0000000000..a1cbf81b58 --- /dev/null +++ b/ui/export_object_ui.h @@ -0,0 +1,55 @@ +/* export_object_ui.h + * Common routines for tracking & saving objects found in streams of data + * Copyright 2007, Stephen Fisher (see AUTHORS file) + * + * 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_OBJECT_UI_H__ +#define __EXPORT_OBJECT_UI_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include <epan/export_object.h> + +/* Common between protocols */ + +gboolean eo_save_entry(const gchar *save_as_filename, export_object_entry_t *entry, gboolean show_err); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EXPORT_OBJECT_UI_H__ */ + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/gtk/export_object_dlg.c b/ui/gtk/export_object_dlg.c index ee1c3af8b3..ba7ce9c136 100644 --- a/ui/gtk/export_object_dlg.c +++ b/ui/gtk/export_object_dlg.c @@ -32,7 +32,7 @@ #include <wsutil/str_util.h> -#include <ui/export_object.h> +#include <ui/export_object_ui.h> #include <ui/simple_dialog.h> #include "dlg_utils.h" @@ -43,13 +43,6 @@ #include "stock_icons.h" #include "export_object_dlg.h" -/* When a protocol needs intermediate data structures to construct the -export objects, then it must specifiy a function that cleans up all -those data structures. This function is passed to export_object_window -and called when tap reset or windows closes occurs. If no function is needed -a NULL value should be passed instead */ -typedef void (*eo_protocoldata_reset_cb)(void); - enum { EO_PKT_NUM_COLUMN, EO_HOSTNAME_COLUMN, @@ -59,22 +52,23 @@ enum { EO_NUM_COLUMNS /* must be last */ }; -struct _export_object_list_t { +typedef struct _export_object_list_gui_t { GSList *entries; GtkWidget *tree, *dlg; GtkTreeView *tree_view; GtkTreeIter *iter; GtkTreeStore *store; gint row_selected; -}; +} export_object_list_gui_t; -static eo_protocoldata_reset_cb eo_protocoldata_reset = NULL; +static export_object_gui_reset_cb eo_protocoldata_reset = NULL; static void eo_remember_this_row(GtkTreeModel *model _U_, GtkTreePath *path, GtkTreeIter *iter _U_, gpointer arg) { - export_object_list_t *object_list = (export_object_list_t *)arg; + export_object_list_t *tap_object = (export_object_list_t *)arg; + export_object_list_gui_t *object_list = (export_object_list_gui_t*)tap_object->gui_data; export_object_entry_t *entry; gint *path_index; @@ -102,23 +96,19 @@ eo_remember_row_num(GtkTreeSelection *sel, gpointer data) static void eo_win_destroy_cb(GtkWindow *win _U_, gpointer data) { - export_object_list_t *object_list = (export_object_list_t *)data; + export_object_list_t *tap_object = (export_object_list_t *)data; + export_object_list_gui_t *object_list = (export_object_list_gui_t*)tap_object->gui_data; export_object_entry_t *entry; GSList *slist = object_list->entries; - remove_tap_listener(object_list); + remove_tap_listener(tap_object); /* Free the GSList attributes */ while(slist) { entry = (export_object_entry_t *)slist->data; - - g_free(entry->hostname); - g_free(entry->content_type); - g_free(entry->filename); - wmem_free(wmem_file_scope(), entry->payload_data); + eo_free_entry(entry); slist = slist->next; - wmem_free(wmem_file_scope(), entry); } /* Free the GSList elements */ @@ -130,7 +120,7 @@ eo_win_destroy_cb(GtkWindow *win _U_, gpointer data) } static char * -gtk_eo_save_object_as_file(export_object_list_t *object_list, char *auxfilename) +gtk_eo_save_object_as_file(export_object_list_gui_t *object_list, char *auxfilename) { GtkWidget *save_as_w; char *pathname; @@ -156,7 +146,8 @@ gtk_eo_save_object_as_file(export_object_list_t *object_list, char *auxfilename) static void eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg) { - export_object_list_t *object_list = (export_object_list_t *)arg; + export_object_list_t *tap_object = (export_object_list_t *)arg; + export_object_list_gui_t *object_list = (export_object_list_gui_t*)tap_object->gui_data; export_object_entry_t *entry; GString *safe_filename = NULL; char *pathname; @@ -193,12 +184,12 @@ eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg) g_string_free(safe_filename, TRUE); } -#define MAXFILELEN 255 static void eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg) { gchar *save_as_fullpath = NULL; - export_object_list_t *object_list = (export_object_list_t *)arg; + export_object_list_t *tap_object = (export_object_list_t *)arg; + export_object_list_gui_t *object_list = (export_object_list_gui_t*)tap_object->gui_data; export_object_entry_t *entry; GtkWidget *save_in_w; GSList *slist = object_list->entries; @@ -216,21 +207,21 @@ eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg) entry = (export_object_entry_t *)slist->data; save_in_path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_in_w)); - if ((strlen(save_in_path) < MAXFILELEN)) { + if ((strlen(save_in_path) < EXPORT_OBJECT_MAXFILELEN)) { do { g_free(save_as_fullpath); if (entry->filename) { safe_filename = eo_massage_str(entry->filename, - MAXFILELEN - strlen(save_in_path), count); + EXPORT_OBJECT_MAXFILELEN - strlen(save_in_path), count); } else { - char generic_name[MAXFILELEN+1]; + char generic_name[EXPORT_OBJECT_MAXFILELEN+1]; const char *ext; - ext = ct2ext(entry->content_type); + ext = eo_ct2ext(entry->content_type); g_snprintf(generic_name, sizeof(generic_name), "object%u%s%s", entry->pkt_num, ext ? "." : "", ext ? ext : ""); safe_filename = eo_massage_str(generic_name, - MAXFILELEN - strlen(save_in_path), count); + EXPORT_OBJECT_MAXFILELEN - strlen(save_in_path), count); } save_as_fullpath = g_build_filename( save_in_path, safe_filename->str, NULL); @@ -260,7 +251,8 @@ eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg) static void eo_reset(void *tapdata) { - export_object_list_t *object_list = (export_object_list_t *)tapdata; + export_object_list_t *tap_object = (export_object_list_t *)tapdata; + export_object_list_gui_t *object_list = (export_object_list_gui_t*)tap_object->gui_data; object_list->entries = NULL; object_list->iter = NULL; @@ -272,7 +264,8 @@ eo_reset(void *tapdata) static void eo_draw(void *tapdata) { - export_object_list_t *object_list = (export_object_list_t *)tapdata; + export_object_list_t *tap_object = (export_object_list_t *)tapdata; + export_object_list_gui_t *object_list = (export_object_list_gui_t*)tap_object->gui_data; export_object_entry_t *eo_entry; gchar *size_str; @@ -305,17 +298,23 @@ eo_draw(void *tapdata) } } -void object_list_add_entry(export_object_list_t *object_list, export_object_entry_t *entry) +static void +object_list_add_entry(void *gui_data, export_object_entry_t *entry) { + export_object_list_gui_t *object_list = (export_object_list_gui_t*)gui_data; + object_list->entries = g_slist_append(object_list->entries, entry); } -export_object_entry_t *object_list_get_entry(export_object_list_t *object_list, int row) { +static export_object_entry_t* +object_list_get_entry(void *gui_data, int row) { + export_object_list_gui_t *object_list = (export_object_list_gui_t*)gui_data; + return (export_object_entry_t *)g_slist_nth_data(object_list->entries, row); } static void -export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_packet, eo_protocoldata_reset_cb eo_protocoldata_resetfn) +export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_packet, export_object_gui_reset_cb eo_protocoldata_resetfn) { GtkWidget *sw; GtkCellRenderer *renderer; @@ -323,17 +322,23 @@ export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_ GtkTreeSelection *selection; GtkWidget *vbox, *bbox, *help_bt, *cancel_bt, *save_bt, *save_all_bt; GString *error_msg; - export_object_list_t *object_list; + export_object_list_t *tap_data; + export_object_list_gui_t *object_list; gchar *window_title; /* Initialize the pointer to the private data clearing function */ eo_protocoldata_reset = eo_protocoldata_resetfn; /* Initialize our object list structure */ - object_list = g_new0(export_object_list_t,1); + tap_data = g_new0(export_object_list_t,1); + object_list = g_new0(export_object_list_gui_t,1); + + tap_data->add_entry = object_list_add_entry; + tap_data->get_entry = object_list_get_entry; + tap_data->gui_data = (void*)object_list; /* Data will be gathered via a tap callback */ - error_msg = register_tap_listener(tapname, object_list, NULL, 0, + error_msg = register_tap_listener(tapname, tap_data, NULL, 0, eo_reset, tap_packet, eo_draw); @@ -342,6 +347,7 @@ export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Can't register %s tap: %s\n", name, error_msg->str); g_string_free(error_msg, TRUE); + g_free(tap_data); g_free(object_list); return; } @@ -425,7 +431,7 @@ export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_ gtk_container_add(GTK_CONTAINER(sw), object_list->tree); selection = gtk_tree_view_get_selection(object_list->tree_view); - g_signal_connect(selection, "changed", G_CALLBACK(eo_remember_row_num), object_list); + g_signal_connect(selection, "changed", G_CALLBACK(eo_remember_row_num), tap_data); bbox = dlg_button_row_new(GTK_STOCK_HELP, WIRESHARK_STOCK_SAVE_ALL, GTK_STOCK_SAVE_AS, GTK_STOCK_CANCEL, NULL); @@ -436,13 +442,12 @@ export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_ /* Save All button */ save_all_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_SAVE_ALL); - g_signal_connect(save_all_bt, "clicked", G_CALLBACK(eo_save_all_clicked_cb), - object_list); + g_signal_connect(save_all_bt, "clicked", G_CALLBACK(eo_save_all_clicked_cb), tap_data); gtk_widget_set_tooltip_text(save_all_bt, "Save all listed objects with their displayed filenames."); /* Save As button */ save_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_SAVE_AS); - g_signal_connect(save_bt, "clicked", G_CALLBACK(eo_save_clicked_cb), object_list); + g_signal_connect(save_bt, "clicked", G_CALLBACK(eo_save_clicked_cb), tap_data); gtk_widget_set_tooltip_text(save_bt, "Saves the currently selected content to a file."); /* Cancel button */ @@ -455,8 +460,7 @@ export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_ /* Setup cancel/delete/destroy signal handlers */ g_signal_connect(object_list->dlg, "delete_event", G_CALLBACK(window_delete_event_cb), NULL); - g_signal_connect(object_list->dlg, "destroy", - G_CALLBACK(eo_win_destroy_cb), object_list); + g_signal_connect(object_list->dlg, "destroy", G_CALLBACK(eo_win_destroy_cb), tap_data); window_set_cancel_button(object_list->dlg, cancel_bt, window_cancel_button_cb); @@ -467,30 +471,9 @@ export_object_window(const gchar *tapname, const gchar *name, tap_packet_cb tap_ cf_retap_packets(&cfile); } -void -eo_dicom_cb(GtkWidget *widget _U_, gpointer data _U_) -{ - export_object_window("dicom_eo", "DICOM", eo_dicom_packet, NULL); -} - -void -eo_http_cb(GtkWidget *widget _U_, gpointer data _U_) -{ - export_object_window("http_eo", "HTTP", eo_http_packet, NULL); -} - -void -eo_smb_cb(GtkWidget *widget _U_, gpointer data _U_) -{ - /* Call the export_object window */ - export_object_window("smb_eo", "SMB", eo_smb_packet, eo_smb_cleanup); -} - -void -eo_tftp_cb(GtkWidget *widget _U_, gpointer data _U_) +void exportobject_cb(register_eo_t *eo) { - /* Call the export_object window */ - export_object_window("tftp_eo", "TFTP", eo_tftp_packet, eo_tftp_cleanup); + export_object_window(get_eo_tap_listener_name(eo), proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo))), get_eo_packet_func(eo), get_eo_reset_func(eo)); } /* diff --git a/ui/gtk/export_object_dlg.h b/ui/gtk/export_object_dlg.h index 73fae69a34..72121df593 100644 --- a/ui/gtk/export_object_dlg.h +++ b/ui/gtk/export_object_dlg.h @@ -25,10 +25,8 @@ #ifndef __EXPORT_OBJECT_DLG_H__ #define __EXPORT_OBJECT_DLG_H__ -/* Protocol specific */ -void eo_dicom_cb(GtkWidget *widget _U_, gpointer data _U_); -void eo_http_cb(GtkWidget *widget _U_, gpointer data _U_); -void eo_smb_cb(GtkWidget *widget _U_, gpointer data _U_); -void eo_tftp_cb(GtkWidget *widget _U_, gpointer data _U_); +#include <epan/export_object.h> + +void exportobject_cb(register_eo_t *eo); #endif /* __EXPORT_OBJECT_DLG_H__ */ diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c index 0b8aeacc60..907f65285d 100644 --- a/ui/gtk/main_menubar.c +++ b/ui/gtk/main_menubar.c @@ -34,6 +34,7 @@ #include <epan/column.h> #include <epan/stats_tree_priv.h> #include <epan/plugin_if.h> +#include <epan/export_object.h> #include "globals.h" #include <epan/color_filters.h> @@ -821,11 +822,8 @@ static const char *ui_desc_menubar = " <menuitem name='ExportSelectedPacketBytes' action='/File/ExportSelectedPacketBytes'/>\n" " <menuitem name='ExportPDUs' action='/File/ExportPDUs'/>\n" " <menuitem name='ExportSSLSessionKeys' action='/File/ExportSSLSessionKeys'/>\n" -" <menu name= 'ExportObjects' action='/File/ExportObjects'>\n" -" <menuitem name='HTTP' action='/File/ExportObjects/HTTP'/>\n" -" <menuitem name='DICOM' action='/File/ExportObjects/DICOM'/>\n" -" <menuitem name='SMB' action='/File/ExportObjects/SMB'/>\n" -" <menuitem name='TFTP' action='/File/ExportObjects/TFTP'/>\n" +" <menu name= 'ExportObjectsMenu' action='/File/ExportObjects'>\n" +" <placeholder name='ExportObjects'/>\n" " </menu>\n" " <separator/>\n" " <menuitem name='Print' action='/File/Print'/>\n" @@ -1280,10 +1278,6 @@ static const GtkActionEntry main_menu_bar_entries[] = { NULL, NULL, G_CALLBACK(export_pdml_cmd_cb) }, { "/File/ExportPacketDissections/JSON", NULL, "as \"_JSON\" file...", NULL, NULL, G_CALLBACK(export_json_cmd_cb) }, - { "/File/ExportObjects/HTTP", NULL, "_HTTP", NULL, NULL, G_CALLBACK(eo_http_cb) }, - { "/File/ExportObjects/DICOM", NULL, "_DICOM", NULL, NULL, G_CALLBACK(eo_dicom_cb) }, - { "/File/ExportObjects/SMB", NULL, "_SMB/SMB2", NULL, NULL, G_CALLBACK(eo_smb_cb) }, - { "/File/ExportObjects/TFTP", NULL, "_TFTP", NULL, NULL, G_CALLBACK(eo_tftp_cb) }, { "/Edit/Copy", NULL, "Copy", NULL, NULL, NULL }, @@ -2810,6 +2804,73 @@ menu_hostlist_list(capture_file *cf) conversation_table_iterate_tables(add_hostlist_menuitem, &conv_data); } +typedef struct { + guint merge_id; + GtkActionGroup *action_group; + int counter; +} eo_menu_t; + +static void +menu_exportobject_cb(GtkAction *action _U_, gpointer user_data) +{ + register_eo_t *eo = (register_eo_t*)user_data; + + exportobject_cb(eo); +} + +static void +add_export_object_menuitem(gpointer data, gpointer user_data) +{ + register_eo_t *eo = (register_eo_t*)data; + eo_menu_t *eo_menu_data = (eo_menu_t*)user_data; + gchar *action_name; + GtkAction *action; + + action_name = g_strdup_printf ("exportobject-%u", eo_menu_data->counter); + /*g_warning("action_name %s, filter_entry->name %s",action_name,filter_entry->name);*/ + action = (GtkAction *)g_object_new (GTK_TYPE_ACTION, + "name", action_name, + "label", proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo))), + "sensitive", TRUE, + NULL); + g_signal_connect (action, "activate", + G_CALLBACK (menu_exportobject_cb), eo); + gtk_action_group_add_action (eo_menu_data->action_group, action); + g_object_unref (action); + + gtk_ui_manager_add_ui (ui_manager_main_menubar, eo_menu_data->merge_id, + "/Menubar/FileMenu/ExportObjectsMenu/ExportObjects", + action_name, + action_name, + GTK_UI_MANAGER_MENUITEM, + FALSE); + g_free(action_name); + eo_menu_data->counter++; +} + +static void +menu_export_object_list(void) +{ + GtkWidget *submenu_export_object; + eo_menu_t eo_data; + + eo_data.merge_id = gtk_ui_manager_new_merge_id (ui_manager_main_menubar); + + eo_data.action_group = gtk_action_group_new ("exportobject-list-group"); + + submenu_export_object = gtk_ui_manager_get_widget(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjects"); + if(!submenu_export_object){ + g_warning("menu_export_object_list: No submenu_exportobject_list found, path= /Menubar/FileMenu/ExportObjects"); + } + + gtk_ui_manager_insert_action_group (ui_manager_main_menubar, eo_data.action_group, 0); + g_object_set_data (G_OBJECT (ui_manager_main_menubar), + "exportobject-list-merge-id", GUINT_TO_POINTER (eo_data.merge_id)); + + eo_data.counter = 0; + eo_iterate_tables(add_export_object_menuitem, &eo_data); +} + static void menu_conversation_display_filter_cb(GtkAction *action _U_, gpointer data) { @@ -3253,6 +3314,7 @@ menus_init(void) menu_dissector_filter(&cfile); menu_conversation_list(&cfile); menu_hostlist_list(&cfile); + menu_export_object_list(); /* Add additional entries which may have been introduced by dissectors and/or plugins */ ws_menubar_external_menus(); @@ -4396,7 +4458,7 @@ set_menus_for_capture_file(capture_file *cf) set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportPacketDissections", FALSE); set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportSelectedPacketBytes", FALSE); set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportSSLSessionKeys", FALSE); - set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjects", FALSE); + set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjectsMenu", FALSE); set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportPDUs", FALSE); set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/Reload", FALSE); } else { @@ -4415,7 +4477,7 @@ set_menus_for_capture_file(capture_file *cf) set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportPacketDissections", TRUE); set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportSelectedPacketBytes", TRUE); set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportSSLSessionKeys", TRUE); - set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjects", TRUE); + set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjectsMenu", TRUE); set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportPDUs", TRUE); set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/Reload", TRUE); } @@ -4441,7 +4503,7 @@ set_menus_for_capture_in_progress(gboolean capture_in_progress) capture_in_progress); set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportSSLSessionKeys", capture_in_progress); - set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjects", + set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/ExportObjectsMenu", capture_in_progress); set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/FileMenu/Set", !capture_in_progress); diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt index 3cd9d2e503..9899ad7477 100644 --- a/ui/qt/CMakeLists.txt +++ b/ui/qt/CMakeLists.txt @@ -60,6 +60,7 @@ set(WIRESHARK_QT_HEADERS endpoint_dialog.h expert_info_dialog.h export_dissection_dialog.h + export_object_action.h export_object_dialog.h export_pdu_dialog.h field_filter_edit.h @@ -227,6 +228,7 @@ set(WIRESHARK_QT_SRC enabled_protocols_dialog.cpp endpoint_dialog.cpp export_dissection_dialog.cpp + export_object_action.cpp export_object_dialog.cpp export_pdu_dialog.cpp field_filter_edit.cpp diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am index f543f42c0a..bb83a45a6a 100644 --- a/ui/qt/Makefile.am +++ b/ui/qt/Makefile.am @@ -190,6 +190,7 @@ MOC_HDRS = \ endpoint_dialog.h \ expert_info_dialog.h \ export_dissection_dialog.h \ + export_object_action.h \ export_object_dialog.h \ export_pdu_dialog.h \ field_filter_edit.h \ @@ -471,6 +472,7 @@ WIRESHARK_QT_SRC = \ enabled_protocols_dialog.cpp \ endpoint_dialog.cpp \ export_dissection_dialog.cpp \ + export_object_action.cpp \ export_object_dialog.cpp \ export_pdu_dialog.cpp \ field_filter_edit.cpp \ diff --git a/ui/qt/export_object_action.cpp b/ui/qt/export_object_action.cpp new file mode 100644 index 0000000000..7b9363ba72 --- /dev/null +++ b/ui/qt/export_object_action.cpp @@ -0,0 +1,65 @@ +/* conversation_colorize_action.cpp + * + * 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 <glib.h> +#include <epan/packet_info.h> +#include <epan/proto_data.h> +#include <epan/packet.h> +#include <wsutil/utf8_entities.h> +#include "export_object_action.h" + +#include <QMenu> + +#include "qt_ui_utils.h" + +ExportObjectAction::ExportObjectAction(QObject *parent, register_eo_t *eo) : + QAction(parent), + eo_(eo) +{ + if (eo_) { + setText( QString("%1%2").arg(proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo)))).arg(UTF8_HORIZONTAL_ELLIPSIS)); + } +} + +void ExportObjectAction::captureFileOpened() +{ + setEnabled(true); +} + +void ExportObjectAction::captureFileClosed() +{ + setEnabled(false); +} + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/export_object_action.h b/ui/qt/export_object_action.h new file mode 100644 index 0000000000..5328f24b31 --- /dev/null +++ b/ui/qt/export_object_action.h @@ -0,0 +1,64 @@ +/* export_object_action.h + * + * 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 EXPORTOBJECTACTION_H +#define EXPORTOBJECTACTION_H + +#include "config.h" + +#include <glib.h> +#include <epan/packet_info.h> +#include <epan/export_object.h> + +#include <QAction> + +// Actions for "Export Objects" menu items. + +class ExportObjectAction : public QAction +{ + Q_OBJECT +public: + ExportObjectAction(QObject *parent, register_eo_t *eo = NULL); + + register_eo_t* exportObject() {return eo_;} + +public slots: + void captureFileOpened(); + void captureFileClosed(); + +private: + register_eo_t *eo_; +}; + +#endif // EXPORTOBJECTACTION_H + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/export_object_dialog.cpp b/ui/qt/export_object_dialog.cpp index 29126334ca..8592332feb 100644 --- a/ui/qt/export_object_dialog.cpp +++ b/ui/qt/export_object_dialog.cpp @@ -28,6 +28,7 @@ #include <wsutil/filesystem.h> #include <wsutil/str_util.h> +#include "qt_ui_utils.h" #include "wireshark_application.h" #include <QDialogButtonBox> @@ -37,14 +38,21 @@ extern "C" { -// object_list_add_entry and object_list_get_entry are defined in ui/export_object.h +static void +object_list_add_entry(void *gui_data, export_object_entry_t *entry) { + export_object_list_gui_t *object_list = (export_object_list_gui_t*)gui_data; -void object_list_add_entry(export_object_list_t *object_list, export_object_entry_t *entry) { - if (object_list && object_list->eod) object_list->eod->addObjectEntry(entry); + if (object_list && object_list->eod) + object_list->eod->addObjectEntry(entry); } -export_object_entry_t *object_list_get_entry(export_object_list_t *object_list, int row) { - if (object_list && object_list->eod) return object_list->eod->objectEntry(row); +static export_object_entry_t* +object_list_get_entry(void *gui_data, int row) { + export_object_list_gui_t *object_list = (export_object_list_gui_t*)gui_data; + + if (object_list && object_list->eod) + return object_list->eod->objectEntry(row); + return NULL; } @@ -54,21 +62,94 @@ export_object_entry_t *object_list_get_entry(export_object_list_t *object_list, static void eo_reset(void *tapdata) { - export_object_list_t *object_list = (export_object_list_t *) tapdata; + export_object_list_t *tap_object = (export_object_list_t *)tapdata; + export_object_list_gui_t *object_list = (export_object_list_gui_t *)tap_object->gui_data; if (object_list && object_list->eod) object_list->eod->resetObjects(); } } // extern "C" -ExportObjectDialog::ExportObjectDialog(QWidget &parent, CaptureFile &cf, ObjectType object_type) : + +enum { + COL_PACKET, + COL_HOSTNAME, + COL_CONTENT_TYPE, + COL_SIZE, + COL_FILENAME +}; + +enum { + export_object_row_type_ = 1000 +}; + +class ExportObjectTreeWidgetItem : public QTreeWidgetItem +{ +public: + ExportObjectTreeWidgetItem(QTreeWidget *parent, export_object_entry_t *entry) : + QTreeWidgetItem (parent, export_object_row_type_), + entry_(entry) + { + // Not perfect but better than nothing. + setTextAlignment(COL_SIZE, Qt::AlignRight); + } + ~ExportObjectTreeWidgetItem() { + eo_free_entry(entry_); + } + + export_object_entry_t *entry() { return entry_; } + + virtual QVariant data(int column, int role) const { + if (!entry_ || role != Qt::DisplayRole) { + return QTreeWidgetItem::data(column, role); + } + + switch (column) { + case COL_PACKET: + return QString::number(entry_->pkt_num); + case COL_HOSTNAME: + return entry_->hostname; + case COL_CONTENT_TYPE: + return entry_->content_type; + case COL_SIZE: + return file_size_to_qstring(entry_->payload_len); + case COL_FILENAME: + return entry_->filename; + default: + break; + } + return QTreeWidgetItem::data(column, role); + } + + bool operator< (const QTreeWidgetItem &other) const + { + if (!entry_ || other.type() != export_object_row_type_) { + return QTreeWidgetItem::operator< (other); + } + + const ExportObjectTreeWidgetItem *other_row = static_cast<const ExportObjectTreeWidgetItem *>(&other); + + switch (treeWidget()->sortColumn()) { + case COL_PACKET: + return entry_->pkt_num < other_row->entry_->pkt_num; + case COL_SIZE: + return entry_->payload_len < other_row->entry_->payload_len; + default: + break; + } + + return QTreeWidgetItem::operator< (other); + } + +private: + export_object_entry_t *entry_; +}; + +ExportObjectDialog::ExportObjectDialog(QWidget &parent, CaptureFile &cf, register_eo_t* eo) : WiresharkDialog(parent, cf), eo_ui_(new Ui::ExportObjectDialog), save_bt_(NULL), save_all_bt_(NULL), - tap_name_(NULL), - name_(NULL), - tap_packet_(NULL), - eo_protocoldata_resetfn_(NULL) + eo_(eo) { QPushButton *close_bt; @@ -80,42 +161,17 @@ ExportObjectDialog::ExportObjectDialog(QWidget &parent, CaptureFile &cf, ObjectT eo_ui_->progressBar->setAttribute(Qt::WA_MacSmallSize, true); #endif - export_object_list_.eod = this; + eo_gui_data_.eod = this; - switch (object_type) { - case Dicom: - tap_name_ = "dicom_eo"; - name_ = "DICOM"; - tap_packet_ = eo_dicom_packet; - break; - case Http: - tap_name_ = "http_eo"; - name_ = "HTTP"; - tap_packet_ = eo_http_packet; - break; - case Imf: - tap_name_ = "imf_eo"; - name_ = "IMF"; - tap_packet_ = eo_imf_packet; - break; - case Smb: - tap_name_ = "smb_eo"; - name_ = "SMB"; - tap_packet_ = eo_smb_packet; - eo_protocoldata_resetfn_ = eo_smb_cleanup; - break; - case Tftp: - tap_name_ = "tftp_eo"; - name_ = "TFTP"; - tap_packet_ = eo_tftp_packet; - break; - } + export_object_list_.add_entry = object_list_add_entry; + export_object_list_.get_entry = object_list_get_entry; + export_object_list_.gui_data = (void*)&eo_gui_data_; save_bt_ = eo_ui_->buttonBox->button(QDialogButtonBox::Save); save_all_bt_ = eo_ui_->buttonBox->button(QDialogButtonBox::SaveAll); close_bt = eo_ui_->buttonBox->button(QDialogButtonBox::Close); - setWindowTitle(wsApp->windowTitleString(QStringList() << tr("Export") << tr("%1 object list").arg(name_))); + setWindowTitle(wsApp->windowTitleString(QStringList() << tr("Export") << tr("%1 object list").arg(proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo)))))); if (save_bt_) save_bt_->setEnabled(false); if (save_all_bt_) save_all_bt_->setEnabled(false); @@ -131,46 +187,37 @@ ExportObjectDialog::ExportObjectDialog(QWidget &parent, CaptureFile &cf, ObjectT ExportObjectDialog::~ExportObjectDialog() { delete eo_ui_; - export_object_list_.eod = NULL; + eo_gui_data_.eod = NULL; removeTapListeners(); } void ExportObjectDialog::addObjectEntry(export_object_entry_t *entry) { - QTreeWidgetItem *entry_item; - gchar *size_str; - if (!entry) return; - size_str = format_size(entry->payload_len, format_size_unit_bytes|format_size_prefix_si); - - entry_item = new QTreeWidgetItem(eo_ui_->objectTree); - entry_item->setData(0, Qt::UserRole, qVariantFromValue(entry)); - - entry_item->setText(0, QString().setNum(entry->pkt_num)); - entry_item->setText(1, entry->hostname); - entry_item->setText(2, entry->content_type); - entry_item->setText(3, size_str); - entry_item->setText(4, entry->filename); - g_free(size_str); - // Not perfect but better than nothing. - entry_item->setTextAlignment(3, Qt::AlignRight); + new ExportObjectTreeWidgetItem(eo_ui_->objectTree, entry); if (save_all_bt_) save_all_bt_->setEnabled(true); } export_object_entry_t *ExportObjectDialog::objectEntry(int row) { - QTreeWidgetItem *item = eo_ui_->objectTree->topLevelItem(row); + QTreeWidgetItem *cur_ti = eo_ui_->objectTree->topLevelItem(row); + ExportObjectTreeWidgetItem *eo_ti = dynamic_cast<ExportObjectTreeWidgetItem *>(cur_ti); - if (item) return item->data(0, Qt::UserRole).value<export_object_entry_t *>(); + if (eo_ti) { + return eo_ti->entry(); + } return NULL; } void ExportObjectDialog::resetObjects() { - if (eo_protocoldata_resetfn_) eo_protocoldata_resetfn_(); + export_object_gui_reset_cb reset_cb = get_eo_reset_func(eo_); + if (reset_cb) + reset_cb(); + if (save_bt_) save_bt_->setEnabled(false); if (save_all_bt_) save_all_bt_->setEnabled(false); } @@ -178,9 +225,9 @@ void ExportObjectDialog::resetObjects() void ExportObjectDialog::show() { /* Data will be gathered via a tap callback */ - if (!registerTapListener(tap_name_, &export_object_list_, NULL, 0, + if (!registerTapListener(get_eo_tap_listener_name(eo_), &export_object_list_, NULL, 0, eo_reset, - tap_packet_, + get_eo_packet_func(eo_), NULL)) { return; } @@ -191,6 +238,8 @@ void ExportObjectDialog::show() for (int i = 0; i < eo_ui_->objectTree->columnCount(); i++) eo_ui_->objectTree->resizeColumnToContents(i); + eo_ui_->objectTree->setSortingEnabled(true); + eo_ui_->objectTree->sortByColumn(COL_PACKET, Qt::AscendingOrder); } void ExportObjectDialog::accept() @@ -217,7 +266,13 @@ void ExportObjectDialog::on_objectTree_currentItemChanged(QTreeWidgetItem *item, if (save_bt_) save_bt_->setEnabled(true); - export_object_entry_t *entry = item->data(0, Qt::UserRole).value<export_object_entry_t *>(); + ExportObjectTreeWidgetItem *eo_ti = dynamic_cast<ExportObjectTreeWidgetItem *>(item); + + if (!eo_ti) { + return; + } + + export_object_entry_t *entry = eo_ti->entry(); if (entry && !file_closed_) { cf_goto_frame(cap_file_.capFile(), entry->pkt_num); } @@ -244,10 +299,15 @@ void ExportObjectDialog::saveCurrentEntry() QDir path(wsApp->lastOpenDir()); QString file_name; - if (!item) return; + ExportObjectTreeWidgetItem *eo_ti = dynamic_cast<ExportObjectTreeWidgetItem *>(item); + if (!eo_ti) { + return; + } - entry = item->data(0, Qt::UserRole).value<export_object_entry_t *>(); - if (!entry) return; + entry = eo_ti->entry(); + if (!entry) { + return; + } file_name = QFileDialog::getSaveFileName(this, wsApp->windowTitleString(tr("Save Object As" UTF8_HORIZONTAL_ELLIPSIS)), path.filePath(entry->filename)); @@ -257,7 +317,6 @@ void ExportObjectDialog::saveCurrentEntry() } } -#define MAXFILELEN 255 void ExportObjectDialog::saveAllEntries() { int i; @@ -280,13 +339,17 @@ void ExportObjectDialog::saveAllEntries() save_in_dir.canonicalPath(), QFileDialog::ShowDirsOnly); - if (save_in_path.length() < 1 || save_in_path.length() > MAXFILELEN) return; + if (save_in_path.length() < 1 || save_in_path.length() > EXPORT_OBJECT_MAXFILELEN) return; for (i = 0; (item = eo_ui_->objectTree->topLevelItem(i)) != NULL; i++) { int count = 0; gchar *save_as_fullpath = NULL; - export_object_entry_t *entry = item->data(0, Qt::UserRole).value<export_object_entry_t *>(); + ExportObjectTreeWidgetItem *eo_ti = dynamic_cast<ExportObjectTreeWidgetItem *>(item); + if (!eo_ti) { + continue; + } + export_object_entry_t *entry = eo_ti->entry(); if (!entry) continue; do { @@ -295,16 +358,16 @@ void ExportObjectDialog::saveAllEntries() g_free(save_as_fullpath); if (entry->filename) safe_filename = eo_massage_str(entry->filename, - MAXFILELEN - save_in_path.length(), count); + EXPORT_OBJECT_MAXFILELEN - save_in_path.length(), count); else { char generic_name[256]; const char *ext; - ext = ct2ext(entry->content_type); + ext = eo_ct2ext(entry->content_type); g_snprintf(generic_name, sizeof(generic_name), "object%u%s%s", entry->pkt_num, ext ? "." : "", ext ? ext : ""); safe_filename = eo_massage_str(generic_name, - MAXFILELEN - save_in_path.length(), count); + EXPORT_OBJECT_MAXFILELEN - save_in_path.length(), count); } save_as_fullpath = g_build_filename(save_in_path.toUtf8().constData(), safe_filename->str, NULL); diff --git a/ui/qt/export_object_dialog.h b/ui/qt/export_object_dialog.h index 9084017a80..e400a128b8 100644 --- a/ui/qt/export_object_dialog.h +++ b/ui/qt/export_object_dialog.h @@ -31,25 +31,22 @@ #include <epan/packet_info.h> #include <epan/prefs.h> #include <epan/tap.h> +#include <epan/export_object.h> -#include <ui/export_object.h> +#include <ui/export_object_ui.h> #include "wireshark_dialog.h" -#include <QMetaType> - class QTreeWidgetItem; class QAbstractButton; -Q_DECLARE_METATYPE(export_object_entry_t *) - namespace Ui { class ExportObjectDialog; } -struct _export_object_list_t { +typedef struct _export_object_list_gui_t { class ExportObjectDialog *eod; -}; +} export_object_list_gui_t; class ExportObjectDialog : public WiresharkDialog @@ -57,9 +54,7 @@ class ExportObjectDialog : public WiresharkDialog Q_OBJECT public: - enum ObjectType { Dicom, Http, Imf, Smb, Tftp }; - - explicit ExportObjectDialog(QWidget &parent, CaptureFile &cf, ObjectType object_type); + explicit ExportObjectDialog(QWidget &parent, CaptureFile &cf, register_eo_t* eo); ~ExportObjectDialog(); @@ -81,23 +76,14 @@ private: void saveCurrentEntry(); void saveAllEntries(); - /* When a protocol needs intermediate data structures to construct the - export objects, then it must specifiy a function that cleans up all - those data structures. This function is passed to export_object_window - and called when tap reset or windows closes occurs. If no function is needed - a NULL value should be passed instead */ - typedef void (*eo_protocoldata_reset_cb)(void); - Ui::ExportObjectDialog *eo_ui_; QPushButton *save_bt_; QPushButton *save_all_bt_; export_object_list_t export_object_list_; - const gchar *tap_name_; - const gchar *name_; - tap_packet_cb tap_packet_; - eo_protocoldata_reset_cb eo_protocoldata_resetfn_; + export_object_list_gui_t eo_gui_data_; + register_eo_t* eo_; }; #endif // EXPORT_OBJECT_DIALOG_H diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp index 169fb943f4..8ed0f6a087 100644 --- a/ui/qt/main_window.cpp +++ b/ui/qt/main_window.cpp @@ -30,6 +30,7 @@ #include <epan/prefs.h> #include <epan/stats_tree_priv.h> #include <epan/plugin_if.h> +#include <epan/export_object.h> #include "ui/commandline.h" @@ -54,6 +55,7 @@ #include "capture_interfaces_dialog.h" #endif #include "conversation_colorize_action.h" +#include "export_object_action.h" #include "display_filter_edit.h" #include "export_dissection_dialog.h" #include "file_set_dialog.h" @@ -347,6 +349,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addDynamicMenus())); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addExternalMenus())); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(initConversationMenus())); + connect(wsApp, SIGNAL(appInitialized()), this, SLOT(initExportObjectsMenus())); connect(wsApp, SIGNAL(profileChanging()), this, SLOT(saveWindowGeometry())); connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(layoutPanes())); @@ -1927,6 +1930,27 @@ void MainWindow::initConversationMenus() connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeActionTriggered())); } +void MainWindow::addExportObjectsMenuItem(gpointer data, gpointer user_data) +{ + register_eo_t *eo = (register_eo_t*)data; + MainWindow *window = (MainWindow*)user_data; + + ExportObjectAction *export_action = new ExportObjectAction(window->main_ui_->menuFileExportObjects, eo); + window->main_ui_->menuFileExportObjects->addAction(export_action); + + //initially disable until a file is loaded (then file signals will take over) + export_action->setEnabled(false); + + connect(&window->capture_file_, SIGNAL(captureFileOpened()), export_action, SLOT(captureFileOpened())); + connect(&window->capture_file_, SIGNAL(captureFileClosed()), export_action, SLOT(captureFileClosed())); + connect(export_action, SIGNAL(triggered()), window, SLOT(applyExportObject())); +} + +void MainWindow::initExportObjectsMenus() +{ + eo_iterate_tables(addExportObjectsMenuItem, this); +} + // Titlebar void MainWindow::setTitlebarForCaptureFile() { diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h index 5320fc7f13..cda9116ebb 100644 --- a/ui/qt/main_window.h +++ b/ui/qt/main_window.h @@ -292,6 +292,8 @@ private slots: void initViewColorizeMenu(); void initConversationMenus(); + static void addExportObjectsMenuItem(gpointer data, gpointer user_data); + void initExportObjectsMenus(); // in main_window_slots.cpp /** @@ -387,11 +389,6 @@ private slots: void on_actionFileExportAsPDML_triggered(); void on_actionFileExportAsJSON_triggered(); void on_actionFileExportPacketBytes_triggered(); - void on_actionFileExportObjectsDICOM_triggered(); - void on_actionFileExportObjectsHTTP_triggered(); - void on_actionFileExportObjectsIMF_triggered(); - void on_actionFileExportObjectsSMB_triggered(); - void on_actionFileExportObjectsTFTP_triggered(); void on_actionFilePrint_triggered(); void on_actionFileExportPDU_triggered(); @@ -489,6 +486,7 @@ private slots: void on_actionAnalyzePAFOrNotSelected_triggered(); void applyConversationFilter(); + void applyExportObject(); void on_actionAnalyzeEnabledProtocols_triggered(); void on_actionAnalyzeDecodeAs_triggered(); diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui index 7c4085d6af..a72b241d7e 100644 --- a/ui/qt/main_window.ui +++ b/ui/qt/main_window.ui @@ -178,11 +178,6 @@ <property name="title"> <string>Export Objects</string> </property> - <addaction name="actionFileExportObjectsDICOM"/> - <addaction name="actionFileExportObjectsHTTP"/> - <addaction name="actionFileExportObjectsIMF"/> - <addaction name="actionFileExportObjectsSMB"/> - <addaction name="actionFileExportObjectsTFTP"/> </widget> <addaction name="actionFileOpen"/> <addaction name="menuOpenRecentCaptureFile"/> @@ -1245,26 +1240,6 @@ <string>As JSON…</string> </property> </action> - <action name="actionFileExportObjectsHTTP"> - <property name="text"> - <string>&HTTP…</string> - </property> - </action> - <action name="actionFileExportObjectsIMF"> - <property name="text"> - <string>&IMF…</string> - </property> - </action> - <action name="actionFileExportObjectsDICOM"> - <property name="text"> - <string>&DICOM…</string> - </property> - </action> - <action name="actionFileExportObjectsSMB"> - <property name="text"> - <string>&SMB…</string> - </property> - </action> <action name="actionEditCopyDescription"> <property name="text"> <string>Description</string> @@ -2076,11 +2051,6 @@ <string>Show or hide the display filter toolbar</string> </property> </action> - <action name="actionFileExportObjectsTFTP"> - <property name="text"> - <string>&TFTP</string> - </property> - </action> <action name="actionStatisticsConversations"> <property name="text"> <string>Conversations</string> diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index 1b2ac37c11..dfdc8ac433 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -43,6 +43,7 @@ #include "ui/commandline.h" #include "epan/color_filters.h" +#include "epan/export_object.h" #include "wsutil/file_util.h" #include "wsutil/filesystem.h" @@ -102,6 +103,7 @@ #include "dissector_tables_dialog.h" #include "endpoint_dialog.h" #include "expert_info_dialog.h" +#include "export_object_action.h" #include "export_object_dialog.h" #include "export_pdu_dialog.h" #ifdef HAVE_EXTCAP @@ -1863,36 +1865,11 @@ void MainWindow::on_actionFileExportSSLSessionKeys_triggered() } } -void MainWindow::on_actionFileExportObjectsDICOM_triggered() -{ - new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Dicom); -} - void MainWindow::on_actionStatisticsHpfeeds_triggered() { openStatisticsTreeDialog("hpfeeds"); } -void MainWindow::on_actionFileExportObjectsHTTP_triggered() -{ - new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Http); -} - -void MainWindow::on_actionFileExportObjectsIMF_triggered() -{ - new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Imf); -} - -void MainWindow::on_actionFileExportObjectsSMB_triggered() -{ - new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Smb); -} - -void MainWindow::on_actionFileExportObjectsTFTP_triggered() -{ - new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Tftp); -} - void MainWindow::on_actionFilePrint_triggered() { PrintDialog pdlg(this, capture_file_.capFile()); @@ -2645,6 +2622,15 @@ void MainWindow::applyConversationFilter() } } +void MainWindow::applyExportObject() +{ + ExportObjectAction *export_action = qobject_cast<ExportObjectAction*>(sender()); + if (!export_action) + return; + + new ExportObjectDialog(*this, capture_file_, export_action->exportObject()); +} + // XXX We could probably create the analyze and prepare actions // dynamically using FilterActions and consolidate the methods // below into one callback. |