diff options
author | Stephen Fisher <steve@stephen-fisher.com> | 2007-02-28 23:20:40 +0000 |
---|---|---|
committer | Stephen Fisher <steve@stephen-fisher.com> | 2007-02-28 23:20:40 +0000 |
commit | d3b873b60d78e87896f26b359d3b56db576a925d (patch) | |
tree | db57a5aff0a43d22bd0a786356bdfdb45f4cb312 /gtk | |
parent | 793e70956e1d26a816dffd5e9faa265ef89a1bc0 (diff) |
Sync up my changes so far to the content list (now called object
list) feature for http traffic. It's now available under File->
Export->Objects->HTTP. More changes to come..
svn path=/trunk/; revision=20951
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/Makefile.common | 3 | ||||
-rw-r--r-- | gtk/content_list_http.c | 405 | ||||
-rw-r--r-- | gtk/export_object.c | 195 | ||||
-rw-r--r-- | gtk/export_object.h | 67 | ||||
-rw-r--r-- | gtk/export_object_http.c | 298 | ||||
-rw-r--r-- | gtk/file_dlg.c | 5 | ||||
-rw-r--r-- | gtk/file_dlg.h | 3 | ||||
-rw-r--r-- | gtk/menu.c | 22 |
8 files changed, 577 insertions, 421 deletions
diff --git a/gtk/Makefile.common b/gtk/Makefile.common index 93d4577873..43de810214 100644 --- a/gtk/Makefile.common +++ b/gtk/Makefile.common @@ -63,6 +63,8 @@ WIRESHARK_GTK_SRC = \ drag_and_drop.c \ wireshark-tap-register.c \ expert_comp_table.c \ + export_object.c \ + export_object_http.c \ file_dlg.c \ fileset_dlg.c \ filter_dlg.c \ @@ -125,7 +127,6 @@ WIRESHARK_TAP_SRC = \ bootp_stat.c \ camel_counter.c \ camel_srt.c \ - content_list_http.c \ conversations_eth.c \ conversations_fc.c \ conversations_fddi.c \ diff --git a/gtk/content_list_http.c b/gtk/content_list_http.c deleted file mode 100644 index 6bf97ca2cc..0000000000 --- a/gtk/content_list_http.c +++ /dev/null @@ -1,405 +0,0 @@ -/* content_list_http.c - * Routines for tracking & saving content found in HTTP streams - * Copyright 2007, Stephen Fisher <stephentfisher@yahoo.com> - * - * $Id$ - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <glib.h> -#include <gtk/gtk.h> - -/* This feature has not been ported to GTK1 */ -#if GTK_MAJOR_VERSION >= 2 - -#include <alert_box.h> -#include <epan/dissectors/packet-http.h> -#include <epan/emem.h> -#include <epan/epan.h> -#include <epan/packet_info.h> -#include <epan/prefs.h> -#include <epan/tap.h> -#include <file.h> -#include <globals.h> -#include <stat_menu.h> -#include <gtk/compat_macros.h> -#include <gtk/dlg_utils.h> -#include <gtk/file_dlg.h> -#include <gtk/gui_stat_menu.h> -#include <gtk/gui_utils.h> -#include <gtk/main.h> -#include <simple_dialog.h> -#include <wiretap/file_util.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef HAVE_FCNTL_H -#include <fcntl.h> -#endif - -enum { - PKT_NUM, - HOSTNAME_COLUMN, - CONTENT_TYPE_COLUMN, - BYTES_COLUMN, - FILENAME_COLUMN, - NUM_CONTENT_LIST_COLUMNS /* must be last */ -}; - -typedef struct _cl_http_t { - GSList *entries; - GtkWidget *tree, *dlg; - GtkTreeView *tree_view; - GtkTreeIter *iter; - GtkTreeStore *store; - gint slist_pos, row_selected; -} cl_http_t; - -typedef struct _cl_http_entry_t { - guint32 pkt_num; - gchar *hostname; - gchar *content_type; - gchar *filename; - guint payload_len; - guint8 *payload_data; -} cl_http_entry_t; - - -static void -remember_this_row(GtkTreeModel *model _U_, GtkTreePath *path, - GtkTreeIter *iter _U_, gpointer arg) -{ - cl_http_t *content_list = arg; - - gint *path_index; - - if((path_index = gtk_tree_path_get_indices(path)) == NULL) - return; - - content_list->row_selected = path_index[0]; -} - -static void -remember_row_num(GtkTreeSelection *sel, gpointer data) -{ - gtk_tree_selection_selected_foreach(sel, remember_this_row, data); -} - -static void -cl_http_win_destroy_cb(GtkWindow *win _U_, gpointer data) -{ - cl_http_t *content_list = data; - - protect_thread_critical_region(); - remove_tap_listener(content_list); - unprotect_thread_critical_region(); - - g_free(content_list); -} - - -static void -cl_http_reset(void *tapdata) -{ - cl_http_t *content_list = tapdata; - - if(content_list->entries) { - g_slist_free(content_list->entries); - content_list->entries = NULL; - } - - content_list->iter = NULL; -} - -static int -cl_http_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, - const void *data) -{ - cl_http_t *content_list = tapdata; - const http_info_value_t *stat_info = data; - cl_http_entry_t *entry; - - if(stat_info->content_type && - g_ascii_strncasecmp(stat_info->content_type, "<NULL>", 6) != 0) { - entry = g_malloc(sizeof(cl_http_entry_t)); - - entry->pkt_num = pinfo->fd->num; - entry->hostname = g_strdup(stat_info->http_host); - entry->content_type = g_strdup(stat_info->content_type); - entry->filename = g_path_get_basename(stat_info->request_uri); - entry->payload_len = stat_info->payload_len; - entry->payload_data = g_memdup(stat_info->payload_data, - stat_info->payload_len); - - content_list->entries = g_slist_append(content_list->entries, entry); - return 1; - } else { - return 0; - } -} - -static void -cl_http_draw(void *tapdata) -{ - cl_http_t *content_list = tapdata; - - cl_http_entry_t *cl_entry; - GSList *slist_entry = NULL; - GSList *last_slist_entry = NULL; - gint last_slist_entry_num; - GtkTreeIter new_iter; - gchar *column_text[NUM_CONTENT_LIST_COLUMNS]; - - last_slist_entry = g_slist_last(content_list->entries); - last_slist_entry_num = g_slist_position(content_list->entries, - last_slist_entry); - - while(content_list->slist_pos <= last_slist_entry_num && - last_slist_entry_num != -1) { - slist_entry = g_slist_nth(content_list->entries, - content_list->slist_pos); - cl_entry = slist_entry->data; - - column_text[0] = g_strdup_printf("%u", cl_entry->pkt_num); - column_text[1] = g_strdup_printf("%s", cl_entry->hostname); - column_text[2] = g_strdup_printf("%s", cl_entry->content_type); - column_text[3] = g_strdup_printf("%u", cl_entry->payload_len); - column_text[4] = g_strdup_printf("%s", cl_entry->filename); - - gtk_tree_store_append(content_list->store, &new_iter, content_list->iter); - - gtk_tree_store_set(content_list->store, &new_iter, - PKT_NUM, column_text[0], - HOSTNAME_COLUMN, column_text[1], - CONTENT_TYPE_COLUMN, column_text[2], - BYTES_COLUMN, column_text[3], - FILENAME_COLUMN, column_text[4], - -1); - - g_free(column_text[0]); - g_free(column_text[1]); - g_free(column_text[2]); - g_free(column_text[3]); - g_free(column_text[4]); - - content_list->slist_pos++; - } -} - -static void -cl_http_save_clicked_cb(GtkWidget *widget, cl_http_entry_t *entry) -{ - int to_fd; - gchar *save_as_filename; - - save_as_filename = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget))); - - to_fd = eth_open(save_as_filename, O_WRONLY | O_CREAT | O_TRUNC | - O_BINARY, 0644); - if(to_fd == -1) { - open_failure_alert_box(save_as_filename, errno, TRUE); - g_free(save_as_filename); - return; - } - - if(eth_write(to_fd, entry->payload_data, entry->payload_len) < 0) { - write_failure_alert_box(save_as_filename, errno); - eth_close(to_fd); - g_free(save_as_filename); - return; - } - - if (eth_close(to_fd) < 0) { - write_failure_alert_box(save_as_filename, errno); - g_free(save_as_filename); - return; - } - - g_free(save_as_filename); -} - - -static void -cl_http_save_entry_cb(GtkWidget *widget _U_, gpointer arg) -{ - GtkWidget *save_as_w; - cl_http_entry_t *entry; - cl_http_t *content_list = arg; - - entry = g_slist_nth_data(content_list->entries, - content_list->row_selected); - - if(!entry) - return; - - save_as_w = file_selection_new("Wireshark: Save Content As ...", - FILE_SELECTION_SAVE); - - gtk_window_set_transient_for(GTK_WINDOW(save_as_w), - GTK_WINDOW(content_list->dlg)); - - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_as_w), - entry->filename); - - if(gtk_dialog_run(GTK_DIALOG(save_as_w)) == GTK_RESPONSE_ACCEPT) - cl_http_save_clicked_cb(save_as_w, entry); - - window_destroy(save_as_w); -} - - -static void -cl_http_cb(GtkWidget *widget _U_, gpointer data _U_) -{ - GString *error_msg; - GtkWidget *sw; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - GtkTreeSelection *selection; - GtkWidget *vbox, *bbox, *close_bt, *save_bt; - - cl_http_t *content_list = g_malloc0(sizeof(cl_http_t)); - - /* Data will be gathered via a tap callback */ - error_msg = register_tap_listener("http", content_list, NULL, - cl_http_reset, - cl_http_packet, - cl_http_draw); - - if (error_msg) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "Can't register http tap: %s\n", error_msg->str); - g_string_free(error_msg, TRUE); - return; - } - - content_list->dlg = dlg_window_new("Wireshark: HTTP Content List"); - gtk_window_set_default_size(GTK_WINDOW(content_list->dlg), - DEF_WIDTH, DEF_HEIGHT); - - vbox = gtk_vbox_new(FALSE, 5); - - gtk_container_border_width(GTK_CONTAINER(vbox), 5); - gtk_container_add(GTK_CONTAINER(content_list->dlg), vbox); - - sw = scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_IN); - - gtk_container_add(GTK_CONTAINER(vbox), sw); - - content_list->store = gtk_tree_store_new(NUM_CONTENT_LIST_COLUMNS, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING); - - content_list->tree = tree_view_new(GTK_TREE_MODEL(content_list->store)); - - content_list->tree_view = GTK_TREE_VIEW(content_list->tree); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Packet num", - renderer, - "text", - PKT_NUM, - NULL); - gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); - gtk_tree_view_append_column(content_list->tree_view, column); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Hostname", - renderer, - "text", - HOSTNAME_COLUMN, - NULL); - gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); - gtk_tree_view_append_column(content_list->tree_view, column); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Content Type", - renderer, - "text", - CONTENT_TYPE_COLUMN, - NULL); - gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); - gtk_tree_view_append_column(content_list->tree_view, column); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Bytes", - renderer, - "text", - BYTES_COLUMN, - NULL); - gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); - gtk_tree_view_append_column(content_list->tree_view, column); - - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes("Filename", - renderer, - "text", - FILENAME_COLUMN, - NULL); - gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); - gtk_tree_view_append_column(content_list->tree_view, column); - - gtk_container_add(GTK_CONTAINER(sw), content_list->tree); - - selection = gtk_tree_view_get_selection(content_list->tree_view); - SIGNAL_CONNECT(selection, "changed", remember_row_num, content_list); - - bbox = dlg_button_row_new(GTK_STOCK_CLOSE, GTK_STOCK_SAVE, NULL); - gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); - gtk_widget_show(bbox); - - save_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_SAVE); - SIGNAL_CONNECT(save_bt, "clicked", cl_http_save_entry_cb, content_list); - - SIGNAL_CONNECT(content_list->dlg, "delete_event", - window_delete_event_cb, NULL); - SIGNAL_CONNECT(content_list->dlg, "destroy", - cl_http_win_destroy_cb, NULL); - - close_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CLOSE); - window_set_cancel_button(content_list->dlg, close_bt, - window_cancel_button_cb); - - gtk_widget_show_all(content_list->dlg); - window_present(content_list->dlg); - - cf_retap_packets(&cfile, FALSE); -} -#endif /* GTK_MAJOR_VERSION >= 2 */ - - -void -register_tap_listener_gtk_cl_http_stat(void) -{ -#if GTK_MAJOR_VERSION >= 2 - register_stat_menu_item("HTTP", REGISTER_STAT_GROUP_CONTENT_LIST, - cl_http_cb, NULL, NULL, NULL); -#endif -} diff --git a/gtk/export_object.c b/gtk/export_object.c new file mode 100644 index 0000000000..bb986ca643 --- /dev/null +++ b/gtk/export_object.c @@ -0,0 +1,195 @@ +/* export_object.c + * Common routines for tracking & saving objects found in streams of data + * Copyright 2007, Stephen Fisher <stephentfisher@yahoo.com> + * + * $Id$ + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib.h> +#include <gtk/gtk.h> + +/* This feature has not been ported to GTK1 */ +#if GTK_MAJOR_VERSION >= 2 + +#include "export_object.h" + +#include <alert_box.h> +#include <simple_dialog.h> + +#include <epan/packet_info.h> +#include <epan/tap.h> +#include <gtk/file_dlg.h> +#include <gtk/gui_utils.h> +#include <gtk/main.h> +#include <wiretap/file_util.h> + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +static void +eo_remember_this_row(GtkTreeModel *model _U_, GtkTreePath *path, + GtkTreeIter *iter _U_, gpointer arg) +{ + export_object_list_t *object_list = arg; + export_object_entry_t *entry; + + gint *path_index; + + if((path_index = gtk_tree_path_get_indices(path)) == NULL) + return; + + object_list->row_selected = path_index[0]; + + entry = g_slist_nth_data(object_list->entries, + object_list->row_selected); + + cf_goto_frame(&cfile, entry->pkt_num); +} + +void +eo_remember_row_num(GtkTreeSelection *sel, gpointer data) +{ + gtk_tree_selection_selected_foreach(sel, eo_remember_this_row, data); +} + + +void +eo_win_destroy_cb(GtkWindow *win _U_, gpointer data) +{ + export_object_list_t *object_list = data; + + protect_thread_critical_region(); + remove_tap_listener(object_list); + unprotect_thread_critical_region(); + + g_free(object_list); +} + +void +eo_save_entry(gchar *save_as_filename, export_object_entry_t *entry) +{ + int to_fd; + + to_fd = eth_open(save_as_filename, O_WRONLY | O_CREAT | O_TRUNC | + O_BINARY, 0644); + if(to_fd == -1) { + open_failure_alert_box(save_as_filename, errno, TRUE); + g_free(save_as_filename); + return; + } + + if(eth_write(to_fd, entry->payload_data, entry->payload_len) < 0) { + write_failure_alert_box(save_as_filename, errno); + eth_close(to_fd); + g_free(save_as_filename); + return; + } + + if (eth_close(to_fd) < 0) { + write_failure_alert_box(save_as_filename, errno); + g_free(save_as_filename); + return; + } + + g_free(save_as_filename); +} + + +void +eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg) +{ + GtkWidget *save_as_w; + export_object_list_t *object_list = arg; + export_object_entry_t *entry = NULL; + + entry = g_slist_nth_data(object_list->entries, + object_list->row_selected); + + if(!entry) { + simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, "No object was selected for saving. Please click on an object and click on save again."); + return; + } + + save_as_w = file_selection_new("Wireshark: Save Object As ...", + FILE_SELECTION_SAVE); + + gtk_window_set_transient_for(GTK_WINDOW(save_as_w), + GTK_WINDOW(object_list->dlg)); + + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(save_as_w), + entry->filename); + + if(gtk_dialog_run(GTK_DIALOG(save_as_w)) == GTK_RESPONSE_ACCEPT) + eo_save_entry(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_as_w)), entry); + + window_destroy(save_as_w); +} + +void +eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg) +{ + gchar *save_as_fullpath = NULL; + export_object_list_t *object_list = arg; + export_object_entry_t *entry; + GtkWidget *save_in_w; + GSList *last_slist_entry; + gint last_slist_entry_num, i; + + save_in_w = file_selection_new("Wireshark: Save All Objects In ...", + FILE_SELECTION_CREATE_FOLDER); + + gtk_window_set_transient_for(GTK_WINDOW(save_in_w), + GTK_WINDOW(object_list->dlg)); + + if(gtk_dialog_run(GTK_DIALOG(save_in_w)) == GTK_RESPONSE_ACCEPT) { + + /* Find the last entry in the SList, then start at the beginning + saving each one. */ + last_slist_entry = g_slist_last(object_list->entries); + last_slist_entry_num = g_slist_position(object_list->entries, + last_slist_entry); + + for(i = 0; i <= last_slist_entry_num; i++) { + + entry = g_slist_nth_data(object_list->entries, i); + + save_as_fullpath = g_strdup_printf("%s%c%s", gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_in_w)), G_DIR_SEPARATOR, entry->filename); + + eo_save_entry(save_as_fullpath, entry); + + } + + } + + window_destroy(save_in_w); +} + +#endif /* GTK_MAJOR_VERSION >= 2 */ diff --git a/gtk/export_object.h b/gtk/export_object.h new file mode 100644 index 0000000000..861fee5c7a --- /dev/null +++ b/gtk/export_object.h @@ -0,0 +1,67 @@ +/* export_object.h + * Declarations of routines for tracking & saving content found in HTTP streams + * Copyright 2007, Stephen Fisher <stephentfisher@yahoo.com> + * + * $Id$ + * + * 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__ + +/* Common between protocols */ +enum { + EO_PKT_NUM_COLUMN, + EO_HOSTNAME_COLUMN, + EO_CONTENT_TYPE_COLUMN, + EO_BYTES_COLUMN, + EO_FILENAME_COLUMN, + EO_NUM_COLUMNS /* must be last */ +}; + +typedef struct _export_object_list_t { + GSList *entries; + GtkWidget *tree, *dlg; + GtkTreeView *tree_view; + GtkTreeIter *iter; + GtkTreeStore *store; + gint slist_pos, row_selected; +} export_object_list_t; + +typedef struct _export_object_entry_t { + guint32 pkt_num; + gchar *hostname; + gchar *content_type; + gchar *filename; + guint payload_len; + guint8 *payload_data; +} export_object_entry_t; + +void eo_remember_row_num(GtkTreeSelection *sel, gpointer data); +void eo_win_destroy_cb(GtkWindow *win _U_, gpointer data); +void eo_save_entry_cb(GtkWidget *widget, export_object_entry_t *entry); +void eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg); +void eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg); + +/* Protocol specific */ +void eo_http_cb(GtkWidget *widget _U_, gpointer data _U_); + +#endif /* __EXPORT_OBJECT_H__ */ diff --git a/gtk/export_object_http.c b/gtk/export_object_http.c new file mode 100644 index 0000000000..6465612134 --- /dev/null +++ b/gtk/export_object_http.c @@ -0,0 +1,298 @@ +/* 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 <stephentfisher@yahoo.com> + * + * $Id$ + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib.h> +#include <gtk/gtk.h> + +/* This feature has not been ported to GTK1 */ +#if GTK_MAJOR_VERSION >= 2 + +#include "export_object.h" + +#include <epan/dissectors/packet-http.h> +#include <epan/emem.h> +#include <epan/epan.h> +#include <epan/prefs.h> +#include <epan/tap.h> +#include <file.h> +#include <globals.h> +#include <simple_dialog.h> +#include <stat_menu.h> +#include <gtk/compat_macros.h> +#include <gtk/dlg_utils.h> +#include <gtk/file_dlg.h> +#include <gtk/gui_utils.h> +#include <gtk/gui_stat_menu.h> + +static void +eo_http_reset(void *tapdata) +{ + export_object_list_t *object_list = tapdata; + + if(object_list->entries) { + g_slist_free(object_list->entries); + object_list->entries = NULL; + } + + object_list->iter = NULL; + object_list->row_selected = -1; +} + +static int +eo_http_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, + const void *data) +{ + export_object_list_t *object_list = tapdata; + const http_info_value_t *stat_info = data; + export_object_entry_t *entry; + + if(stat_info->content_type && + g_ascii_strncasecmp(stat_info->content_type, "<NULL>", 6) != 0) { + entry = g_malloc(sizeof(export_object_entry_t)); + + entry->pkt_num = pinfo->fd->num; + entry->hostname = g_strdup(stat_info->http_host); + entry->content_type = g_strdup(stat_info->content_type); + + if(stat_info->request_uri) + entry->filename = + g_path_get_basename(stat_info->request_uri); + else + entry->filename = NULL; + + entry->payload_len = stat_info->payload_len; + entry->payload_data = g_memdup(stat_info->payload_data, + stat_info->payload_len); + + object_list->entries = + g_slist_append(object_list->entries, entry); + return 1; + } else { + return 0; + } +} + +static void +eo_http_draw(void *tapdata) +{ + export_object_list_t *object_list = tapdata; + export_object_entry_t *eo_entry; + + GSList *slist_entry = NULL; + GSList *last_slist_entry = NULL; + gint last_slist_entry_num; + GtkTreeIter new_iter; + gchar *column_text[EO_NUM_COLUMNS]; + + last_slist_entry = g_slist_last(object_list->entries); + last_slist_entry_num = g_slist_position(object_list->entries, + last_slist_entry); + + while(object_list->slist_pos <= last_slist_entry_num && + last_slist_entry_num != -1) { + slist_entry = g_slist_nth(object_list->entries, + object_list->slist_pos); + eo_entry = slist_entry->data; + + column_text[0] = g_strdup_printf("%u", eo_entry->pkt_num); + column_text[1] = g_strdup_printf("%s", eo_entry->hostname); + column_text[2] = g_strdup_printf("%s", eo_entry->content_type); + column_text[3] = g_strdup_printf("%u", eo_entry->payload_len); + column_text[4] = g_strdup_printf("%s", eo_entry->filename); + + gtk_tree_store_append(object_list->store, &new_iter, + object_list->iter); + + gtk_tree_store_set(object_list->store, &new_iter, + EO_PKT_NUM_COLUMN, column_text[0], + EO_HOSTNAME_COLUMN, column_text[1], + EO_CONTENT_TYPE_COLUMN, column_text[2], + EO_BYTES_COLUMN, column_text[3], + EO_FILENAME_COLUMN, column_text[4], + -1); + + g_free(column_text[0]); + g_free(column_text[1]); + g_free(column_text[2]); + g_free(column_text[3]); + g_free(column_text[4]); + + object_list->slist_pos++; + } +} + +void +eo_http_cb(GtkWidget *widget _U_, gpointer data _U_) +{ + GString *error_msg; + GtkWidget *sw; + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkTreeSelection *selection; + GtkWidget *vbox, *bbox, *close_bt, *save_bt, *save_all_bt; + GtkTooltips *button_bar_tips; + + export_object_list_t *object_list = g_malloc0(sizeof(export_object_list_t)); + + button_bar_tips = gtk_tooltips_new(); + + /* Data will be gathered via a tap callback */ + error_msg = register_tap_listener("http", object_list, NULL, + eo_http_reset, + eo_http_packet, + eo_http_draw); + + if (error_msg) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "Can't register http tap: %s\n", error_msg->str); + g_string_free(error_msg, TRUE); + return; + } + + object_list->dlg = dlg_window_new("Wireshark: HTTP Content List"); + + gtk_window_set_default_size(GTK_WINDOW(object_list->dlg), + DEF_WIDTH, DEF_HEIGHT); + + vbox = gtk_vbox_new(FALSE, 5); + + gtk_container_border_width(GTK_CONTAINER(vbox), 5); + gtk_container_add(GTK_CONTAINER(object_list->dlg), vbox); + + sw = scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), + GTK_SHADOW_IN); + + gtk_container_add(GTK_CONTAINER(vbox), sw); + + object_list->store = gtk_tree_store_new(EO_NUM_COLUMNS, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING); + + object_list->tree = tree_view_new(GTK_TREE_MODEL(object_list->store)); + + object_list->tree_view = GTK_TREE_VIEW(object_list->tree); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes("Packet num", + renderer, + "text", + EO_PKT_NUM_COLUMN, + NULL); + gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); + gtk_tree_view_append_column(object_list->tree_view, column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes("Hostname", + renderer, + "text", + EO_HOSTNAME_COLUMN, + NULL); + gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); + gtk_tree_view_append_column(object_list->tree_view, column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes("Content Type", + renderer, + "text", + EO_CONTENT_TYPE_COLUMN, + NULL); + gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); + gtk_tree_view_append_column(object_list->tree_view, column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes("Bytes", + renderer, + "text", + EO_BYTES_COLUMN, + NULL); + gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); + gtk_tree_view_append_column(object_list->tree_view, column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes("Filename", + renderer, + "text", + EO_FILENAME_COLUMN, + NULL); + gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); + gtk_tree_view_append_column(object_list->tree_view, column); + + gtk_container_add(GTK_CONTAINER(sw), object_list->tree); + + selection = gtk_tree_view_get_selection(object_list->tree_view); + SIGNAL_CONNECT(selection, "changed", eo_remember_row_num, object_list); + + bbox = gtk_hbox_new(FALSE, 5); + + /* Save All button */ + save_all_bt = gtk_button_new_with_mnemonic("Save _All"); + SIGNAL_CONNECT(save_all_bt, "clicked", eo_save_all_clicked_cb, + object_list); + gtk_tooltips_set_tip(GTK_TOOLTIPS(button_bar_tips), save_all_bt, + "Save all displayed objects with their displayed " + "filenames.", NULL); + gtk_box_pack_end(GTK_BOX(bbox), save_all_bt, FALSE, FALSE, 0); + + /* Save button */ + save_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_SAVE); + SIGNAL_CONNECT(save_bt, "clicked", eo_save_clicked_cb, object_list); + gtk_tooltips_set_tip(GTK_TOOLTIPS(button_bar_tips), save_bt, + "Saves the currently selected content to a file.", + NULL); + gtk_box_pack_end(GTK_BOX(bbox), save_bt, FALSE, FALSE, 0); + + /* Close button */ + close_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLOSE); + window_set_cancel_button(object_list->dlg, close_bt, + window_cancel_button_cb); + gtk_tooltips_set_tip(GTK_TOOLTIPS(button_bar_tips), close_bt, + "Close this dialog.", NULL); + gtk_box_pack_end(GTK_BOX(bbox), close_bt, FALSE, FALSE, 0); + + /* Pack the buttons into the "button box" */ + gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); + gtk_widget_show(bbox); + + /* Setup delete/destroy signal handlers */ + SIGNAL_CONNECT(object_list->dlg, "delete_event", + window_delete_event_cb, NULL); + SIGNAL_CONNECT(object_list->dlg, "destroy", + eo_win_destroy_cb, NULL); + + /* Show the window */ + gtk_widget_show_all(object_list->dlg); + window_present(object_list->dlg); + + cf_retap_packets(&cfile, FALSE); +} +#endif /* GTK_MAJOR_VERSION >= 2 */ diff --git a/gtk/file_dlg.c b/gtk/file_dlg.c index 2b8d5ee20c..306a86c598 100644 --- a/gtk/file_dlg.c +++ b/gtk/file_dlg.c @@ -101,6 +101,11 @@ file_selection_new(const gchar *title, file_selection_action_t action) ok_button_text = GTK_STOCK_OK; break; + case FILE_SELECTION_CREATE_FOLDER: + gtk_action = GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER; + ok_button_text = GTK_STOCK_OK; + break; + default: g_assert_not_reached(); gtk_action = -1; diff --git a/gtk/file_dlg.h b/gtk/file_dlg.h index ea90a3c911..43cdb1dd79 100644 --- a/gtk/file_dlg.h +++ b/gtk/file_dlg.h @@ -56,7 +56,8 @@ typedef enum { FILE_SELECTION_OPEN, /**< open a file */ FILE_SELECTION_READ_BROWSE, /**< browse for a file to read */ FILE_SELECTION_SAVE, /**< save/export a file */ - FILE_SELECTION_WRITE_BROWSE /**< browse for a file to write to */ + FILE_SELECTION_WRITE_BROWSE, /**< browse for a file to write to */ + FILE_SELECTION_CREATE_FOLDER /**< browse for a dir. to save in */ } file_selection_action_t; /** Create a file selection dialog box window that belongs to Wireshark's diff --git a/gtk/menu.c b/gtk/menu.c index 0ca5df11dc..f92e78a929 100644 --- a/gtk/menu.c +++ b/gtk/menu.c @@ -84,6 +84,10 @@ #include "u3.h" #include "macros_dlg.h" +#if GTK_MAJOR_VERSION >= 2 +#include "export_object.h" +#endif + GtkWidget *popup_menu_object; static void @@ -417,6 +421,10 @@ static GtkItemFactoryEntry menu_items[] = #endif ITEM_FACTORY_ENTRY("/File/Export/Selected Packet _Bytes...", "<control>H", savehex_cb, 0, NULL, NULL), +#if GTK_MAJOR_VERSION >= 2 + ITEM_FACTORY_ENTRY("/File/Export/_Objects/_HTTP", NULL, eo_http_cb, 0, NULL, + NULL), +#endif ITEM_FACTORY_ENTRY("/File/<separator>", NULL, NULL, 0, "<Separator>", NULL), ITEM_FACTORY_STOCK_ENTRY("/File/_Print...", "<control>P", file_print_cmd_cb, 0, GTK_STOCK_PRINT), @@ -983,9 +991,6 @@ register_stat_menu_item( switch(group) { case(REGISTER_STAT_GROUP_GENERIC): toolspath = "/Statistics/"; break; -#if GTK_MAJOR_VERSION >= 2 - case(REGISTER_STAT_GROUP_CONTENT_LIST): toolspath = "/Statistics/C_ontent List/"; break; -#endif case(REGISTER_STAT_GROUP_CONVERSATION_LIST): toolspath = "/Statistics/_Conversation List/"; break; case(REGISTER_STAT_GROUP_ENDPOINT_LIST): toolspath = "/Statistics/_Endpoint List/"; break; case(REGISTER_STAT_GROUP_RESPONSE_TIME): toolspath = "/Statistics/Service _Response Time/"; break; @@ -1105,12 +1110,6 @@ static guint merge_tap_menus_layered(GList *node, gint group) { break; case(REGISTER_STAT_GROUP_GENERIC): break; - case(REGISTER_STAT_GROUP_CONTENT_LIST): -#if GTK_MAJOR_VERSION > 2 || (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 6) - entry->item_type = "<StockItem>"; - entry->extra_data = GTK_STOCK_FILE; -#endif - break; case(REGISTER_STAT_GROUP_CONVERSATION_LIST): entry->item_type = "<StockItem>"; entry->extra_data = WIRESHARK_STOCK_CONVERSATIONS; @@ -1186,11 +1185,6 @@ void merge_all_tap_menus(GList *node) { if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_GENERIC)) { gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2); } -#if GTK_MAJOR_VERSION >= 2 - if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_CONTENT_LIST)) { - /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/ - } -#endif if (merge_tap_menus_layered(node, REGISTER_STAT_GROUP_CONVERSATION_LIST)) { /*gtk_item_factory_create_item(main_menu_factory, entry, NULL, 2);*/ } |