Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Ethereal-dev: Re: [Ethereal-dev] VJ compressed PPP packets ??

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Guy Harris <gharris@xxxxxxxxxxxx>
Date: Thu, 15 Mar 2001 23:05:11 -0800
On Thu, Mar 15, 2001 at 02:41:48PM -0600, Jeff Foster wrote:
> This is a repost to send a new diff file because the
> last one was corrupted by my edit :-( 
> 
> 
> Attached is the is diff files for the changes I made to
> impliment named data sources.

> Index: file.c
> ===================================================================
> RCS file: /cvsroot/ethereal/file.c,v
> retrieving revision 1.232
> diff -u -r1.232 file.c
> --- file.c	2001/02/11 09:28:15	1.232
> +++ file.c	2001/03/15 20:30:06
> @@ -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.227 2000/11/21 23:54:08 guy Exp $
>   *
>   * Ethereal - Network traffic analyzer
>   * By Gerald Combs <gerald@xxxxxxxx>

There are some other patches that revert the RCS ID, and at least some
of them back out changes made between the reverted-to and current RCS
versions.  One of them, the patch to "gtk/main.h", *only* reverts the
RCS ID - it doesn't actually change anything else in "gtk/main.h".

> There are small changes
> to some of the files in epan to support the addition
> of a name to the tvbuffer.  The majority of the changes
> are to the GUI code.

There's also a change:

> diff -u -r1.23 packet.h
> --- packet.h	2001/03/15 06:41:13	1.23
> +++ packet.h	2001/03/15 20:30:08
> @@ -100,6 +100,7 @@
>    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 @@
>    AT_ATALK,		/* Appletalk DDP */
>    AT_VINES,		/* Banyan Vines */
>    AT_OSI,		/* OSI NSAP */
> +  AT_DLCI               /* Frame Relay DLCI */
>  } address_type;

which I assume is part of an unrelated change to put Frame Relay DLCIs
in the address columns of the summary and/or to make them available to
dissectors above the FR dissector.

> Currently this code doesn't add named data support to
> tethereal. That shouldn't be a problem until we actually
> have a dissector that uses named data. Then tethereal 
> will only display the received frame and not the extra
> data sources created by dissectors.

We probably want to do what's done for the hex view notebook - if
there's only one data source, print it the way we do now, and, if
there's more than one data source, print each one, with the name as a
tag.

Note that the code that prints the hex data for "tethereal -x" is the
same as the code that prints the hex data if you select "Print hex data"
in the "Print" dialog box in Ethereal, so there's also currently no
named data support when printing a packet to a printer or a file in
Ethereal.

I've attached a patch that fixes the RCS IDs and puts back some changes
that got reverted by your patch; this patch should be applied to the
result of applying your patch to the current CVS tree.  It also changes
"gtk/gtkglobals.h" not to declare the now-dead "byte_view" global, and
to declare the new "byte_nb_ptr" global instead, to get rid of the extra
definition of "byte_nb_ptr" in "gtk/proto_draw.c" (it's already defined
in "gtk/main.c" and, with the change to "gtk/gtkglobals.h", declared
there), and to fix a couple of comments in "gtk/packet_win.c".

