/* 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 * * $Id$ * * Wireshark - Network traffic analyzer * By Gerald Combs * 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 #include /* This feature has not been ported to GTK1 */ #if GTK_MAJOR_VERSION >= 2 #include "export_object.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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, "", 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 */