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:
Stephen Fisher 2007-03-03 03:14:00 +00:00
parent 7f88f16077
commit 2c5ccc66ef
9 changed files with 354 additions and 266 deletions

View File

@ -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

View File

@ -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>

View File

@ -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,

View File

@ -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 */

View File

@ -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_);

View File

@ -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 */

View File

@ -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");

View File

@ -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,