That's "patch-fixup"; I've also attached "patch-datasource", which is
the result of a "cvs diff -u" on the tree resulting from both patches
piped through "cvsdiff-fix" (so it can be applied with "patch -p0"), and
which will convert the current CVS tree, unmodified, to a tree with your
patche plus "patch-fixup".
*** file.c.dist	Thu Mar 15 21:47:27 2001
--- file.c	Thu Mar 15 21:56:51 2001
***************
*** 1,7 ****
  /* file.c
   * File I/O routines
   *
!  * $Id: file.c,v 1.227 2000/11/21 23:54:08 guy Exp $
   *
   * Ethereal - Network traffic analyzer
   * By Gerald Combs <gerald@xxxxxxxx>
--- 1,7 ----
  /* file.c
   * File I/O routines
   *
!  * $Id: file.c,v 1.232 2001/02/11 09:28:15 guy Exp $
   *
   * Ethereal - Network traffic analyzer
   * By Gerald Combs <gerald@xxxxxxxx>
***************
*** 88,95 ****
  #include "conversation.h"
  #include "globals.h"
  #include "gtk/colors.h"
- 
- #include "plugins.h"
  
  extern GtkWidget *packet_list, *info_bar, *byte_nb_ptr, *tree_view;
  extern guint      file_ctx;
--- 88,93 ----
*** gtk/gtkglobals.h.dist	Sat Mar  3 16:26:01 2001
--- gtk/gtkglobals.h	Thu Mar 15 22:50:11 2001
***************
*** 31,37 ****
  #endif
  
  extern GtkWidget   *top_level, *packet_list, *tree_view,
!             *byte_view, *info_bar;
  extern GdkFont     *m_r_font, *m_b_font;
  extern guint m_font_height, m_font_width;
  
--- 31,37 ----
  #endif
  
  extern GtkWidget   *top_level, *packet_list, *tree_view,
!             *byte_nb_ptr, *info_bar;
  extern GdkFont     *m_r_font, *m_b_font;
  extern guint m_font_height, m_font_width;
  
*** gtk/main.c.dist	Thu Mar 15 21:47:28 2001
--- gtk/main.c	Thu Mar 15 22:37:03 2001
***************
*** 1,6 ****
  /* main.c
   *
!  * $Id: main.c,v 1.171 2001/01/10 10:11:27 guy Exp $
   *
   * Ethereal - Network traffic analyzer
   * By Gerald Combs <gerald@xxxxxxxxxxxx>
--- 1,6 ----
  /* main.c
   *
!  * $Id: main.c,v 1.182 2001/03/02 23:10:12 gram Exp $
   *
   * Ethereal - Network traffic analyzer
   * By Gerald Combs <gerald@xxxxxxxxxxxx>
*** gtk/packet_win.c.dist	Thu Mar 15 21:47:28 2001
--- gtk/packet_win.c	Thu Mar 15 22:00:36 2001
***************
*** 3,9 ****
   *
   * Copyright 2000, Jeffrey C. Foster <jfoste@xxxxxxxxxxxx>
   *
!  * $Id: packet_win.c,v 1.16 2000/10/06 10:11:40 gram Exp $
   *
   * Ethereal - Network traffic analyzer
   * By Gerald Combs <gerald@xxxxxxxx>
--- 3,9 ----
   *
   * Copyright 2000, Jeffrey C. Foster <jfoste@xxxxxxxxxxxx>
   *
!  * $Id: packet_win.c,v 1.18 2001/02/11 09:28:17 guy Exp $
   *
   * Ethereal - Network traffic analyzer
   * By Gerald Combs <gerald@xxxxxxxx>
***************
*** 50,56 ****
  #include "main.h"
  #include "timestamp.h"
  #include "packet.h"
- #include "capture.h"
  #include "summary.h"
  #include "file.h"
  #include "menu.h"
--- 50,55 ----
***************
*** 64,70 ****
  #include "simple_dialog.h"
  #include "ui_util.h"
  #include "proto_draw.h"
- #include "dfilter/dfilter.h"
  #include "keys.h"
  #include "gtkglobals.h"
  #include "plugins.h"
--- 63,68 ----
***************
*** 245,251 ****
          set_notebook_page ( DataPtr->bv_nb_ptr, i);
          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;
          if ( len < 0){
                  data = DataPtr->pd;
--- 243,249 ----
          set_notebook_page ( DataPtr->bv_nb_ptr, i);
          len = get_byte_view_and_data( DataPtr->bv_nb_ptr, &byte_view, &data);
  
! 	if ( !byte_view)	/* exit if no hex window to write in */
  		return;
          if ( len < 0){
                  data = DataPtr->pd;
***************
*** 274,280 ****
  
          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);
