aboutsummaryrefslogtreecommitdiffstats
path: root/packet-giop.c
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>1998-11-18 03:04:25 +0000
committerGerald Combs <gerald@wireshark.org>1998-11-18 03:04:25 +0000
commit2ec7b2e63d9db6aef8b32b1ff3f4712610122082 (patch)
treee7b843e2c4c07c120b46074a0443821db832c3dd /packet-giop.c
parentb0fdc8edb26529620367db8a274f79a1247689b8 (diff)
downloadwireshark-2ec7b2e63d9db6aef8b32b1ff3f4712610122082.tar.gz
wireshark-2ec7b2e63d9db6aef8b32b1ff3f4712610122082.tar.bz2
wireshark-2ec7b2e63d9db6aef8b32b1ff3f4712610122082.zip
* File needed for one of Laurent's patches that I just committed.
svn path=/trunk/; revision=104
Diffstat (limited to 'packet-giop.c')
-rw-r--r--packet-giop.c702
1 files changed, 702 insertions, 0 deletions
diff --git a/packet-giop.c b/packet-giop.c
new file mode 100644
index 0000000000..5d615ba32f
--- /dev/null
+++ b/packet-giop.c
@@ -0,0 +1,702 @@
+/* packet-giop.c
+ * Routines for CORBA GIOP/IIOP packet disassembly
+ *
+ * Laurent Deniel <deniel@worldnet.fr>
+ *
+ * $Id: packet-giop.c,v 1.1 1998/11/18 03:04:25 gerald Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.org>
+ * 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 (check_col(fd, COL_PROTOCOL)) {
+ col_add_str(fd, 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 (check_col(fd, COL_INFO)) {
+ col_add_fstr(fd, 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 (check_col(fd, COL_INFO)) {
+ col_add_fstr(fd, 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 (check_col(fd, COL_INFO)) {
+ col_add_fstr(fd, 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 (check_col(fd, COL_INFO)) {
+ col_add_fstr(fd, 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 (check_col(fd, COL_INFO)) {
+ col_add_fstr(fd, COL_INFO, "CancelRequest %d", request_id);
+ }
+
+ break;
+
+ case CloseConnection :
+ if (check_col(fd, COL_INFO)) {
+ col_add_str(fd, COL_INFO, "CloseConnection");
+ }
+ break;
+
+ case MessageError :
+ if (check_col(fd, COL_INFO)) {
+ col_add_str(fd, COL_INFO, "MessageError");
+ }
+ break;
+
+ case Fragment :
+ if (check_col(fd, COL_INFO)) {
+ col_add_str(fd, 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 */
+