forked from osmocom/wireshark
Update object export code:
- Add to User's Guide - Add a help button - Move a lot of code into the shared export_object.c file and out of dissector specific file export_object_http.c. This will make adding additional protocols much easier. - Change comment in packet-http.c to reflect new name (Export Object) - Various other minor improvements svn path=/trunk/; revision=20961
This commit is contained in:
parent
7f88f16077
commit
2c5ccc66ef
|
@ -247,11 +247,12 @@ FILE SECTION
|
|||
<!ENTITY WiresharkExportPSDialog SYSTEM "./wsug_graphics/ws-export-ps.png" NDATA PNG>
|
||||
<!ENTITY WiresharkExportPSMLDialog SYSTEM "./wsug_graphics/ws-export-psml.png" NDATA PNG>
|
||||
<!ENTITY WiresharkExportPDMLDialog SYSTEM "./wsug_graphics/ws-export-pdml.png" NDATA PNG>
|
||||
<!ENTITY WiresharkExportSelectedDialog SYSTEM "./wsug_graphics/ws-export-selected.png" NDATA PNG>
|
||||
<!ENTITY WiresharkExportSelectedDialog SYSTEM
|
||||
"./wsug_graphics/ws-export-selected.png" NDATA PNG>
|
||||
<!ENTITY WiresharkExportObjectsDialog SYSTEM "./wsug_graphics/ws-export-objects.png" NDATA PNG>
|
||||
<!ENTITY WiresharkPrint SYSTEM "./wsug_graphics/ws-print.png" NDATA PNG>
|
||||
<!ENTITY WiresharkPacketRangeFrame SYSTEM "./wsug_graphics/ws-packet-range.png" NDATA PNG>
|
||||
<!ENTITY WiresharkPacketFormatFrame SYSTEM "./wsug_graphics/ws-packet-format.png" NDATA PNG>
|
||||
|
||||
<!-- Sixth Chapter -->
|
||||
|
||||
<!-- Appendices etc -->
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 38 KiB |
|
@ -939,6 +939,86 @@
|
|||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
<section id="ChIOExportObjectsDialog">
|
||||
<title>The "Export Objects" dialog box</title>
|
||||
<para>
|
||||
This feature scans through HTTP streams in the currently
|
||||
open capture file or running capture and takes reassembled
|
||||
objects such as HTML documents, image files, executables
|
||||
and anything else that can be transferred over HTTP and
|
||||
lets you save them to disk. If you have a capture
|
||||
running, this list is automatically updated every few
|
||||
seconds with any new objects seen. The saved objects can then be
|
||||
opened with the proper viewer or executed in the case of
|
||||
executables (if it is for the same platform you are
|
||||
running Wireshark on) without any further work on your
|
||||
part.
|
||||
</para>
|
||||
<figure>
|
||||
<title>The "Export Objects" dialog box</title>
|
||||
<graphic entityref="WiresharkExportObjectsDialog" format="PNG"/>
|
||||
</figure>
|
||||
|
||||
<itemizedlist>
|
||||
<para>Columns:</para>
|
||||
<listitem><para>
|
||||
<command>Packet num:</command> The packet number in
|
||||
which this object was found. In some cases, there can
|
||||
be multiple objects in the same packet.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
<command>Hostname:</command> The hostname of the
|
||||
server that sent the object as a response to an HTTP request.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
<command>Content Type:</command> The HTTP content type
|
||||
of this object.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
<command>Bytes:</command> The size of this object in bytes.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
<command>Filename:</command> The final part of the URI
|
||||
(after the last slash). This is typically a filename,
|
||||
but may be a long complex looking string, which
|
||||
typically indicates that the file was received in response to
|
||||
a HTTP POST request.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<itemizedlist>
|
||||
<para>Buttons:</para>
|
||||
<listitem><para>
|
||||
<command>Help:</command> Opens this section in the
|
||||
user's guide.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
<command>Close:</command> Closes this dialog.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
<command>Save As:</command> Saves the currently
|
||||
selected object as a filename you specify. The
|
||||
default filename to save as is taken from the filename
|
||||
column of the objects list.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
<command>Save All:</command> Saves all objects in the
|
||||
list using the filename from the filename column. You
|
||||
will be asked what directory / folder to save them
|
||||
in. If the filename is invalid for the operating system /
|
||||
file system you are running Wireshark on, then an error
|
||||
will appear and that object will not be saved (but all
|
||||
of the others will be).
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="ChIOPrintSection"><title>Printing packets</title>
|
||||
|
|
|
@ -1079,7 +1079,7 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
* be called if something was on some particular port.
|
||||
*/
|
||||
|
||||
/* Save values for Content List -> HTTP GUI feature */
|
||||
/* Save values for the Export Object GUI feature */
|
||||
stat_info->content_type = se_strdup(headers.content_type);
|
||||
stat_info->payload_len = next_tvb->length;
|
||||
stat_info->payload_data = se_memdup(next_tvb->real_data,
|
||||
|
|
|
@ -34,15 +34,17 @@
|
|||
/* 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/prefs.h>
|
||||
#include <epan/tap.h>
|
||||
#include <gtk/compat_macros.h>
|
||||
#include <gtk/dlg_utils.h>
|
||||
#include <gtk/file_dlg.h>
|
||||
#include <gtk/gui_utils.h>
|
||||
#include <gtk/help_dlg.h>
|
||||
#include <gtk/main.h>
|
||||
#include <wiretap/file_util.h>
|
||||
|
||||
|
@ -54,6 +56,18 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "export_object.h"
|
||||
|
||||
enum {
|
||||
EO_PKT_NUM_COLUMN,
|
||||
EO_HOSTNAME_COLUMN,
|
||||
EO_CONTENT_TYPE_COLUMN,
|
||||
EO_BYTES_COLUMN,
|
||||
EO_FILENAME_COLUMN,
|
||||
EO_NUM_COLUMNS /* must be last */
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
eo_remember_this_row(GtkTreeModel *model _U_, GtkTreePath *path,
|
||||
GtkTreeIter *iter _U_, gpointer arg)
|
||||
|
@ -74,14 +88,14 @@ eo_remember_this_row(GtkTreeModel *model _U_, GtkTreePath *path,
|
|||
cf_goto_frame(&cfile, entry->pkt_num);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
eo_remember_row_num(GtkTreeSelection *sel, gpointer data)
|
||||
{
|
||||
gtk_tree_selection_selected_foreach(sel, eo_remember_this_row, data);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
eo_win_destroy_cb(GtkWindow *win _U_, gpointer data)
|
||||
{
|
||||
export_object_list_t *object_list = data;
|
||||
|
@ -90,17 +104,17 @@ eo_win_destroy_cb(GtkWindow *win _U_, gpointer data)
|
|||
remove_tap_listener(object_list);
|
||||
unprotect_thread_critical_region();
|
||||
|
||||
g_free(object_list);
|
||||
g_free(object_list);
|
||||
}
|
||||
|
||||
void
|
||||
static 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 |
|
||||
to_fd = eth_open(save_as_filename, O_WRONLY | O_CREAT | O_EXCL |
|
||||
O_BINARY, 0644);
|
||||
if(to_fd == -1) {
|
||||
if(to_fd == -1) { /* An error occurred */
|
||||
open_failure_alert_box(save_as_filename, errno, TRUE);
|
||||
g_free(save_as_filename);
|
||||
return;
|
||||
|
@ -123,7 +137,7 @@ eo_save_entry(gchar *save_as_filename, export_object_entry_t *entry)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg)
|
||||
{
|
||||
GtkWidget *save_as_w;
|
||||
|
@ -134,7 +148,7 @@ eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg)
|
|||
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.");
|
||||
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, "No object was selected for saving. Please click on an object and click save again.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -153,10 +167,10 @@ eo_save_clicked_cb(GtkWidget *widget _U_, gpointer arg)
|
|||
window_destroy(save_as_w);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg)
|
||||
{
|
||||
gchar *save_as_fullpath = NULL;
|
||||
gchar *save_as_fullpath;
|
||||
export_object_list_t *object_list = arg;
|
||||
export_object_entry_t *entry;
|
||||
GtkWidget *save_in_w;
|
||||
|
@ -172,7 +186,7 @@ eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg)
|
|||
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. */
|
||||
saving each one until we reach the last entry. */
|
||||
last_slist_entry = g_slist_last(object_list->entries);
|
||||
last_slist_entry_num = g_slist_position(object_list->entries,
|
||||
last_slist_entry);
|
||||
|
@ -181,15 +195,238 @@ eo_save_all_clicked_cb(GtkWidget *widget _U_, gpointer arg)
|
|||
|
||||
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);
|
||||
save_as_fullpath = g_build_filename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(save_in_w)), entry->filename, NULL);
|
||||
|
||||
eo_save_entry(save_as_fullpath, entry);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
window_destroy(save_in_w);
|
||||
}
|
||||
|
||||
static void
|
||||
eo_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 void
|
||||
eo_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
|
||||
export_object_window(gchar *tapname, tap_packet_cb tap_packet)
|
||||
{
|
||||
GtkWidget *sw;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreeSelection *selection;
|
||||
GtkWidget *vbox, *bbox, *help_bt, *close_bt, *save_bt, *save_all_bt;
|
||||
GtkTooltips *button_bar_tips;
|
||||
GString *error_msg;
|
||||
export_object_list_t *object_list;
|
||||
gchar *window_title;
|
||||
|
||||
/* Initialize our object list structure */
|
||||
object_list = g_malloc0(sizeof(export_object_list_t));
|
||||
|
||||
/* Data will be gathered via a tap callback */
|
||||
error_msg = register_tap_listener(tapname, object_list, NULL,
|
||||
eo_reset,
|
||||
tap_packet,
|
||||
eo_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;
|
||||
}
|
||||
|
||||
/* Set up our GUI window */
|
||||
button_bar_tips = gtk_tooltips_new();
|
||||
|
||||
window_title = g_strdup_printf("Wireshark: %s object list", tapname);
|
||||
object_list->dlg = dlg_window_new(window_title);
|
||||
g_free(window_title);
|
||||
|
||||
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);
|
||||
|
||||
/* Help button */
|
||||
help_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_HELP);
|
||||
SIGNAL_CONNECT(help_bt, "clicked", topic_cb, HELP_EXPORT_OBJECT_LIST);
|
||||
gtk_tooltips_set_tip(GTK_TOOLTIPS(button_bar_tips), help_bt,
|
||||
"Show help on this dialog", NULL);
|
||||
gtk_box_pack_start(GTK_BOX(bbox), help_bt, FALSE, FALSE, 0);
|
||||
|
||||
/* 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 listed 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_AS);
|
||||
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);
|
||||
GTK_WIDGET_SET_FLAGS(close_bt, GTK_CAN_DEFAULT);
|
||||
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 cancel/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);
|
||||
window_set_cancel_button(object_list->dlg, close_bt,
|
||||
window_cancel_button_cb);
|
||||
|
||||
/* 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 */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* export_object.h
|
||||
* Declarations of routines for tracking & saving content found in HTTP streams
|
||||
* Common routines for tracking & saving objects found in streams of data
|
||||
* Copyright 2007, Stephen Fisher <stephentfisher@yahoo.com>
|
||||
*
|
||||
* $Id$
|
||||
|
@ -28,15 +28,6 @@
|
|||
#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;
|
||||
|
@ -55,11 +46,7 @@ typedef struct _export_object_entry_t {
|
|||
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);
|
||||
void export_object_window(gchar *tapname, tap_packet_cb tap_packet);
|
||||
|
||||
/* Protocol specific */
|
||||
void eo_http_cb(GtkWidget *widget _U_, gpointer data _U_);
|
||||
|
|
|
@ -35,36 +35,12 @@
|
|||
/* 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;
|
||||
}
|
||||
#include "export_object.h"
|
||||
|
||||
static int
|
||||
eo_http_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_,
|
||||
|
@ -74,225 +50,28 @@ eo_http_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_,
|
|||
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) {
|
||||
if(stat_info->content_type) { /* We have new data waiting */
|
||||
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->hostname = stat_info->http_host;
|
||||
entry->content_type = 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);
|
||||
entry->payload_data = stat_info->payload_data;
|
||||
|
||||
object_list->entries =
|
||||
g_slist_append(object_list->entries, entry);
|
||||
return 1;
|
||||
return 1; /* State changed - window should be redrawn */
|
||||
} 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++;
|
||||
return 0; /* State unchanged - no window updates needed */
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
export_object_window("http", eo_http_packet);
|
||||
}
|
||||
|
||||
#endif /* GTK_MAJOR_VERSION >= 2 */
|
||||
|
|
|
@ -469,6 +469,9 @@ topic_action(topic_action_e action)
|
|||
case(HELP_EXPORT_BYTES_WIN32_DIALOG):
|
||||
help_topic_html("ChIOExportSection.html#ChIOExportSelectedDialog");
|
||||
break;
|
||||
case(HELP_EXPORT_OBJECT_LIST):
|
||||
help_topic_html("ChIOExportSection.html#ChIOExportObjectsDialog");
|
||||
break;
|
||||
case(HELP_OPEN_DIALOG):
|
||||
case(HELP_OPEN_WIN32_DIALOG):
|
||||
help_topic_html("ChIOOpenSection.html");
|
||||
|
|
|
@ -76,6 +76,7 @@ typedef enum {
|
|||
HELP_CAPTURE_INFO_DIALOG,
|
||||
HELP_EXPORT_FILE_DIALOG,
|
||||
HELP_EXPORT_BYTES_DIALOG,
|
||||
HELP_EXPORT_OBJECT_LIST,
|
||||
HELP_OPEN_DIALOG,
|
||||
HELP_MERGE_DIALOG,
|
||||
HELP_SAVE_DIALOG,
|
||||
|
|
Loading…
Reference in New Issue