Changes required to support multiple named data sources.

Tvbuffers changed to added the data source name,
GUI and printing code changed to support these changes
and display the multiple hex views.

svn path=/trunk/; revision=3165
This commit is contained in:
Jeff Foster 2001-03-23 14:44:04 +00:00
parent c5791fac0c
commit 395b68ea19
13 changed files with 432 additions and 98 deletions

View File

@ -1,6 +1,6 @@
/* epan.h
*
* $Id: epan.c,v 1.6 2001/02/01 20:21:16 gram Exp $
* $Id: epan.c,v 1.7 2001/03/23 14:44:01 jfoster Exp $
*
* Ethereal Protocol Analyzer Library
*
@ -77,6 +77,11 @@ epan_dissect_new(void* pseudo_header, const guint8* data, frame_data *fd, proto_
edt = g_new(epan_dissect_t, 1);
/* start with empty data source list */
if ( fd->data_src)
g_slist_free( fd->data_src);
fd->data_src = 0;
/* XXX - init tree */
edt->tree = tree;

View File

@ -1,7 +1,7 @@
/* packet.c
* Routines for packet disassembly
*
* $Id: packet.c,v 1.22 2001/03/22 16:24:16 gram Exp $
* $Id: packet.c,v 1.23 2001/03/23 14:44:01 jfoster Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -1073,7 +1073,10 @@ dissect_packet(tvbuff_t **p_tvb, union wtap_pseudo_header *pseudo_header,
col_set_writable(fd, TRUE);
TRY {
*p_tvb = tvb_new_real_data(pd, fd->cap_len, fd->pkt_len);
*p_tvb = tvb_new_real_data(pd, fd->cap_len, fd->pkt_len, "Frame");
/* Add this tvbuffer into the data_src list */
fd->data_src = g_slist_append( fd->data_src, *p_tvb);
pi.compat_top_tvb = *p_tvb;
}
CATCH(BoundsError) {

View File

@ -1,7 +1,7 @@
/* packet.h
* Definitions for packet disassembly structures and routines
*
* $Id: packet.h,v 1.23 2001/03/15 06:41:13 guy Exp $
* $Id: packet.h,v 1.24 2001/03/23 14:44:01 jfoster Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -100,6 +100,7 @@ typedef struct _frame_data {
struct _frame_data *next; /* Next element in list */
struct _frame_data *prev; /* Previous element in list */
GSList *pfd; /* Per frame proto data */
GSList *data_src; /* Frame data sources */
guint32 num; /* Frame number */
guint32 pkt_len; /* Packet length */
guint32 cap_len; /* Amount actually captured */
@ -131,6 +132,7 @@ typedef enum {
AT_ATALK, /* Appletalk DDP */
AT_VINES, /* Banyan Vines */
AT_OSI, /* OSI NSAP */
AT_DLCI /* Frame Relay DLCI */
} address_type;
typedef struct _address {

View File

@ -1,7 +1,7 @@
/* proto.c
* Routines for protocol tree
*
* $Id: proto.c,v 1.14 2001/03/15 22:08:41 guy Exp $
* $Id: proto.c,v 1.15 2001/03/23 14:44:02 jfoster Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -1460,6 +1460,9 @@ proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint
return pi;
}
/* The default name for a NullTVB. This removed when all dissectors use tvbuffs */
static gchar* null_tvb_ds_name = "Frame";
static field_info *
alloc_field_info(int hfindex, tvbuff_t *tvb, gint start, gint length)
{
@ -1481,6 +1484,14 @@ alloc_field_info(int hfindex, tvbuff_t *tvb, gint start, gint length)
fi->value = fvalue_new(fi->hfinfo->type);
/* add the data source name */
/* This has the hack to return a default name for NullTVB. This */
/* hack can be removed when all dissectors use tvbuffs */
if ( tvb)
fi->ds_name = tvb_get_name(tvb);
else
fi->ds_name = null_tvb_ds_name;
return fi;
}
@ -2595,6 +2606,7 @@ proto_get_finfo_ptr_array(proto_tree *tree, int id)
typedef struct {
guint offset;
field_info *finfo;
gchar *name;
} offset_search_t;
static gboolean
@ -2604,7 +2616,7 @@ check_for_offset(GNode *node, gpointer data)
offset_search_t *offsearch = data;
/* !fi == the top most container node which holds nothing */
if (fi && fi->visible) {
if (fi && fi->visible && !strcmp( offsearch->name,fi->ds_name)) {
if (offsearch->offset >= fi->start &&
offsearch->offset < (fi->start + fi->length)) {
@ -2624,12 +2636,13 @@ check_for_offset(GNode *node, gpointer data)
* siblings of each node myself. When I have more time I'll do that.
* (yeah right) */
field_info*
proto_find_field_from_offset(proto_tree *tree, guint offset)
proto_find_field_from_offset(proto_tree *tree, guint offset, char* ds_name)
{
offset_search_t offsearch;
offsearch.offset = offset;
offsearch.finfo = NULL;
offsearch.name = ds_name;
g_node_traverse((GNode*)tree, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
check_for_offset, &offsearch);

View File

@ -1,7 +1,7 @@
/* proto.h
* Definitions for protocol display
*
* $Id: proto.h,v 1.8 2001/03/02 23:10:11 gram Exp $
* $Id: proto.h,v 1.9 2001/03/23 14:44:02 jfoster Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -121,6 +121,7 @@ typedef struct field_info {
char *representation; /* for GUI tree */
int visible;
fvalue_t *value;
gchar *ds_name; /* data source name */
} field_info;
@ -558,6 +559,6 @@ char*
proto_alloc_dfilter_string(field_info *finfo, guint8 *pd);
field_info*
proto_find_field_from_offset(proto_tree *tree, guint offset);
proto_find_field_from_offset(proto_tree *tree, guint offset, gchar *ds_name);
#endif /* proto.h */

View File

@ -9,7 +9,7 @@
* the data of a backing tvbuff, or can be a composite of
* other tvbuffs.
*
* $Id: tvbuff.c,v 1.15 2001/03/13 21:34:27 gram Exp $
* $Id: tvbuff.c,v 1.16 2001/03/23 14:44:02 jfoster Exp $
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
*
@ -69,6 +69,7 @@ struct tvbuff {
tvbuff_type type;
gboolean initialized;
guint usage_count;
gchar* ds_name; /* data source name */
/* The tvbuffs in which this tvbuff is a member
* (that is, a backing tvbuff for a TVBUFF_SUBSET
@ -319,7 +320,7 @@ tvb_set_real_data(tvbuff_t* tvb, const guint8* data, guint length, gint reported
}
tvbuff_t*
tvb_new_real_data(const guint8* data, guint length, gint reported_length)
tvb_new_real_data(const guint8* data, guint length, gint reported_length, const gchar* ds_name)
{
tvbuff_t *tvb;
@ -329,6 +330,9 @@ tvb_new_real_data(const guint8* data, guint length, gint reported_length)
tvb_set_real_data(tvb, data, length, reported_length);
/* set the data source name */
tvb->ds_name = g_strdup( ds_name);
CLEANUP_POP;
return tvb;
@ -497,6 +501,7 @@ tvb_new_subset(tvbuff_t *backing, gint backing_offset, gint backing_length, gint
tvb_set_subset(tvb, backing, backing_offset, backing_length, reported_length);
tvb->ds_name = backing->ds_name;
CLEANUP_POP;
return tvb;
@ -1568,3 +1573,9 @@ tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len)
{
return bytes_to_str(tvb_get_ptr(tvb, offset, len), len);
}
gchar*
tvb_get_name(tvbuff_t* tvb)
{
return tvb->ds_name;
}

View File

@ -9,7 +9,7 @@
* the data of a backing tvbuff, or can be a composite of
* other tvbuffs.
*
* $Id: tvbuff.h,v 1.11 2001/03/13 21:34:27 gram Exp $
* $Id: tvbuff.h,v 1.12 2001/03/23 14:44:02 jfoster Exp $
*
* Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
*
@ -139,7 +139,7 @@ void tvb_set_child_real_data_tvbuff(tvbuff_t* parent, tvbuff_t* child);
void tvb_set_real_data(tvbuff_t*, const guint8* data, guint length, gint reported_length);
/* Combination of tvb_new() and tvb_set_real_data(). Can throw ReportedBoundsError. */
tvbuff_t* tvb_new_real_data(const guint8* data, guint length, gint reported_length);
tvbuff_t* tvb_new_real_data(const guint8* data, guint length, gint reported_length, const gchar *name);
/* Define the subset of the backing buffer to use.
@ -363,6 +363,8 @@ gint tvb_strncaseeql(tvbuff_t *tvb, gint offset, const guint8 *str, gint size);
*/
gchar *tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len);
gchar *tvb_get_name(tvbuff_t *tvb);
/************** END OF ACCESSORS ****************/
/* Sets pd and offset so that tvbuff's can be used with code

50
file.c
View File

@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
* $Id: file.c,v 1.232 2001/02/11 09:28:15 guy Exp $
* $Id: file.c,v 1.233 2001/03/23 14:43:59 jfoster Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -89,7 +89,7 @@
#include "globals.h"
#include "gtk/colors.h"
extern GtkWidget *packet_list, *info_bar, *byte_view, *tree_view;
extern GtkWidget *packet_list, *info_bar, *byte_nb_ptr, *tree_view;
extern guint file_ctx;
gboolean auto_scroll_live = FALSE;
@ -771,6 +771,7 @@ read_packet(capture_file *cf, int offset)
fdata->next = NULL;
fdata->prev = NULL;
fdata->pfd = NULL;
fdata->data_src = NULL;
fdata->pkt_len = phdr->len;
fdata->cap_len = phdr->caplen;
fdata->file_off = offset;
@ -990,6 +991,10 @@ rescan_packets(capture_file *cf, const char *action, gboolean refilter,
g_slist_free(fdata->pfd);
}
fdata->pfd = NULL;
if (fdata->data_src) { /* release data source list */
g_slist_free(fdata->data_src);
}
fdata->data_src = NULL;
}
wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
@ -1017,6 +1022,10 @@ rescan_packets(capture_file *cf, const char *action, gboolean refilter,
g_slist_free(fdata->pfd);
}
fdata->pfd = NULL;
if (fdata->data_src) {
g_slist_free(fdata->data_src);
}
fdata->data_src = NULL;
}
}
@ -1222,8 +1231,7 @@ print_packets(capture_file *cf, print_args_t *print_args)
if (print_args->print_hex) {
/* Print the full packet data as hex. */
print_hex_data(cf->print_fh, print_args->format, cf->pd,
fdata->cap_len, fdata->flags.encoding);
print_hex_data(cf->print_fh, print_args->format, fdata);
}
/* Print a blank line if we print anything after this. */
@ -1364,12 +1372,25 @@ static void
clear_tree_and_hex_views(void)
{
/* Clear the hex dump. */
gtk_text_freeze(GTK_TEXT(byte_view));
gtk_text_set_point(GTK_TEXT(byte_view), 0);
gtk_text_forward_delete(GTK_TEXT(byte_view),
gtk_text_get_length(GTK_TEXT(byte_view)));
gtk_text_thaw(GTK_TEXT(byte_view));
GtkWidget *byte_view;
int i;
/* Get the current tab scroll window, then get the text widget */
/* from the E_BYTE_VIEW_TEXT_INFO_KEY data field */
i = gtk_notebook_get_current_page( GTK_NOTEBOOK(byte_nb_ptr));
if ( i >= 0){
byte_view = gtk_notebook_get_nth_page( GTK_NOTEBOOK(byte_nb_ptr), i);
byte_view = gtk_object_get_data(GTK_OBJECT(byte_view), E_BYTE_VIEW_TEXT_INFO_KEY);
gtk_text_freeze(GTK_TEXT(byte_view));
gtk_text_set_point(GTK_TEXT(byte_view), 0);
gtk_text_forward_delete(GTK_TEXT(byte_view),
gtk_text_get_length(GTK_TEXT(byte_view)));
gtk_text_thaw(GTK_TEXT(byte_view));
}
/* Remove all nodes in ctree. This is how it's done in testgtk.c in GTK+ */
gtk_clist_clear ( GTK_CLIST(tree_view) );
@ -1516,6 +1537,8 @@ void
select_packet(capture_file *cf, int row)
{
frame_data *fdata;
tvbuff_t *bv_tvb;
int i;
/* Get the frame data struct pointer for this frame */
fdata = (frame_data *) gtk_clist_get_row_data(GTK_CLIST(packet_list), row);
@ -1569,8 +1592,15 @@ select_packet(capture_file *cf, int row)
/* Display the GUI protocol tree and hex dump. */
clear_tree_and_hex_views();
i = 0;
while((bv_tvb = g_slist_nth_data ( cf->current_frame->data_src, i++))){
add_byte_view( tvb_get_name( bv_tvb), tvb_get_ptr(bv_tvb, 0, -1), tvb_length(bv_tvb));
}
proto_tree_draw(cf->protocol_tree, tree_view);
packet_hex_print(GTK_TEXT(byte_view), cf->pd, cf->current_frame, NULL);
set_notebook_page( byte_nb_ptr, 0);
/* A packet is selected. */
set_menus_for_selected_packet(TRUE);

View File

@ -1,7 +1,7 @@
/* gtkglobals.h
* GTK-related Global defines, etc.
*
* $Id: gtkglobals.h,v 1.12 2001/03/02 23:10:12 gram Exp $
* $Id: gtkglobals.h,v 1.13 2001/03/23 14:44:04 jfoster Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -31,7 +31,7 @@
#endif
extern GtkWidget *top_level, *packet_list, *tree_view,
*byte_view, *info_bar;
*byte_nb_ptr, *info_bar;
extern GdkFont *m_r_font, *m_b_font;
extern guint m_font_height, m_font_width;

View File

@ -1,6 +1,6 @@
/* main.c
*
* $Id: main.c,v 1.182 2001/03/02 23:10:12 gram Exp $
* $Id: main.c,v 1.183 2001/03/23 14:44:04 jfoster Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -8,6 +8,8 @@
*
* Richard Sharpe, 13-Feb-1999, added support for initializing structures
* needed by dissect routines
* Jeff Foster, 2001/03/12, added support tabbed hex display windowss
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -135,7 +137,7 @@
packet_info pi;
capture_file cfile;
GtkWidget *top_level, *packet_list, *tree_view, *byte_view,
GtkWidget *top_level, *packet_list, *tree_view, *byte_nb_ptr,
*info_bar, *tv_scrollw, *pkt_scrollw;
static GtkWidget *bv_scrollw;
GdkFont *m_r_font, *m_b_font;
@ -414,26 +416,44 @@ static void
packet_list_select_cb(GtkWidget *w, gint row, gint col, gpointer evt) {
blank_packetinfo();
/* Remove the hex display tabbed pages */
while( (gtk_notebook_get_nth_page( GTK_NOTEBOOK(byte_nb_ptr), 0)))
gtk_notebook_remove_page( GTK_NOTEBOOK(byte_nb_ptr), 0);
select_packet(&cfile, row);
}
static void
packet_list_unselect_cb(GtkWidget *w, gint row, gint col, gpointer evt) {
unselect_packet(&cfile);
}
static void
tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column, gpointer user_data)
{
field_info *finfo;
gchar *help_str = NULL;
gboolean has_blurb = FALSE;
guint length = 0;
guint length = 0, byte_len;
GtkWidget *byte_view;
guint8 *byte_data;
g_assert(node);
finfo = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
if (!finfo) return;
set_notebook_page( byte_nb_ptr, find_notebook_page( byte_nb_ptr, finfo->ds_name));
byte_view = gtk_object_get_data(GTK_OBJECT(byte_nb_ptr), E_BYTE_VIEW_TEXT_INFO_KEY);
byte_data = gtk_object_get_data(GTK_OBJECT(byte_view), E_BYTE_VIEW_DATA_PTR_KEY);
byte_len = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(byte_view), E_BYTE_VIEW_DATA_LEN_KEY));
g_assert(byte_data);
finfo_selected = finfo;
set_menus_for_selected_tree_row(TRUE);
@ -456,18 +476,28 @@ tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column, gpointer user
g_free(help_str);
}
packet_hex_print(GTK_TEXT(byte_view), cfile.pd, cfile.current_frame,
finfo);
packet_hex_print(GTK_TEXT(byte_view), byte_data, cfile.current_frame,
finfo, byte_len);
}
static void
tree_view_unselect_row_cb(GtkCTree *ctree, GList *node, gint column, gpointer user_data)
{
GtkWidget *byte_view;
guint8 *data;
gint len;
field_info* fi;
fi = (field_info*)user_data;
len = get_byte_view_and_data( byte_nb_ptr, &byte_view, &data);
if ( len < 0) return;
gtk_statusbar_pop(GTK_STATUSBAR(info_bar), help_ctx);
finfo_selected = NULL;
set_menus_for_selected_tree_row(FALSE);
packet_hex_print(GTK_TEXT(byte_view), cfile.pd, cfile.current_frame,
NULL);
packet_hex_print(GTK_TEXT(byte_view), data, cfile.current_frame,
NULL, len);
}
void collapse_all_cb(GtkWidget *widget, gpointer data) {
@ -1576,9 +1606,13 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
gtk_widget_show(tree_view);
/* Byte view. */
create_byte_view(bv_size, l_pane, &byte_view, &bv_scrollw,
create_byte_view(bv_size, l_pane, &byte_nb_ptr, &bv_scrollw,
prefs->gui_scrollbar_on_right);
gtk_signal_connect(GTK_OBJECT(byte_nb_ptr), "button_press_event",
GTK_SIGNAL_FUNC(popup_menu_handler),
gtk_object_get_data(GTK_OBJECT(popup_menu_object), PM_HEXDUMP_KEY));
/* Filter/info box */
stat_hbox = gtk_hbox_new(FALSE, 1);
gtk_container_border_width(GTK_CONTAINER(stat_hbox), 0);
@ -1631,4 +1665,3 @@ create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
gtk_widget_show(top_level);
}

View File

@ -3,7 +3,7 @@
*
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
*
* $Id: packet_win.c,v 1.18 2001/02/11 09:28:17 guy Exp $
* $Id: packet_win.c,v 1.19 2001/03/23 14:44:04 jfoster Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -77,7 +77,7 @@ struct PacketWinData {
GtkWidget *tv_scrollw;
GtkWidget *tree_view;
GtkWidget *bv_scrollw;
GtkWidget *byte_view;
GtkWidget *bv_nb_ptr;
field_info *finfo_selected;
epan_dissect_t *edt;
};
@ -132,9 +132,12 @@ static void
create_new_window ( char *Title, gint tv_size, gint bv_size){
GtkWidget *main_w, *main_vbox, *pane,
*tree_view, *byte_view, *tv_scrollw,
*bv_scrollw;
*tree_view, *tv_scrollw,
*bv_scrollw,
*bv_nb_ptr;
struct PacketWinData *DataPtr;
int i;
tvbuff_t* bv_tvb;
main_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
@ -159,7 +162,7 @@ create_new_window ( char *Title, gint tv_size, gint bv_size){
gtk_widget_show(tree_view);
/* Byte view */
create_byte_view(bv_size, pane, &byte_view, &bv_scrollw,
create_byte_view(bv_size, pane, &bv_nb_ptr, &bv_scrollw,
prefs.gui_scrollbar_on_right);
/* Allocate data structure to represent this window. */
@ -177,7 +180,7 @@ create_new_window ( char *Title, gint tv_size, gint bv_size){
DataPtr->main = main_w;
DataPtr->tv_scrollw = tv_scrollw;
DataPtr->tree_view = tree_view;
DataPtr->byte_view = byte_view;
DataPtr->bv_nb_ptr = bv_nb_ptr;
DataPtr->bv_scrollw = bv_scrollw;
detail_windows = g_list_append(detail_windows, DataPtr);
@ -193,8 +196,14 @@ create_new_window ( char *Title, gint tv_size, gint bv_size){
/* draw the protocol tree & print hex data */
proto_tree_draw(DataPtr->protocol_tree, tree_view);
packet_hex_print(GTK_TEXT(byte_view), DataPtr->pd, DataPtr->frame, NULL);
i=0; /* do all the hex views */
while((bv_tvb = g_slist_nth_data ( DataPtr->frame->data_src, i++))){
add_byte_tab( DataPtr->bv_nb_ptr, tvb_get_name( bv_tvb),
tvb_get_ptr(bv_tvb, 0, -1), tvb_length(bv_tvb));
}
DataPtr->finfo_selected = NULL;
gtk_widget_show(main_w);
}
@ -218,6 +227,9 @@ new_tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column,
/* called when a tree row is selected in the popup packet window */
field_info *finfo;
GtkWidget *byte_view;
guint8 *data;
int len, i;
struct PacketWinData *DataPtr = (struct PacketWinData*)user_data;
@ -225,10 +237,20 @@ new_tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column,
finfo = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
if (!finfo) return;
DataPtr->finfo_selected = finfo;
i = find_notebook_page( DataPtr->bv_nb_ptr, finfo->ds_name);
set_notebook_page ( DataPtr->bv_nb_ptr, i);
len = get_byte_view_and_data( DataPtr->bv_nb_ptr, &byte_view, &data);
packet_hex_print(GTK_TEXT(DataPtr->byte_view), DataPtr->pd,
DataPtr->frame, finfo);
if ( !byte_view) /* exit it no hex window to write in */
return;
if ( len < 0){
data = DataPtr->pd;
len = DataPtr->frame->cap_len;
}
DataPtr->finfo_selected = finfo;
packet_hex_print(GTK_TEXT(byte_view), data,
DataPtr->frame, finfo, len);
}
@ -238,13 +260,22 @@ new_tree_view_unselect_row_cb(GtkCTree *ctree, GList *node, gint column,
/* called when a tree row is unselected in the popup packet window */
guint8* data;
int len;
GtkWidget* byte_view;
struct PacketWinData *DataPtr = (struct PacketWinData*)user_data;
DataPtr->finfo_selected = NULL;
packet_hex_print(GTK_TEXT(DataPtr->byte_view), DataPtr->pd,
DataPtr->frame, NULL);
len = get_byte_view_and_data( DataPtr->bv_nb_ptr, &byte_view, &data);
if ( !byte_view) /* exit it no hex window to write in */
return;
g_assert( len >= 0);
packet_hex_reprint(GTK_TEXT(byte_view));
}
/* Functions called from elsewhere to act on all popup packet windows. */
@ -271,8 +302,7 @@ redraw_hex_dump_cb(gpointer data, gpointer user_data)
{
struct PacketWinData *DataPtr = (struct PacketWinData *)data;
redraw_hex_dump(DataPtr->byte_view, DataPtr->pd,
DataPtr->frame, DataPtr->finfo_selected);
redraw_hex_dump(DataPtr->bv_nb_ptr, DataPtr->frame, DataPtr->finfo_selected);
}
/* Redraw the hex dump part of all the popup packet windows. */

View File

@ -1,12 +1,14 @@
/* proto_draw.c
* Routines for GTK+ packet display
*
* $Id: proto_draw.c,v 1.28 2001/03/07 19:33:24 gram Exp $
* $Id: proto_draw.c,v 1.29 2001/03/23 14:44:04 jfoster Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* Copyright 1998 Gerald Combs
*
* Jeff Foster, 2001/03/12, added support for displaying named
* data sources as tabbed hex windows
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -56,32 +58,115 @@
#define BYTE_VIEW_WIDTH 16
#define BYTE_VIEW_SEP 8
GtkWidget *byte_nb_ptr;
static void
proto_tree_draw_node(GNode *node, gpointer data);
GtkWidget*
get_notebook_bv_ptr( GtkWidget *nb_ptr){
/* Get the current text window for the notebook */
return gtk_object_get_data(GTK_OBJECT(nb_ptr), E_BYTE_VIEW_TEXT_INFO_KEY);
}
int get_byte_view_data( GtkWidget *byte_view_notebook, guint8 **data_ptr) {
/* get the data pointer and data length for a hex window */
/* return the length of the data or -1 on error */
GtkWidget *byte_view = get_notebook_bv_ptr( byte_view_notebook);
if ( !byte_view)
return -1;
if ((*data_ptr = gtk_object_get_data(GTK_OBJECT(byte_view), E_BYTE_VIEW_DATA_PTR_KEY)))
return GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(byte_view),
E_BYTE_VIEW_DATA_LEN_KEY));
return -1;
}
int get_byte_view_and_data( GtkWidget *byte_view_notebook, GtkWidget **byte_view, guint8 **data_ptr) {
/* Get both byte_view widget pointer and the data pointer */
/* return the data length or -1 if error */
*byte_view = get_notebook_bv_ptr( byte_view_notebook);
if ( *byte_view)
return get_byte_view_data( byte_view_notebook, data_ptr);
return -1;
}
void
set_notebook_page( GtkWidget *nb_ptr, int num){
/* Set the current text window for the notebook and set the */
/* text window pointer storage */
GtkWidget* child;
gtk_notebook_set_page ( GTK_NOTEBOOK( nb_ptr), num);
child = gtk_notebook_get_nth_page( GTK_NOTEBOOK(nb_ptr), num);
child = gtk_object_get_data(GTK_OBJECT(child), E_BYTE_VIEW_TEXT_INFO_KEY);
gtk_object_set_data(GTK_OBJECT(nb_ptr), E_BYTE_VIEW_TEXT_INFO_KEY, child);
}
int find_notebook_page( GtkWidget *nb_ptr, gchar *label){
/* find the notebook page number for this label */
int i = -1;
gchar *ptr;
GtkWidget* child;
while(( child = gtk_notebook_get_nth_page(GTK_NOTEBOOK(nb_ptr), ++i))){
child = gtk_notebook_get_tab_label(GTK_NOTEBOOK(nb_ptr), child);
gtk_notebook_get_tab_label(GTK_NOTEBOOK(nb_ptr), child);
gtk_label_get(GTK_LABEL(child), &ptr);
if (!strcmp( label, ptr))
return i;
}
return -1;
}
/* Redraw a given byte view window. */
void
redraw_hex_dump(GtkWidget *bv, guint8 *pd, frame_data *fd, field_info *finfo)
redraw_hex_dump(GtkWidget *nb, frame_data *fd, field_info *finfo)
{
packet_hex_print(GTK_TEXT(bv), pd, fd, finfo);
GtkWidget* bv;
guint8* data;
int len;
len = get_byte_view_and_data( byte_nb_ptr, &bv, &data);
if ( bv)
packet_hex_print(GTK_TEXT(bv), data, fd, finfo, len);
}
void
redraw_hex_dump_all(void)
{
if (cfile.current_frame != NULL)
redraw_hex_dump(byte_view, cfile.pd, cfile.current_frame, finfo_selected);
redraw_hex_dump( byte_nb_ptr, cfile.current_frame, finfo_selected);
redraw_hex_dump_packet_wins();
}
static void
expand_tree(GtkCTree *ctree, GtkCTreeNode *node, gpointer user_data)
{
field_info *finfo;
gboolean *val;
finfo = gtk_ctree_node_get_row_data( ctree, node );
finfo = gtk_ctree_node_get_row_data( ctree, node);
g_assert(finfo);
val = &tree_is_expanded[finfo->tree_type];
@ -94,7 +179,7 @@ collapse_tree(GtkCTree *ctree, GtkCTreeNode *node, gpointer user_data)
field_info *finfo;
gboolean *val;
finfo = gtk_ctree_node_get_row_data( ctree, node );
finfo = gtk_ctree_node_get_row_data( ctree, node);
g_assert(finfo);
val = &tree_is_expanded[finfo->tree_type];
@ -122,6 +207,7 @@ byte_view_select(GtkWidget *widget, GdkEventButton *event, gpointer data)
GtkText *bv = GTK_TEXT(widget);
int row, column;
int byte;
gchar *name;
/* The column of the first hex digit in the first half */
const int digits_start_1 = 6;
@ -181,9 +267,11 @@ byte_view_select(GtkWidget *widget, GdkEventButton *event, gpointer data)
/* Add the number of bytes from the previous rows. */
byte += row * 16;
/* Get the data source name */
name = gtk_object_get_data(GTK_OBJECT(widget), E_BYTE_VIEW_NAME_KEY);
/* Find the finfo that corresponds to our byte. */
finfo = proto_find_field_from_offset(cfile.protocol_tree, byte);
finfo = proto_find_field_from_offset(cfile.protocol_tree, byte, name);
if (!finfo) {
return FALSE;
@ -239,14 +327,50 @@ byte_view_button_press_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
return FALSE;
}
void
create_byte_view(gint bv_size, GtkWidget *pane, GtkWidget **byte_view_p,
create_byte_view(gint bv_size, GtkWidget *pane, GtkWidget **byte_nb_p,
GtkWidget **bv_scrollw_p, int pos)
{
GtkWidget *byte_view, *byte_scrollw;
GtkWidget *byte_scrollw, *byte_nb;
byte_nb = gtk_notebook_new();
gtk_notebook_set_tab_pos ( GTK_NOTEBOOK(byte_nb), GTK_POS_BOTTOM);
gtk_paned_pack2(GTK_PANED(pane), byte_nb, FALSE, FALSE);
gtk_widget_show(byte_nb);
/* Byte view. Create a scrolled window for the text. */
byte_scrollw = gtk_scrolled_window_new(NULL, NULL);
*byte_nb_p = byte_nb;
*bv_scrollw_p = byte_scrollw;
}
void
byte_view_realize_cb( GtkWidget *bv, gpointer data){
guint8* byte_data = gtk_object_get_data(GTK_OBJECT(bv), E_BYTE_VIEW_DATA_PTR_KEY);
int byte_len = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(bv), E_BYTE_VIEW_DATA_LEN_KEY));
packet_hex_print(GTK_TEXT(bv), byte_data, cfile.current_frame, NULL, byte_len);
}
GtkWidget *add_byte_tab( GtkWidget *byte_nb, const char *name, const guint8 *data, int len)
{
GtkWidget *byte_view, *byte_scrollw, *label;
gchar *name_ptr;
/* Byte view. Create a scrolled window for the text. */
byte_scrollw = gtk_scrolled_window_new(NULL, NULL);
/* Add scrolled pane to tabbed window */
label = gtk_label_new (name);
gtk_notebook_append_page (GTK_NOTEBOOK(byte_nb), byte_scrollw, label);
/* Byte view. Create a scrolled window for the text. */
gtk_paned_pack2(GTK_PANED(pane), byte_scrollw, FALSE, FALSE);
gtk_widget_set_usize(byte_scrollw, -1, bv_size);
@ -257,7 +381,7 @@ create_byte_view(gint bv_size, GtkWidget *pane, GtkWidget **byte_view_p,
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(byte_scrollw),
/* Horizontal */GTK_POLICY_NEVER,
/* Vertical*/ GTK_POLICY_ALWAYS);
set_scrollbar_placement_scrollw(byte_scrollw, pos);
set_scrollbar_placement_scrollw(byte_scrollw, prefs.gui_scrollbar_on_right);
remember_scrolled_window(byte_scrollw);
gtk_widget_show(byte_scrollw);
@ -265,36 +389,50 @@ create_byte_view(gint bv_size, GtkWidget *pane, GtkWidget **byte_view_p,
gtk_text_set_editable(GTK_TEXT(byte_view), FALSE);
gtk_text_set_word_wrap(GTK_TEXT(byte_view), FALSE);
gtk_text_set_line_wrap(GTK_TEXT(byte_view), FALSE);
gtk_object_set_data(GTK_OBJECT(byte_view), E_BYTE_VIEW_DATA_PTR_KEY, data);
gtk_object_set_data(GTK_OBJECT(byte_view), E_BYTE_VIEW_DATA_LEN_KEY, GINT_TO_POINTER(len));
gtk_label_get(GTK_LABEL(label), &name_ptr);
gtk_object_set_data(GTK_OBJECT(byte_view), E_BYTE_VIEW_NAME_KEY, name_ptr);
gtk_container_add(GTK_CONTAINER(byte_scrollw), byte_view);
gtk_widget_show(byte_view);
gtk_signal_connect(GTK_OBJECT(byte_view), "show",
GTK_SIGNAL_FUNC(byte_view_realize_cb), NULL);
gtk_signal_connect(GTK_OBJECT(byte_view), "button_press_event",
GTK_SIGNAL_FUNC(byte_view_button_press_cb),
gtk_object_get_data(GTK_OBJECT(popup_menu_object), PM_HEXDUMP_KEY));
gtk_widget_show(byte_view);
*byte_view_p = byte_view;
*bv_scrollw_p = byte_scrollw;
gtk_object_set_data(GTK_OBJECT(byte_scrollw), E_BYTE_VIEW_TEXT_INFO_KEY,
byte_view);
/* no tabs if this is the first page */
if ( !(gtk_notebook_page_num(GTK_NOTEBOOK(byte_nb), byte_scrollw)))
gtk_notebook_set_show_tabs ( GTK_NOTEBOOK(byte_nb), FALSE);
else
gtk_notebook_set_show_tabs ( GTK_NOTEBOOK(byte_nb), TRUE);
return byte_view;
}
int add_byte_view(const char *name, const guint8 *data, int len){
add_byte_tab( byte_nb_ptr, name, data,len);
return 0;
}
void
packet_hex_print(GtkText *bv, guint8 *pd, frame_data *fd, field_info *finfo)
packet_hex_print_common(GtkText *bv, guint8 *pd, int len, int bstart, int bend, int encoding)
{
gint i = 0, j, k, cur;
guchar line[128], hexchars[] = "0123456789abcdef", c = '\0';
GdkFont *cur_font, *new_font;
gint bstart, blen;
gint bend = -1;
GdkColor *fg, *bg;
gboolean reverse, newreverse;
if (finfo != NULL) {
bstart = finfo->start;
blen = finfo->length;
} else {
bstart = -1;
blen = -1;
}
/* Freeze the text for faster display */
gtk_text_freeze(bv);
@ -307,11 +445,7 @@ packet_hex_print(GtkText *bv, guint8 *pd, frame_data *fd, field_info *finfo)
gtk_adjustment_set_value(bv->vadj, 0.0);
gtk_text_forward_delete(bv, gtk_text_get_length(bv));
if (bstart >= 0 && blen >= 0) {
bend = bstart + blen;
}
while (i < fd->cap_len) {
while (i < len) {
/* Print the line number */
sprintf(line, "%04x ", i);
@ -327,7 +461,7 @@ packet_hex_print(GtkText *bv, guint8 *pd, frame_data *fd, field_info *finfo)
cur = 0;
/* Print the hex bit */
while (i < k) {
if (i < fd->cap_len) {
if (i < len) {
line[cur++] = hexchars[(pd[i] & 0xf0) >> 4];
line[cur++] = hexchars[pd[i] & 0x0f];
} else {
@ -374,11 +508,11 @@ packet_hex_print(GtkText *bv, guint8 *pd, frame_data *fd, field_info *finfo)
fg = reverse ? &WHITE : &BLACK;
bg = reverse ? &BLACK : &WHITE;
while (i < k) {
if (i < fd->cap_len) {
if (fd->flags.encoding == CHAR_ASCII) {
if (i < len) {
if (encoding == CHAR_ASCII) {
c = pd[i];
}
else if (fd->flags.encoding == CHAR_EBCDIC) {
else if (encoding == CHAR_EBCDIC) {
c = EBCDIC_to_ASCII1(pd[i]);
}
else {
@ -428,7 +562,7 @@ packet_hex_print(GtkText *bv, guint8 *pd, frame_data *fd, field_info *finfo)
cur = 0;
/* Print the hex bit */
while (i < k) {
if (i < fd->cap_len) {
if (i < len) {
line[cur++] = hexchars[(pd[i] & 0xf0) >> 4];
line[cur++] = hexchars[pd[i] & 0x0f];
} else {
@ -454,11 +588,11 @@ packet_hex_print(GtkText *bv, guint8 *pd, frame_data *fd, field_info *finfo)
/* Print the ASCII bit */
cur_font = (i >= bstart && i < bend) ? m_b_font : m_r_font;
while (i < k) {
if (i < fd->cap_len) {
if (fd->flags.encoding == CHAR_ASCII) {
if (i < len) {
if (encoding == CHAR_ASCII) {
c = pd[i];
}
else if (fd->flags.encoding == CHAR_EBCDIC) {
else if (encoding == CHAR_EBCDIC) {
c = EBCDIC_to_ASCII1(pd[i]);
}
else {
@ -488,17 +622,66 @@ packet_hex_print(GtkText *bv, guint8 *pd, frame_data *fd, field_info *finfo)
/* scroll text into position */
gtk_text_thaw(bv); /* must thaw before adjusting scroll bars */
if ( bstart > 0 ) {
int linenum;
int lineheight, linenum;
float scrollval;
linenum = bstart / BYTE_VIEW_WIDTH;
scrollval = MIN(linenum * m_font_height,
bv->vadj->upper - bv->vadj->page_size);
/* This is the lineheight that the GtkText widget uses when drawing text. */
lineheight = m_b_font->ascent + m_b_font->descent;
scrollval = MIN(linenum * lineheight,bv->vadj->upper - bv->vadj->page_size);
gtk_adjustment_set_value(bv->vadj, scrollval);
}
}
void
packet_hex_print(GtkText *bv, guint8 *pd, frame_data *fd, field_info *finfo, int len){
/* do the initial printing and save the information needed */
/* to redraw the display if preferences change. */
int bstart, bend = -1, blen;
if (finfo != NULL) {
bstart = finfo->start;
blen = finfo->length;
} else {
bstart = -1;
blen = -1;
}
if (bstart >= 0 && blen >= 0) {
bend = bstart + blen;
}
/* save the information needed to redraw the text */
/* should we save the fd & finfo pointers instead ?? */
gtk_object_set_data(GTK_OBJECT(bv), E_BYTE_VIEW_START_KEY, GINT_TO_POINTER(bend));
gtk_object_set_data(GTK_OBJECT(bv), E_BYTE_VIEW_END_KEY, GINT_TO_POINTER(bstart));
gtk_object_set_data(GTK_OBJECT(bv), E_BYTE_VIEW_ENCODE_KEY, GINT_TO_POINTER(fd->flags.encoding));
packet_hex_print_common( bv, pd, len, bstart, bend, fd->flags.encoding);
}
void
packet_hex_reprint(GtkText *bv){
/* redraw the text using the saved information, */
/* usually called if the preferences haved changed. */
int start, end, len, encoding;
guint8 *data;
start = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(bv), E_BYTE_VIEW_START_KEY));
end = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(bv), E_BYTE_VIEW_END_KEY));
len = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(bv), E_BYTE_VIEW_DATA_LEN_KEY));
data = gtk_object_get_data(GTK_OBJECT(bv), E_BYTE_VIEW_DATA_PTR_KEY);
encoding = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(bv), E_BYTE_VIEW_ENCODE_KEY));
packet_hex_print_common( bv, data, len, start, end, encoding);
}
/* List of all protocol tree widgets, so we can globally set the selection
mode, line style, expander style, and font of all of them. */
static GList *ptree_widgets;
@ -635,7 +818,7 @@ create_tree_view(gint tv_size, e_prefs *prefs, GtkWidget *pane,
/* Tree view */
tv_scrollw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(tv_scrollw),
GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
set_scrollbar_placement_scrollw(tv_scrollw, pos);
remember_scrolled_window(tv_scrollw);
gtk_paned_pack1(GTK_PANED(pane), tv_scrollw, TRUE, TRUE);
@ -714,9 +897,13 @@ proto_tree_draw_node(GNode *node, gpointer data)
gchar *label_ptr;
GtkCTreeNode *parent;
gboolean is_leaf, is_expanded;
int i;
if (!fi->visible)
return;
i= find_notebook_page( byte_nb_ptr, fi->ds_name);
if ( i < 0) return; /* no notebook pages ?? */
set_notebook_page( byte_nb_ptr, i);
/* was a free format label produced? */
if (fi->representation) {

View File

@ -1,7 +1,7 @@
/* gtkpacket.h
* Definitions for GTK+ packet display structures and routines
*
* $Id: proto_draw.h,v 1.10 2000/09/09 10:26:58 guy Exp $
* $Id: proto_draw.h,v 1.11 2001/03/23 14:44:04 jfoster Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -26,15 +26,32 @@
#ifndef __GTKPACKET_H__
#define __GTKPACKET_H__
#define E_BYTE_VIEW_TEXT_INFO_KEY "byte_view_win"
#define E_BYTE_VIEW_DATA_PTR_KEY "byte_view_data"
#define E_BYTE_VIEW_DATA_LEN_KEY "byte_view_len"
#define E_BYTE_VIEW_START_KEY "byte_view_start"
#define E_BYTE_VIEW_END_KEY "byte_view_end"
#define E_BYTE_VIEW_ENCODE_KEY "byte_view_encode"
#define E_BYTE_VIEW_NAME_KEY "byte_view_name"
GtkWidget *add_byte_tab( GtkWidget *byte_nb, const char *name, const guint8 *data, int len);
int add_byte_view( const char *name, const guint8 *data, int len);
void set_notebook_page( GtkWidget *nb_ptr, int num);
int find_notebook_page( GtkWidget *nb_ptr, gchar *label);
GtkWidget *get_byte_view( GtkWidget *byte_view_notebook);
int get_byte_view_data( GtkWidget *byte_view_notebook, guint8 **data_ptr);
int get_byte_view_and_data( GtkWidget *byte_view_notebook, GtkWidget **byte_view, guint8 **data_ptr);
void redraw_hex_dump(GtkWidget *nb, frame_data *fd, field_info *finfo);
void redraw_hex_dump(GtkWidget *bv, guint8 *pd, frame_data *fd,
field_info *finfo);
void redraw_hex_dump_all(void);
void create_byte_view(gint bv_size, GtkWidget *pane, GtkWidget **byte_view_p,
GtkWidget **bv_scrollw_p, int pos);
void packet_hex_print(GtkText *, guint8 *, frame_data *, field_info *);
#define E_TREEINFO_FIELD_INFO_KEY "tree_info_finfo"
void packet_hex_print(GtkText *, guint8 *, frame_data *, field_info *, int);
void packet_hex_reprint(GtkText *);
void create_tree_view(gint tv_size, e_prefs *prefs, GtkWidget *pane,
GtkWidget **tv_scrollw_p, GtkWidget **tree_view_p, int pos);