Ethereal-dev: [ethereal-dev] OMG GIOP/IIOP support

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

From: Laurent Deniel <deniel@xxxxxxxxxxx>
Date: Fri, 13 Nov 1998 23:00:44 +0100
 Hi,

 The following is a diff to ethereal 0.4.1 that implements
 OMG CORBA GIOP/IIOP decoding 
 (it should also take in account the include file modifications 
  performed in the current CVS tree).

 Laurent.

--
Laurent DENIEL            | E-mail: deniel@xxxxxxxxxxx
Paris, FRANCE             |         deniel@xxxxxxxxxxxxxxxxxxxxxxxxxxxx
                          | WWW   : http://www.worldnet.fr/~deniel
    All above opinions are personal, unless stated otherwise.
diff -u --recursive --new-file ethereal-0.4.1/AUTHORS ethereal-0.4.1-deniel/AUTHORS
--- ethereal-0.4.1/AUTHORS	Fri Oct 16 03:24:46 1998
+++ ethereal-0.4.1-deniel/AUTHORS	Fri Nov 13 22:38:50 1998
@@ -38,6 +38,7 @@
     Name resolution
     Ethernet/Manufacturer files support
     FDDI support
+    OMG GIOP/IIOP support
     ISO/OSI CLNP/COTP support
     Miscellaneous enhancements and fixes
 }
diff -u --recursive --new-file ethereal-0.4.1/Makefile.in ethereal-0.4.1-deniel/Makefile.in
--- ethereal-0.4.1/Makefile.in	Fri Oct 16 03:25:23 1998
+++ ethereal-0.4.1-deniel/Makefile.in	Fri Nov 13 19:56:38 1998
@@ -93,6 +93,7 @@
 	packet-dns.c   \
 	packet-eth.c   \
 	packet-fddi.c  \
+	packet-giop.c  \
 	packet-llc.c   \
 	packet-lpd.c   \
 	packet-ip.c    \
@@ -174,7 +175,7 @@
 ethereal_OBJECTS =  capture.o ethereal.o ethertype.o file.o filter.o \
 follow.o menu.o packet.o packet-aarp.o packet-arp.o packet-atalk.o \
 packet-bootp.o packet-data.o packet-dns.o packet-eth.o packet-fddi.o \
-packet-llc.o packet-lpd.o packet-ip.o packet-ipv6.o packet-ipx.o \
+packet-giop.o packet-llc.o packet-lpd.o packet-ip.o packet-ipv6.o packet-ipx.o \
 packet-nbipx.o packet-nbns.o packet-ncp.o packet-null.o packet-osi.o \
 packet-ospf.o packet-ppp.o packet-raw.o packet-rip.o packet-tcp.o \
 packet-tr.o packet-trmac.o packet-udp.o packet-vines.o prefs.o print.o \
@@ -437,6 +438,7 @@
 packet-eth.o: packet-eth.c config.h ethereal.h packet.h etypes.h \
 	resolv.h
 packet-fddi.o: packet-fddi.c config.h ethereal.h packet.h resolv.h
+packet-giop.o: packet-giop.c config.h ethereal.h packet.h
 packet-ip.o: packet-ip.c config.h ethereal.h packet.h etypes.h resolv.h
 packet-ipv6.o: packet-ipv6.c config.h ethereal.h packet.h packet-ipv6.h \
 	etypes.h