--- 272,278 ----
  
          len = get_byte_view_and_data( DataPtr->bv_nb_ptr, &byte_view, &data);
  
! 	if ( !byte_view)	/* exit if no hex window to write in */
  		return;
  
  	g_assert( len >= 0);
*** gtk/proto_draw.c.dist	Thu Mar 15 21:47:28 2001
--- gtk/proto_draw.c	Thu Mar 15 22:51:22 2001
***************
*** 1,7 ****
  /* proto_draw.c
   * Routines for GTK+ packet display
   *
!  * $Id: proto_draw.c,v 1.25 2001/01/11 05:51:10 gram Exp $
   *
   * Ethereal - Network traffic analyzer
   * By Gerald Combs <gerald@xxxxxxxx>
--- 1,7 ----
  /* proto_draw.c
   * Routines for GTK+ packet display
   *
!  * $Id: proto_draw.c,v 1.28 2001/03/07 19:33:24 gram Exp $
   *
   * Ethereal - Network traffic analyzer
   * By Gerald Combs <gerald@xxxxxxxx>
***************
*** 58,66 ****
  #define BYTE_VIEW_WIDTH    16
  #define BYTE_VIEW_SEP      8
  
- 
- GtkWidget *byte_nb_ptr;
- 
  static void
  proto_tree_draw_node(GNode *node, gpointer data);
  
--- 58,63 ----
***************
*** 101,106 ****
--- 98,104 ----
  }
  
  
+ 	
  void
  set_notebook_page(  GtkWidget *nb_ptr, int num){
  
***************
*** 159,164 ****
--- 157,163 ----
    redraw_hex_dump_packet_wins();
  }
  
+ 
  static void
  expand_tree(GtkCTree *ctree, GtkCTreeNode *node, gpointer user_data)
  {
***************
*** 369,377 ****
    label = gtk_label_new (name);
    gtk_notebook_append_page (GTK_NOTEBOOK(byte_nb), byte_scrollw, label);
  
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(byte_scrollw),
! 					GTK_POLICY_NEVER,
! 					GTK_POLICY_ALWAYS);
    set_scrollbar_placement_scrollw(byte_scrollw,  prefs.gui_scrollbar_on_right);
    remember_scrolled_window(byte_scrollw);
    gtk_widget_show(byte_scrollw);
--- 368,381 ----
    label = gtk_label_new (name);
    gtk_notebook_append_page (GTK_NOTEBOOK(byte_nb), byte_scrollw, label);
  
+ 
+   /* The horizontal scrollbar of the scroll-window doesn't seem
+    * to affect the GtkText widget at all, even when line wrapping
+    * is turned off in the GtkText widget and there is indeed more
+    * horizontal data. */
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(byte_scrollw),
! 			/* Horizontal */GTK_POLICY_NEVER,
! 			/* Vertical*/	GTK_POLICY_ALWAYS);
    set_scrollbar_placement_scrollw(byte_scrollw,  prefs.gui_scrollbar_on_right);
    remember_scrolled_window(byte_scrollw);
    gtk_widget_show(byte_scrollw);
***************
*** 379,385 ****
    byte_view = gtk_text_new(NULL, NULL);
    gtk_text_set_editable(GTK_TEXT(byte_view), FALSE);
    gtk_text_set_word_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);
--- 383,391 ----
    byte_view = gtk_text_new(NULL, NULL);
    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,
! 		      (gpointer)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);
***************
*** 656,668 ****
    /* scroll text into position */
    gtk_text_thaw(bv); /* must thaw before adjusting scroll bars */
    if ( bstart > 0 ) {
!     int lineheight, linenum;
      float scrollval;
  
      linenum = bstart / BYTE_VIEW_WIDTH;
!     /* 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);
    }
--- 662,673 ----
    /* scroll text into position */
    gtk_text_thaw(bv); /* must thaw before adjusting scroll bars */
    if ( bstart > 0 ) {
!     int linenum;
      float scrollval;
  
      linenum = bstart / BYTE_VIEW_WIDTH;
!     scrollval = MIN(linenum * m_font_height,
! 		    bv->vadj->upper - bv->vadj->page_size);
  
      gtk_adjustment_set_value(bv->vadj, scrollval);
    }
***************
*** 804,810 ****
    /* Tree view */
    tv_scrollw = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(tv_scrollw),
!     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);
--- 809,815 ----
    /* 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);
    set_scrollbar_placement_scrollw(tv_scrollw, pos);
    remember_scrolled_window(tv_scrollw);
    gtk_paned_pack1(GTK_PANED(pane), tv_scrollw, TRUE, TRUE);
Index: file.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/file.c,v
retrieving revision 1.232
diff -u -r1.232 file.c
--- file.c	2001/02/11 09:28:15	1.232
+++ file.c	2001/03/16 07:03:53
@@ -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 @@
   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 @@
 	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 @@
 	g_slist_free(fdata->pfd);
       }
       fdata->pfd = NULL;
+      if (fdata->data_src) {
+	g_slist_free(fdata->data_src);
+      }
+      fdata->data_src = NULL;
     }
   }
 
@@ -1364,12 +1373,25 @@
 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 +1538,8 @@
 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 +1593,15 @@
 
   /* 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);
Index: tethereal.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/tethereal.c,v
retrieving revision 1.68
diff -u -r1.68 tethereal.c
--- tethereal.c	2001/02/18 03:38:42	1.68
+++ tethereal.c	2001/03/16 07:03:58
@@ -874,6 +874,7 @@
   fdata->next = NULL;
   fdata->prev = NULL;
   fdata->pfd = NULL;
+  fdata->data_src = NULL;
   fdata->num = cf->count;
   fdata->pkt_len = phdr->len;
   fdata->cap_len = phdr->caplen;
Index: epan/epan.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/epan/epan.c,v
retrieving revision 1.6
diff -u -r1.6 epan/epan.c
--- epan/epan.c	2001/02/01 20:21:16	1.6
+++ epan/epan.c	2001/03/16 07:03:58
@@ -77,6 +77,11 @@
 
 	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;
 
Index: epan/packet.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/epan/packet.c,v
retrieving revision 1.21
diff -u -r1.21 epan/packet.c
--- epan/packet.c	2001/03/15 06:41:13	1.21
+++ epan/packet.c	2001/03/16 07:04:02
@@ -1073,7 +1073,10 @@
 	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) {
Index: epan/packet.h
===================================================================
RCS file: /usr/local/cvsroot/ethereal/epan/packet.h,v
retrieving revision 1.23
diff -u -r1.23 epan/packet.h
--- epan/packet.h	2001/03/15 06:41:13	1.23
+++ epan/packet.h	2001/03/16 07:04:03
@@ -100,6 +100,7 @@
   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 @@
   AT_ATALK,		/* Appletalk DDP */
   AT_VINES,		/* Banyan Vines */
   AT_OSI,		/* OSI NSAP */
+  AT_DLCI               /* Frame Relay DLCI */
 } address_type;
 
 typedef struct _address {
Index: epan/proto.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/epan/proto.c,v
retrieving revision 1.14
diff -u -r1.14 epan/proto.c
--- epan/proto.c	2001/03/15 22:08:41	1.14
+++ epan/proto.c	2001/03/16 07:04:08
@@ -1460,6 +1460,9 @@
 	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 @@
 
 	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 @@
 typedef struct {
 	guint		offset;
 	field_info	*finfo;
+	gchar 		*name;
 } offset_search_t;
 
 static gboolean
@@ -2604,7 +2616,7 @@
 	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 @@
  * 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);