diff -u --recursive --new-file ethereal-0.4.1/packet-giop.c ethereal-0.4.1-deniel/packet-giop.c
--- ethereal-0.4.1/packet-giop.c	Thu Jan  1 01:00:00 1970
+++ ethereal-0.4.1-deniel/packet-giop.c	Fri Nov 13 22:48:20 1998
@@ -0,0 +1,702 @@
+/* packet-giop.c
+ * Routines for CORBA GIOP/IIOP packet disassembly
+ *
+ * Laurent Deniel <deniel@xxxxxxxxxxx>
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@xxxxxxxx>
+ * Copyright 1998 Gerald Combs
+ *
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gtk/gtk.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include "ethereal.h"
+#include "packet.h"
+
+/*
+ * GIOP / IIOP types definition - OMG CORBA 2.x / GIOP 1.[01]
+ * See OMG WEB site <http://www.omg.org> - CORBA+IIOP 2.2 (98-02-01.ps)
+ *
+ * Notes on mapping:
+ *
+ * <sequence> : unsigned int (# elts) + elements
+ * <string>   : unsigned int (string length) + length characters (with '\0')
+ * <enum>     : unsigned int (from 0 to n)
+ */
+
+#define GIOP_MAGIC 	 "GIOP"
+#define GIOP_MAJOR 	 1
+#define GIOP_MINOR 	 1
+
+#define GIOP_HEADER_SIZE 12
+
+typedef struct OctetSequence{
+  u_int 	sequence_length;
+  u_char  	sequence_data[1];	       	/* of length bytes */
+} OctetSequence;
+
+typedef OctetSequence Principal;
+typedef OctetSequence String;
+
+/* 
+ * Some structures that contain sequences can not be directly used 
+ * (alignment problem on 64 bit architectures)
+ */
+
+typedef struct ServiceContext {
+  u_int		context_id;
+  OctetSequence context_data;
+} ServiceContext;
+
+typedef struct ServiceContextList{
+  u_int 	  nr_context;
+  ServiceContext  service_context[1]; 		/* nr_context elements */
+} ServiceContextList;
+
+typedef enum MsgType {
+  Request,
+  Reply,
+  CancelRequest, 
+  LocateRequest,
+  LocateReply, 
+  CloseConnection,
+  MessageError,
+  Fragment					/* GIOP 1.1 only */
+} MsgType;
+
+typedef struct Version {
+  u_char 	major;
+  u_char 	minor;
+} Version;
+
+typedef struct MessageHeader {
+  char 		magic[4];
+  Version 	GIOP_version;
+  u_char 	flags;				/* byte_order in 1.0 */
+  u_char 	message_type;
+  u_int 	message_size;
+} MessageHeader;
+
+typedef struct RequestHeader_1_0 {
+  /* ServiceContextList service_context;*/
+  u_int 	request_id;
+  u_char 	response_expected;
+  OctetSequence object_key;
+  /* String     operation; 	     	*/
+  /* Principal  requesting_principal; 	*/
+} RequestHeader_1_0;
+
+typedef struct RequestHeader_1_1 {
+  /* ServiceContextList service_context;*/
+  u_int 	request_id;
+  u_char 	response_expected;
+  u_char 	reserved[3];
+  OctetSequence object_key;
+  /* String 	operation; 	     	*/
+  /* Principal  requesting_principal;	*/
+} RequestHeader_1_1;
+
+typedef enum ReplyStatusType {
+  NO_EXCEPTION, 
+  USER_EXCEPTION, 
+  SYSTEM_EXCEPTION, 
+  LOCATION_FORWARD
+} ReplyStatusType;
+
+typedef struct ReplyHeader {
+  /* ServiceContext service_context; 	*/
+  u_int 	request_id;
+  u_int 	reply_status;
+} ReplyHeader;
+
+typedef struct SystemExceptionReplyBody {
+  String 	exception_id; 
+  u_int		minor_code_value;
+  u_int		completion_status;
+} SystemExceptionReplyBody;
+
+typedef struct CancelRequestHeader {
+  u_int		request_id;
+} CancelRequestHeader;
+
+typedef struct LocateRequestHeader {
+  u_int 	request_id;
+  OctetSequence object_key;
+} LocateRequestHeader;
+
+typedef enum LocateStatusType {
+  UNKNOWN_OBJECT, 
+  OBJECT_HERE, 
+  OBJECT_FORWARD
+} LocateStatusType;
+
+typedef struct LocateReplyHeader {
+  u_int 	request_id;
+  u_int 	locate_status;
+} LocateReplyHeader;
+
+
+u_char *print_object_key(int length, u_char *from) 
+{
+#define MAX_OBJECT_KEY_LENGTH 64
+  static u_char buffer[MAX_OBJECT_KEY_LENGTH];
+  u_char *to = buffer;
+  int i = 0;
+  length = MIN(MAX_OBJECT_KEY_LENGTH - 3, length);
+  *to++ = '"';
+  while(i++ < length) {
+    *to = (isprint(*from)) ? *from : '.'; 
+    to++;
+    from++;
+  }  
+  *to++ = '"';
+  *to = '\0';
+  return buffer;
+}
+
+/* main entry point */
+
+void dissect_giop(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) 
+{
+
+  MessageHeader header;
+  GtkWidget *clnp_tree = NULL, *ti;
+  u_char response_expected = 0;
+  u_int first_offset = offset;
+  u_int big_endian = FALSE;
+  u_int request_id = 0;
+  u_int message_size;
+  u_int minor_version;
+  u_int context_id;
+  u_int reply_status;
+  u_int locate_status;
+  u_int sequence_length;
+  u_int nr_seq;
+  RequestHeader_1_1 request_1_1;
+  RequestHeader_1_0 request_1_0;
+  ReplyHeader reply;
+  LocateReplyHeader locate_rep;
+  LocateRequestHeader locate_req;
+  int i;
+
+#define END_OF_GIOP_MESSAGE (offset - first_offset - GIOP_HEADER_SIZE)
+
+  if (fd->cap_len < offset + GIOP_HEADER_SIZE) {
+    dissect_data(pd, offset, fd, tree);
+    return;
+  }
+
+  /* avoid alignment problem */
+
+  memcpy(&header, &pd[offset], sizeof(header));
+
+  /* check magic number and version */
+
+  if (memcmp(header.magic, GIOP_MAGIC, sizeof(header.magic)) != 0) {
+    dissect_data(pd, offset, fd, tree);
+    return;
+  }
+
+  if (header.GIOP_version.major != GIOP_MAJOR ||
+      ((minor_version = header.GIOP_version.minor) >  GIOP_MINOR)) {
+    dissect_data(pd, offset, fd, tree);
+    return;
+  }
+
+  switch(minor_version) {
+    case 1  :
+      if (header.flags & 0x01)
+	big_endian = FALSE;
+      else
+	big_endian = TRUE;
+      break;
+    case 0  :
+      if (header.flags)
+	big_endian = FALSE;
+      else
+	big_endian = TRUE;
+      break;
+    default :
+      break;
+  }
+  
+  if (big_endian)
+    message_size = pntohl(&header.message_size);
+  else
+    message_size = pletohl(&header.message_size);
+
+  if (fd->win_info[COL_NUM]) {
+    strcpy(fd->win_info[COL_PROTOCOL], "GIOP");
+  }
+
+  if (tree) {
+    ti = add_item_to_tree(GTK_WIDGET(tree), offset, 
+			  GIOP_HEADER_SIZE + message_size,
+			  "General Inter-ORB Protocol");
+    clnp_tree = gtk_tree_new();
+    add_subtree(ti, clnp_tree, ETT_GIOP);
+    add_item_to_tree(clnp_tree, offset,      4,
+		     "Magic number: %s", GIOP_MAGIC);
+    add_item_to_tree(clnp_tree, offset +  4, 2, 
+		     "Version: %d.%d", 
+		     header.GIOP_version.major,
+		     header.GIOP_version.minor);
+    switch(minor_version) {
+      case 1  :
+	add_item_to_tree(clnp_tree, offset +  6, 1, 
+			 "Flags: 0x%02x (%s%s)", 
+			 header.flags,
+			 (big_endian) ? "little" : "big",
+			 (header.flags & 0x02) ? " fragment" : "");
+	break;
+      case 0  :
+	add_item_to_tree(clnp_tree, offset +  6, 1, 
+			 "Byte ordering: %s endian",
+			 (big_endian) ? "little" : "big");
+	break;
+      default :
+	break;
+    } /* minor_version */
+
+    add_item_to_tree(clnp_tree, offset +  7, 1, 
+		     "Message type: %s",
+		     (header.message_type == Request) ? "Request" :
+		     (header.message_type == Reply) ? "Reply" :
+		     (header.message_type == CancelRequest) ? "CancelRequest" :
+		     (header.message_type == LocateRequest) ? "LocateRequest" :
+		     (header.message_type == LocateReply) ? "LocateReply" :
+		     (header.message_type == CloseConnection) ? "CloseConnection" :
+		     (header.message_type == MessageError) ? "MessageError" :
+		     (header.message_type == Fragment) ? "Fragment" : "?");
+
+    add_item_to_tree(clnp_tree, offset +  8, 4, 
+		     "Message size: %d", message_size);
+
+  } /* tree */
+
+  offset += GIOP_HEADER_SIZE;
+
+  if (fd->cap_len < offset + message_size) {
+    dissect_data(pd, offset, fd, tree);
+    return;
+  }
+
+  /* skip service_context in Request/Reply messages */
+
+  switch(header.message_type) {
+
+    case Request:
+    case Reply :
+
+      nr_seq = (big_endian) ? pntohl(&pd[offset]) : pletohl(&pd[offset]);
+
+      offset += sizeof(nr_seq);
+
+      for (i = 0 ; i < nr_seq ; i++) {
+
+	if (big_endian) {	
+	  context_id = pntohl(&pd[offset]);
+	  sequence_length = pntohl(&pd[offset + sizeof(context_id)]);
+	}
+	else {
+	  context_id = pletohl(&pd[offset]);
+	  sequence_length = pletohl(&pd[offset + sizeof(context_id)]);
+	}
+
+	if (tree) {
+	  add_item_to_tree(clnp_tree, offset, sizeof(context_id),
+			   "Context id: %d", context_id);
+	  add_item_to_tree(clnp_tree, offset + sizeof(context_id),
+			   sizeof(sequence_length),
+			   "Sequence length: %d", sequence_length);
+	  add_item_to_tree(clnp_tree,
+			   offset + 
+			   sizeof(context_id) + sizeof(sequence_length),
+			   sequence_length,
+			   "Sequence data: <not shown>");
+	}
+
+	offset += sizeof(context_id) + sizeof(sequence_length) + sequence_length;
+	offset += (sequence_length %4) ? 4 - (sequence_length%4) : 0 ;
+
+      } /* for */
+
+    default :
+      break;
+
+  } /* switch message_type */
+
+  /* decode next parts according to message type */
+
+  switch(header.message_type) {
+
+    case Request:
+
+      switch(minor_version) {
+        case 1  :
+	  memcpy(&request_1_1, &pd[offset], sizeof(request_1_1));
+	  response_expected = request_1_1.response_expected;
+	  request_id = (big_endian)? pntohl(&request_1_1.request_id) :
+	    pletohl(&request_1_1.request_id);
+	  if (tree) {
+	    add_item_to_tree(clnp_tree, offset, sizeof(request_id),
+			     "Request id: %d", request_id);
+	    add_item_to_tree(clnp_tree, offset + sizeof(request_id),
+			     sizeof(request_1_1.response_expected),
+			     "Response expected: %d", 
+			     response_expected);
+	    add_item_to_tree(clnp_tree, offset + sizeof(request_id) +
+			     sizeof(request_1_1.response_expected),
+			     3,
+			     "Reserved");
+	  }
+	  offset += sizeof(request_id) + 
+	    sizeof(request_1_1.response_expected) + 3;
+	  break;
+        case 0  :
+	  memcpy(&request_1_0, &pd[offset], sizeof(request_1_0));
+	  response_expected = request_1_0.response_expected;
+	  request_id = (big_endian)? pntohl(&request_1_0.request_id) :
+	    pletohl(&request_1_0.request_id);
+	  if (tree) {
+	    add_item_to_tree(clnp_tree, offset, sizeof(request_id),
+			     "Request id: %d", request_id);
+	    add_item_to_tree(clnp_tree, offset + sizeof(request_id),
+			     sizeof(request_1_0.response_expected),
+			     "Response expected: %d", 
+			     response_expected);
+	  }
+
+	  offset += sizeof(request_id) + 
+	    sizeof(request_1_0.response_expected);
+	  break;
+        default :
+	  break;
+      }
+
+      /* strange thing here with some ORBs/IIOP1.0 ? */
+      if ((offset - first_offset) % 4)
+	offset += 4 - (offset - first_offset)%4;
+
+      /* object_key */
+
+      sequence_length = (big_endian) ? 
+	pntohl(&pd[offset]) : pletohl(&pd[offset]);
+
+      if (tree) {
+	add_item_to_tree(clnp_tree, offset, sizeof(sequence_length),
+			 "Object key length: %d", sequence_length);
+	add_item_to_tree(clnp_tree, offset + sizeof(sequence_length),
+			 sequence_length,
+			 "Object key: %s",
+			 print_object_key(sequence_length, 
+			   (u_char *)&pd[offset + sizeof(sequence_length)]));
+      }
+
+      /* operation & requesting_principal */
+
+      offset += sizeof(sequence_length) + sequence_length;
+      offset += (sequence_length %4) ? 4 - (sequence_length%4) : 0 ;
+
+      sequence_length = (big_endian) ? 
+	pntohl(&pd[offset]) : pletohl(&pd[offset]);
+
+      if (sequence_length > message_size) {
+	dissect_data(pd, offset, fd, tree);
+	return;
+      }
+       
+      if (tree) {
+	add_item_to_tree(clnp_tree, offset, sizeof(sequence_length),
+			 "Operation length: %d", sequence_length);
+	add_item_to_tree(clnp_tree, offset + sizeof(sequence_length), 
+			 sequence_length,
+			 "Operation: %s",
+			 &pd[offset+sizeof(sequence_length)]);
+	add_item_to_tree(clnp_tree, offset +
+			 sizeof(sequence_length)+ sequence_length,
+			 message_size - END_OF_GIOP_MESSAGE - 
+			 sizeof(sequence_length) - sequence_length,
+			 "Requesting principal: <not shown>");
+      }
+
+      if (fd->win_info[COL_NUM]) {
+	sprintf(fd->win_info[COL_INFO], "Request %s %d: %s",
+		response_expected ? "two-way" : "one-way" ,
+		request_id,
+		&pd[offset+sizeof(sequence_length)]);
+      }
+
+      break;
+
+    case Reply :
+
+      memcpy(&reply, &pd[offset], sizeof(reply));
+      request_id =  (big_endian) ? 
+	pntohl(&reply.request_id) : pletohl(&reply.request_id);
+      reply_status = (big_endian) ? 
+	pntohl(&reply.reply_status) : pletohl(&reply.reply_status);
+
+      if (tree) {
+	add_item_to_tree(clnp_tree, offset, sizeof(request_id),
+			 "Request id: %d", request_id);
+	add_item_to_tree(clnp_tree, offset + sizeof(request_id), 
+			 sizeof(reply_status),
+			 "Reply status: %s",
+			 reply_status == NO_EXCEPTION ? "no exception" :
+			 reply_status == USER_EXCEPTION ? "user exception" :
+			 reply_status == SYSTEM_EXCEPTION ? "system exception" :
+			 reply_status == LOCATION_FORWARD ? "location forward" :
+			 "?");
+      }
+
+      if (fd->win_info[COL_NUM]) {
+	sprintf(fd->win_info[COL_INFO], "Reply %d: %s",
+		request_id,
+		reply_status == NO_EXCEPTION ? "no exception" :
+		reply_status == USER_EXCEPTION ? "user exception" :
+		reply_status == SYSTEM_EXCEPTION ? "system exception" :
+		reply_status == LOCATION_FORWARD ? "location forward" :
+		"?");
+      }
+
+      offset += sizeof(request_id) + sizeof(reply_status);
+
+      if (reply_status == SYSTEM_EXCEPTION) {
+
+	u_int minor_code_value;
+	u_int completion_status;
+
+	sequence_length = (big_endian) ? 
+	  pntohl(&pd[offset]) : pletohl(&pd[offset]);
+
+	if (sequence_length > message_size) {
+	  dissect_data(pd, offset, fd, tree);
+	  return;
+	}
+
+	if (tree) {
+	  add_item_to_tree(clnp_tree, offset, sizeof(sequence_length),
+			   "Exception length: %d", sequence_length);
+	  add_item_to_tree(clnp_tree, offset + sizeof(sequence_length), 
+			   sequence_length,
+			   "Exception id: %s",
+			   &pd[offset+sizeof(sequence_length)]);
+
+	}
+
+	offset += sizeof(sequence_length) + sequence_length;
+
+	minor_code_value = (big_endian) ? 
+	  pntohl(&pd[offset]) : pletohl(&pd[offset]);
+	completion_status = (big_endian) ? 
+	  pntohl(&pd[offset+sizeof(minor_code_value)]) :
+	  pletohl(&pd[offset+sizeof(minor_code_value)]);
+	
+	if (tree) {
+	  add_item_to_tree(clnp_tree, offset, sizeof(minor_code_value),
+			   "Minor code value: %d", minor_code_value);
+	  add_item_to_tree(clnp_tree, offset + sizeof(minor_code_value),
+			   sizeof(completion_status),
+			   "Completion Status: %d",
+			   completion_status);
+	  
+	}
+
+      }
+      else if (reply_status == USER_EXCEPTION) {
+
+	sequence_length = (big_endian) ? 
+	  pntohl(&pd[offset]) : pletohl(&pd[offset]);
+
+	if (sequence_length > message_size) {
+	  dissect_data(pd, offset, fd, tree);
+	  return;
+	}
+
+	if (tree) {
+	  add_item_to_tree(clnp_tree, offset, sizeof(sequence_length),
+			   "Exception length: %d", sequence_length);
+	  add_item_to_tree(clnp_tree, offset + sizeof(sequence_length), 
+			   sequence_length,
+			   "Exception id: %s",
+			   &pd[offset+sizeof(sequence_length)]);
+
+	}
+
+	offset += sizeof(sequence_length) + sequence_length;
+
+	sequence_length = (big_endian) ? 
+	  pntohl(&pd[offset]) : pletohl(&pd[offset]);
+
+	if (sequence_length > message_size) {
+	  dissect_data(pd, offset, fd, tree);
+	  return;
+	}
+
+	if (tree && sequence_length) {
+	  add_item_to_tree(clnp_tree, offset, sizeof(sequence_length),
+			   "Exception member length: %d", sequence_length);
+	  add_item_to_tree(clnp_tree, offset + sizeof(sequence_length), 
+			   sequence_length,
+			   "Exception member: %s",
+			   &pd[offset+sizeof(sequence_length)]);
+	}
+
+	offset += sizeof(sequence_length) + sequence_length;
+
+      }
+      else {
+	
+	if (tree) {
+	  add_item_to_tree(clnp_tree, offset,
+			   message_size - END_OF_GIOP_MESSAGE,
+			   "Reply body: <not shown>");
+	}
+
+      } /* reply_status */
+
+      break;
+
+    case LocateRequest :
+
+      memcpy(&locate_req, &pd[offset], sizeof(locate_req));
+      request_id =  (big_endian) ? 
+	pntohl(&locate_req.request_id) : pletohl(&locate_req.request_id);
+
+      sequence_length = (big_endian) ? 
+	pntohl(&pd[offset+sizeof(request_id)]) : 
+	pletohl(&pd[offset+sizeof(request_id)]);
+
+      if (tree) {
+	add_item_to_tree(clnp_tree, offset, sizeof(request_id),
+			 "Request id: %d", request_id);
+	add_item_to_tree(clnp_tree, offset + sizeof(request_id), 
+			 sizeof(sequence_length),
+			 "Object key length: %d", sequence_length);
+	offset += sizeof(request_id) + sizeof(sequence_length);
+	add_item_to_tree(clnp_tree,
+			 offset,
+			 sequence_length,
+			 "Object key: %s", 
+			 print_object_key(sequence_length, 
+					  (u_char *)&pd[offset]));
+      }
+
+      if (fd->win_info[COL_NUM]) {
+	sprintf(fd->win_info[COL_INFO], "LocateRequest %d", request_id);
+      }
+
+      break;
+
+    case LocateReply :
+
+      memcpy(&locate_rep, &pd[offset], sizeof(locate_rep));
+      request_id =  (big_endian) ? 
+	pntohl(&locate_rep.request_id) : pletohl(&locate_rep.request_id);
+      locate_status = (big_endian) ? 
+	pntohl(&locate_rep.locate_status) : pletohl(&locate_rep.locate_status);
+
+      if (tree) {
+	add_item_to_tree(clnp_tree, offset, sizeof(request_id),
+			 "Request id: %d", request_id);
+	add_item_to_tree(clnp_tree, offset + sizeof(request_id), 
+			 sizeof(locate_status),
+			 "Locate status: %d", locate_status);
+	offset += sizeof(request_id) + sizeof(locate_status);
+	if (locate_status == OBJECT_FORWARD) {
+	  add_item_to_tree(clnp_tree, offset,
+			   message_size - END_OF_GIOP_MESSAGE,
+			   "Locate reply body: <not shown>");
+	}
+      }
+
+      if (fd->win_info[COL_NUM]) {
+	sprintf(fd->win_info[COL_INFO], "LocateReply %d: %s",
+		request_id, 
+		(locate_status == UNKNOWN_OBJECT) ? "Unknown object" :
+		(locate_status == OBJECT_HERE) ? "Object here" :
+		(locate_status == OBJECT_FORWARD) ? "Object forward" : "?");
+      }
+
+      break;
+
+    case CancelRequest :
+
+      request_id =  (big_endian) ? 
+	pntohl(&pd[offset]) : pletohl(&pd[offset]);
+
+      if (tree) {
+	add_item_to_tree(clnp_tree, offset, sizeof(request_id),
+			 "Request id: %d", request_id);
+      }
+
+      if (fd->win_info[COL_NUM]) {
+	sprintf(fd->win_info[COL_INFO], "CancelRequest %d", request_id);
+      }
+
+      break;
+
+    case CloseConnection :
+      if (fd->win_info[COL_NUM]) {
+	sprintf(fd->win_info[COL_INFO], "CloseConnection");
+      }
+      break;
+
+    case MessageError :
+      if (fd->win_info[COL_NUM]) {
+	sprintf(fd->win_info[COL_INFO], "MessageError");
+      }
+      break;
+
+    case Fragment :
+      if (fd->win_info[COL_NUM]) {
+	sprintf(fd->win_info[COL_INFO], "Fragment");
+      }
+      break;
+
+    default :
+      break;
+
+  } /* switch message_type */
+
+
+  offset = first_offset + GIOP_HEADER_SIZE + message_size;
+
+  if (offset < fd->cap_len) {
+    dissect_data(pd, offset, fd, tree);
+  }
+
+} /* dissect_giop */
+
diff -u --recursive --new-file ethereal-0.4.1/packet-tcp.c ethereal-0.4.1-deniel/packet-tcp.c
--- ethereal-0.4.1/packet-tcp.c	Wed Oct 14 03:51:53 1998
+++ ethereal-0.4.1-deniel/packet-tcp.c	Fri Nov 13 20:03:15 1998
@@ -303,7 +303,15 @@
         dissect_lpd(pd, offset, fd, tree);
         break;
       default:
-        dissect_data(pd, offset, fd, tree);
+  
+	/* check existence of high level protocols */
+	
+	if (memcmp(&pd[offset], "GIOP",  4) == 0) {
+	  dissect_giop(pd, offset, fd, tree);
+	}
+	else {
+	  dissect_data(pd, offset, fd, tree);
+	}
     }
   }
  
diff -u --recursive --new-file ethereal-0.4.1/packet.h ethereal-0.4.1-deniel/packet.h
--- ethereal-0.4.1/packet.h	Fri Oct 16 03:21:26 1998
+++ ethereal-0.4.1-deniel/packet.h	Fri Nov 13 19:56:38 1998
@@ -435,6 +435,7 @@
 	ETT_NBNS_RR,
 	ETT_NBIPX,
 	ETT_AARP,
+	ETT_GIOP,
 	NUM_TREE_TYPES	/* last item number plus one */
 };
 
@@ -523,6 +524,7 @@
 void dissect_ip(const u_char *, int, frame_data *, GtkTree *);
 void dissect_ipv6(const u_char *, int, frame_data *, GtkTree *);
 void dissect_ipx(const u_char *, int, frame_data *, GtkTree *);
+void dissect_giop(const u_char *, int, frame_data *, GtkTree *);
 void dissect_llc(const u_char *, int, frame_data *, GtkTree *);
 void dissect_lpd(const u_char *, int, frame_data *, GtkTree *);
 void dissect_nbipx_ns(const u_char *, int, frame_data *, GtkTree *);