Index: epan/proto.h
===================================================================
RCS file: /usr/local/cvsroot/ethereal/epan/proto.h,v
retrieving revision 1.8
diff -u -r1.8 epan/proto.h
--- epan/proto.h	2001/03/02 23:10:11	1.8
+++ epan/proto.h	2001/03/16 07:04:09
@@ -121,6 +121,7 @@
 	char				*representation; /* for GUI tree */
 	int				visible;
 	fvalue_t			*value;
+	gchar				*ds_name;  /* data source name */
 } field_info;
 
 
@@ -558,6 +559,6 @@
 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 */
Index: epan/tvbuff.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/epan/tvbuff.c,v
retrieving revision 1.15
diff -u -r1.15 epan/tvbuff.c
--- epan/tvbuff.c	2001/03/13 21:34:27	1.15
+++ epan/tvbuff.c	2001/03/16 07:04:12
@@ -50,7 +50,7 @@
 	/* The offset/length of 'tvb' to which I'm privy */
 	guint		offset;
 	guint		length;
-
+	/* the byte view name length */
 } tvb_backing_t;
 
 typedef struct {
@@ -69,6 +69,7 @@
 	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 @@
 }
 
 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_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_set_subset(tvb, backing, backing_offset, backing_length, reported_length);
 
+	tvb->ds_name = backing->ds_name;
 	CLEANUP_POP;
 
 	return tvb;
@@ -1567,4 +1572,10 @@
 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;
 }
Index: epan/tvbuff.h
===================================================================
RCS file: /usr/local/cvsroot/ethereal/epan/tvbuff.h,v
retrieving revision 1.11
diff -u -r1.11 epan/tvbuff.h
--- epan/tvbuff.h	2001/03/13 21:34:27	1.11
+++ epan/tvbuff.h	2001/03/16 07:04:14
@@ -139,7 +139,7 @@
 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.
@@ -362,6 +362,8 @@
  * to the string with the formatted data.
  */
 gchar *tvb_bytes_to_str(tvbuff_t *tvb, gint offset, gint len);
+
+gchar *tvb_get_name(tvbuff_t *tvb);
 
 /************** END OF ACCESSORS ****************/
 
Index: gtk/gtkglobals.h
===================================================================
RCS file: /usr/local/cvsroot/ethereal/gtk/gtkglobals.h,v
retrieving revision 1.12
diff -u -r1.12 gtk/gtkglobals.h
--- gtk/gtkglobals.h	2001/03/02 23:10:12	1.12
+++ gtk/gtkglobals.h	2001/03/16 07:04:14
@@ -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;
 
Index: gtk/main.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/gtk/main.c,v
retrieving revision 1.182
diff -u -r1.182 gtk/main.c
--- gtk/main.c	2001/03/02 23:10:12	1.182
+++ gtk/main.c	2001/03/16 07:04:18
@@ -8,7 +8,9 @@
  *
  * 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
  * as published by the Free Software Foundation; either version 2
@@ -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 @@
 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 @@
 	  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 @@
   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 @@
   gtk_widget_show(top_level);
 }
 
-	
Index: gtk/packet_win.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/gtk/packet_win.c,v
retrieving revision 1.18
diff -u -r1.18 gtk/packet_win.c
--- gtk/packet_win.c	2001/02/11 09:28:17	1.18
+++ gtk/packet_win.c	2001/03/16 07:04:19
@@ -78,6 +78,7 @@
 	GtkWidget  *tree_view;
  	GtkWidget  *bv_scrollw;
  	GtkWidget  *byte_view;
+	GtkWidget  *bv_nb_ptr;
  	field_info *finfo_selected;
 	epan_dissect_t	*edt;
 };
@@ -132,9 +133,12 @@
 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 +163,7 @@
   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 +181,7 @@
   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 +197,14 @@
 
   /* 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 +228,9 @@
 /* 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 +238,21 @@
 	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 ( GTK_NOTEBOOK(DataPtr->bv_nb_ptr), i);
+        set_notebook_page ( DataPtr->bv_nb_ptr, i);
+        len = get_byte_view_and_data( DataPtr->bv_nb_ptr, &byte_view, &data);
+
+	if ( !byte_view)	/* exit if no hex window to write in */
+		return;
+        if ( len < 0){
+                data = DataPtr->pd;
+                len =  DataPtr->frame->cap_len;
+        }
 
-	packet_hex_print(GTK_TEXT(DataPtr->byte_view), DataPtr->pd,
-		DataPtr->frame, finfo);
+	DataPtr->finfo_selected = finfo;
+	packet_hex_print(GTK_TEXT(byte_view), data,
+		DataPtr->frame, finfo, len);
 
 }
 
@@ -238,13 +262,22 @@
 
 /* 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 if 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 +304,7 @@
 {
 	struct PacketWinData *DataPtr = (struct PacketWinData *)data;
 
-	redraw_hex_dump(DataPtr->byte_view, DataPtr->pd,
-	    DataPtr->frame, DataPtr->finfo_selected);
+	redraw_hex_dump(DataPtr->byte_view, DataPtr->frame, DataPtr->finfo_selected);
 }
 
 /* Redraw the hex dump part of all the popup packet windows. */
Index: gtk/proto_draw.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/gtk/proto_draw.c,v
retrieving revision 1.28
diff -u -r1.28 gtk/proto_draw.c
--- gtk/proto_draw.c	2001/03/07 19:33:24	1.28
+++ gtk/proto_draw.c	2001/03/16 07:04:20
@@ -7,6 +7,8 @@
  * By Gerald Combs <gerald@xxxxxxxx>
  * 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
@@ -59,29 +61,110 @@
 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 +177,7 @@
 	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 +205,7 @@
 	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 +265,11 @@
 	/* 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,17 +325,50 @@
 
 	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_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;
+  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);
-  gtk_paned_pack2(GTK_PANED(pane), byte_scrollw, FALSE, FALSE);
-  gtk_widget_set_usize(byte_scrollw, -1, bv_size);
+  /* Add scrolled pane to tabbed window */
+  label = gtk_label_new (name);
+  gtk_notebook_append_page (GTK_NOTEBOOK(byte_nb), byte_scrollw, label);
 
+
   /* The horizontal scrollbar of the scroll-window doesn't seem
    * to affect the GtkText widget at all, even when line wrapping
    * is turned off in the GtkText widget and there is indeed more
@@ -257,7 +376,7 @@
   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,28 +384,50 @@
   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,
+		      (gpointer)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)
-{
-  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;
+packet_hex_print_common(GtkText *bv, guint8 *pd, int len, int bstart, int bend, int encoding);
+
+void
+packet_hex_print(GtkText *bv, guint8 *pd, frame_data *fd, field_info *finfo, int len){
 
+  int bstart, bend = -1, blen;
+
   if (finfo != NULL) {
     bstart = finfo->start;
     blen = finfo->length;
@@ -294,6 +435,43 @@
     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){
+
+  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);
+}
+
+void
+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;
+  GdkColor *fg, *bg;
+  gboolean reverse, newreverse;
 
   /* Freeze the text for faster display */
   gtk_text_freeze(bv);
@@ -306,12 +484,8 @@
      for more information */
   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 +501,7 @@
       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 +548,11 @@
       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 +602,7 @@
       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 +628,11 @@
       /* 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 {
@@ -714,9 +888,13 @@
 	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) {
Index: gtk/proto_draw.h
===================================================================
RCS file: /usr/local/cvsroot/ethereal/gtk/proto_draw.h,v
retrieving revision 1.10
diff -u -r1.10 gtk/proto_draw.h
--- gtk/proto_draw.h	2000/09/09 10:26:58	1.10
+++ gtk/proto_draw.h	2001/03/16 07:04:21
@@ -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"
 
-void redraw_hex_dump(GtkWidget *bv, guint8 *pd, frame_data *fd,
-    field_info *finfo);
+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_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);