2 * Routines for CORBA GIOP/IIOP packet disassembly
4 * Laurent Deniel <deniel@worldnet.fr>
5 * Craig Rodrigues <rodrigc@mediaone.net>
7 * $Id: packet-giop.c,v 1.19 2000/11/07 07:46:20 guy Exp $
9 * Ethereal - Network traffic analyzer
10 * By Gerald Combs <gerald@zing.org>
11 * Copyright 1998 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #ifdef HAVE_SYS_TYPES_H
36 # include <sys/types.h>
44 static int proto_giop = -1;
45 static int hf_giop_message_type = -1;
46 static int hf_giop_message_size = -1;
48 static gint ett_giop = -1;
49 static gint ett_giop_reply = -1;
50 static gint ett_giop_request = -1;
51 static gint ett_giop_cancel_request = -1;
52 static gint ett_giop_locate_request = -1;
53 static gint ett_giop_locate_reply = -1;
54 static gint ett_giop_fragment = -1;
56 static const value_string sync_scope[] = {
58 { 0x1, "SYNC_WITH_TRANSPORT"},
59 { 0x2, "SYNC_WITH_SERVER"},
60 { 0x3, "SYNC_WITH_TARGET"},
64 static const value_string giop_message_types[] = {
67 { 0x2, "CancelRequest"},
68 { 0x3, "LocateRequest"},
69 { 0x4, "LocateReply"},
70 { 0x5, "CloseConnection"},
71 { 0x6, "MessageError"},
76 static const value_string giop_locate_status_types[] = {
77 { 0x0, "Unknown Object" },
78 { 0x1, "Object Here"},
79 { 0x2, "Object Forward"},
80 { 0x3, "Object Forward Perm"},
81 { 0x4, "Loc System Exception"},
82 { 0x5, "Loc Needs Addressing Mode"},
88 * GIOP / IIOP types definition - OMG CORBA 2.x / GIOP 1.[012]
89 * See CORBA 2.4 specification: http://cgi.omg.org/cgi-bin/doc?formal/00-10-1
93 * <sequence> : unsigned int (# elts) + elements
94 * <string> : unsigned int (string length) + length characters (with '\0')
95 * <enum> : unsigned int (from 0 to n)
98 #define GIOP_MAGIC "GIOP"
99 static const guint GIOP_MAJOR = 1;
100 static const guint GIOP_MINOR = 2;
102 static const guint GIOP_HEADER_SIZE = 12;
104 static const int KeyAddr = 0;
105 static const int ProfileAddr = 1;
106 static const int ReferenceAddr = 2;
108 typedef struct OctetSequence
110 guint32 sequence_length;
111 guint8 sequence_data[1]; /* of length bytes */
115 typedef OctetSequence Principal;
116 typedef OctetSequence String;
119 * Some structures that contain sequences can not be directly used
120 * (alignment problem on 64 bit architectures)
123 typedef struct ServiceContext
126 OctetSequence context_data;
130 typedef struct ServiceContextList
133 ServiceContext service_context[1]; /* nr_context elements */
146 Fragment /* GIOP 1.1 only */
150 typedef struct Version
157 typedef struct MessageHeader
160 Version GIOP_version;
161 guint8 flags; /* byte_order in 1.0 */
163 guint32 message_size;
167 typedef struct RequestHeader_1_0
169 /* ServiceContextList service_context; */
171 guint8 response_expected;
172 OctetSequence object_key;
173 /* String operation; */
174 /* Principal requesting_principal; */
178 typedef struct RequestHeader_1_1
180 /* ServiceContextList service_context; */
182 guint8 response_expected;
184 OctetSequence object_key;
185 /* String operation; */
186 /* Principal requesting_principal; */
190 typedef enum ReplyStatusType
196 LOCATION_FORWARD_PERM, /* new for GIOP 1.2 */
197 NEEDS_ADDRESSING_MODE /* new for GIOP 1.2 */
201 const static value_string reply_status_types[] = {
202 { NO_EXCEPTION, "No Exception" } ,
203 { USER_EXCEPTION, "User Exception" } ,
204 { SYSTEM_EXCEPTION, "System Exception" } ,
205 { LOCATION_FORWARD, "Location Forward" } ,
206 { LOCATION_FORWARD_PERM, "Location Forward Perm" } ,
207 { NEEDS_ADDRESSING_MODE, "Needs Addressing Mode"} ,
211 typedef struct ReplyHeader
213 /* ServiceContext service_context; */
215 guint32 reply_status;
219 typedef struct SystemExceptionReplyBody
222 u_int minor_code_value;
223 u_int completion_status;
225 SystemExceptionReplyBody;
227 typedef struct CancelRequestHeader
233 typedef struct LocateRequestHeader
236 OctetSequence object_key;
240 typedef enum LocateStatusType
245 OBJECT_FORWARD_PERM, // new value for GIOP 1.2
246 LOC_SYSTEM_EXCEPTION, // new value for GIOP 1.2
247 LOC_NEEDS_ADDRESSING_MODE // new value for GIOP 1.2
251 typedef struct LocateReplyHeader
254 guint32 locate_status;
258 /* Take in a string and replace non-printable characters with periods */
260 printable_string (gchar *in, guint32 len)
264 for(i=0; i < len; i++)
266 if( !isprint( in[i] ) )
271 /* Determine the byte order from the GIOP MessageHeader */
273 is_big_endian (MessageHeader * header)
275 gboolean big_endian = FALSE;
277 switch (header->GIOP_version.minor)
281 if (header->flags & 0x01)
298 /* Copy a 4 octet sequence from the tvbuff
299 * which represents an unsigned long value, and convert
300 * it to an unsigned long vaule, taking into account byte order.
301 * offset is first incremented so that it falls on a proper alignment
302 * boundary for unsigned long values.
303 * offset is then incremented by 4, to indicate the 4 octets which
304 * have been processed.
307 get_CDR_ulong(tvbuff_t *tvb, int *offset, gboolean stream_is_big_endian)
311 /* unsigned long values must be aligned on a 4 byte boundary */
312 while( ( (*offset + GIOP_HEADER_SIZE) % 4) != 0)
315 val = (stream_is_big_endian) ? tvb_get_ntohl (tvb, *offset) :
316 tvb_get_letohl (tvb, *offset);
322 /* Copy a 2 octet sequence from the tvbuff
323 * which represents an unsigned short value, and convert
324 * it to an unsigned short value, taking into account byte order.
325 * offset is first incremented so that it falls on a proper alignment
326 * boundary for unsigned short values.
327 * offset is then incremented by 2, to indicate the 2 octets which
328 * have been processed.
331 get_CDR_ushort(tvbuff_t *tvb, int *offset, gboolean stream_is_big_endian)
335 /* unsigned long values must be aligned on a 4 byte boundary */
336 while( ( (*offset + GIOP_HEADER_SIZE) % 2) != 0)
339 val = (stream_is_big_endian) ? tvb_get_ntohs (tvb, *offset) :
340 tvb_get_letohs (tvb, *offset);
346 /* Copy a sequence of octets from the tvbuff.
347 * Caller of this function must remember to free the
348 * array pointed to by seq.
349 * This function also increments offset by len.
352 get_CDR_octet_seq(tvbuff_t *tvb, gchar **seq, int *offset, int len)
354 *seq = g_new0(gchar, len + 1);
355 tvb_memcpy( tvb, *seq, *offset, len);
360 * Dissects a TargetAddress which is defined in (CORBA 2.4, section 15.4.2)
362 * typedef short AddressingDisposition;
363 * const short KeyAddr = 0;
364 * const short ProfileAddr = 1;
365 * const short ReferenceAddr = 2;
366 * struct IORAddressingInfo {
367 * unsigned long selected_profile_index;
371 * union TargetAddress switch (AddressingDisposition) {
372 * case KeyAddr: sequence <octet> object_key;
373 * case ProfileAddr: IOP::TaggedProfile profile;
374 * case ReferenceAddr: IORAddressingInfo ior;
378 dissect_target_address(tvbuff_t * tvb, int *offset, proto_tree * sub_tree,
379 MessageHeader * header, gboolean stream_is_big_endian)
381 guint16 discriminant;
382 gchar *object_key = NULL;
385 discriminant = get_CDR_ushort(tvb, offset, stream_is_big_endian);
388 proto_tree_add_text (sub_tree, tvb, *offset -2, 2,
389 "TargetAddress Discriminant: %d", discriminant);
392 switch (discriminant)
395 len = get_CDR_ulong(tvb, offset, stream_is_big_endian);
396 get_CDR_octet_seq(tvb, &object_key, offset, len);
397 printable_string( object_key, len );
401 proto_tree_add_text (sub_tree, tvb, *offset -len -4, 4,
402 "KeyAddr (object key length): %d", len);
403 proto_tree_add_text (sub_tree, tvb, *offset -len, len,
404 "KeyAddr (object key): %s", object_key);
410 proto_tree_add_text (sub_tree, tvb, *offset, tvb_length(tvb) - *offset,
411 "ProfileAddr (not implemented) %s", object_key);
417 proto_tree_add_text (sub_tree, tvb, *offset, tvb_length(tvb) - *offset,
418 "ReferenceAddr (not implemented) %s", object_key);
424 g_free( object_key );
427 /* The format of the Reply Header for GIOP 1.0 and 1.1
428 * is documented in Section 15.4.3.1 * of the CORBA 2.4 standard.
430 struct ReplyHeader_1_0 {
431 IOP::ServiceContextList service_context;
432 unsigned long request_id;
433 ReplyStatusType_1_0 reply_status;
437 dissect_giop_reply (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
438 proto_tree * clnp_tree, MessageHeader * header,
439 gboolean stream_is_big_endian)
444 guint32 sequence_length;
448 proto_tree *reply_tree = NULL;
453 big_endian = is_big_endian (header);
455 /* From Section 15.3.2.5 of the CORBA 2.4 standard, a sequence
456 * is an unsigned long value (4 octets) indicating the number of
457 * items in the sequence, followed by the items in the sequence
460 /* The format of the IOP::ServiceContextList struct is defined in
461 * section 13.7 of the CORBA 2.4 standard as:
463 typedef unsigned long ServiceId;
465 struct ServiceContext {
466 ServiceId context_id;
467 sequence <octet> context_data;
469 typedef sequence <ServiceContext>ServiceContextList;
474 tf = proto_tree_add_text (tree, tvb, offset,
476 "General Inter-ORB Protocol Reply");
477 if (reply_tree == NULL)
479 reply_tree = proto_item_add_subtree (tf, ett_giop_reply);
484 nr_seq = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
486 for (i = 1; i <= nr_seq; i++)
491 context_id = tvb_get_ntohl (tvb, offset);
492 sequence_length = tvb_get_ntohl (tvb, offset + 4);
496 context_id = tvb_get_letohl (tvb, offset);
497 sequence_length = tvb_get_letohl (tvb, offset + 4);
500 context_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
504 proto_tree_add_text (reply_tree, tvb, offset -4, 4,
505 "Context id: %d", context_id);
508 sequence_length = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
511 proto_tree_add_text (reply_tree, tvb, offset -4,
512 4, "Sequence length: %d", sequence_length);
517 if (sequence_length > 0)
519 proto_tree_add_text (reply_tree, tvb, offset,
521 "Sequence data: <not shown>");
525 offset += sequence_length;
529 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
533 proto_tree_add_text (reply_tree, tvb, offset-4, 4,
534 "Request id: %d", request_id);
537 reply_status = tvb_get_guint8 (tvb, offset);
540 proto_tree_add_text (reply_tree, tvb, offset, 1,
542 match_strval(reply_status, reply_status_types));
549 /** The format of the GIOP 1.2 Reply header is very similar to the 1.0
550 * and 1.1 header, only the fields have been rearranged. From Section
551 * 15.4.3.1 of the CORBA 2.4 specification:
553 * struct ReplyHeader_1_2 {
554 unsigned long request_id;
555 ReplyStatusType_1_2 reply_status;
556 IOP:ServiceContextList service_context; // 1.2 change
560 dissect_giop_reply_1_2 (tvbuff_t * tvb, packet_info * pinfo,
561 proto_tree * tree, proto_tree * clnp_tree,
562 MessageHeader * header,
563 gboolean stream_is_big_endian)
568 guint32 sequence_length;
571 proto_tree *reply_tree = NULL;
577 tf = proto_tree_add_text (tree, tvb, offset,
579 "General Inter-ORB Protocol Reply");
580 if (reply_tree == NULL)
582 reply_tree = proto_item_add_subtree (tf, ett_giop_reply);
587 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
590 proto_tree_add_text (reply_tree, tvb, offset-4, 4,
591 "Request id: %d", request_id);
594 reply_status = tvb_get_guint8 (tvb, offset);
598 proto_tree_add_text (reply_tree, tvb, offset-1, 1,
600 match_strval(reply_status, reply_status_types));
604 nr_seq = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
606 for (i = 1; i <= nr_seq; i++)
609 context_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
612 proto_tree_add_text (reply_tree, tvb, offset -4, 4,
613 "Context id: %d", context_id);
616 sequence_length = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
619 proto_tree_add_text (reply_tree, tvb, offset- 4,
620 4, "Sequence length: %d", sequence_length);
623 offset += sequence_length;
626 if (sequence_length > 0)
628 proto_tree_add_text (reply_tree, tvb, offset - sequence_length,
630 "Sequence data: <not shown>");
638 dissect_giop_cancel_request (tvbuff_t * tvb, packet_info * pinfo,
639 proto_tree * tree, proto_tree * clnp_tree,
640 MessageHeader * header, gboolean stream_is_big_endian)
644 proto_tree *cancel_request_tree = NULL;
649 tf = proto_tree_add_text (tree, tvb, offset,
651 "General Inter-ORB Protocol CancelRequest");
652 if (cancel_request_tree == NULL)
654 cancel_request_tree = proto_item_add_subtree (tf, ett_giop_cancel_request);
659 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
662 proto_tree_add_text (cancel_request_tree, tvb, offset-4, 4,
663 "Request id: %d", request_id);
669 /** The formats for GIOP 1.0 and 1.1 Request messages are defined
670 * in section 15.4.2.1 of the CORBA 2.4 specification.
672 * struct RequestHeader{
673 * IOP::ServiceContextList service_context;
674 * unsigned long request_id;
675 * boolean response_expected;
676 * octet reserved[3]; // Only in GIOP 1.1
677 * sequence<octet> object_key;
679 * CORBA::OctetSeq requesting_principal;
683 dissect_giop_request_1_1 (tvbuff_t * tvb, packet_info * pinfo,
684 proto_tree * tree, proto_tree * clnp_tree,
685 MessageHeader * header, gboolean stream_is_big_endian)
690 guint32 sequence_length;
693 gchar *object_key = NULL;
694 gchar *operation = NULL;
695 gchar *requesting_principal = NULL;
696 guint8 response_expected;
697 gchar *reserved = NULL;
698 proto_tree *request_tree = NULL;
705 tf = proto_tree_add_text (tree, tvb, offset,
707 "General Inter-ORB Protocol Request");
708 if (request_tree == NULL)
710 request_tree = proto_item_add_subtree (tf, ett_giop_request);
715 nr_seq = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
717 for (i = 1; i <= nr_seq; i++)
720 context_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
723 proto_tree_add_text (request_tree, tvb, offset-4, 4,
724 "Context id: %d", context_id);
727 sequence_length = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
730 proto_tree_add_text (request_tree, tvb, offset-4, 4,
731 "Sequence length: %d", sequence_length);
734 offset += sequence_length;
735 if (sequence_length > 0)
737 proto_tree_add_text (request_tree, tvb, offset - sequence_length,
739 "Sequence data: <not shown>");
745 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
748 proto_tree_add_text (request_tree, tvb, offset-4, 4,
749 "Request id: %d", request_id);
752 response_expected = tvb_get_guint8( tvb, offset );
756 proto_tree_add_text (request_tree, tvb, offset-1, 1,
757 "Response expected: %d", response_expected);
760 if( header->GIOP_version.minor > 0)
762 get_CDR_octet_seq( tvb, &reserved, &offset, 3);
765 proto_tree_add_text (request_tree, tvb, offset-3, 3,
766 "Reserved: %x %x %x", reserved[0], reserved[1], reserved[2]);
770 /* Length of object_key sequence */
771 len = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
775 proto_tree_add_text (request_tree, tvb, offset-4, 4,
776 /**/ "Object Key length: %d", len);
781 get_CDR_octet_seq(tvb, &object_key, &offset, len);
782 printable_string( object_key, len );
786 proto_tree_add_text (request_tree, tvb, offset - len, len,
787 /**/ "Object Key: %s", object_key);
792 /* length of operation string */
793 len = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
796 proto_tree_add_text (request_tree, tvb, offset -4, 4,
797 /**/ "Operation length: %d", len);
802 get_CDR_octet_seq(tvb, &operation, &offset, len);
805 proto_tree_add_text (request_tree, tvb, offset - len, len,
806 /**/ "Operation: %s", operation);
811 /* length of requesting_principal string */
812 len = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
815 proto_tree_add_text (request_tree, tvb, offset-4, 4,
816 /**/ "Requesting Principal Length: %d", len);
821 get_CDR_octet_seq(tvb, &requesting_principal, &offset, len);
824 proto_tree_add_text (request_tree, tvb, offset - len, len,
825 /**/ "Requesting Principal: %s", requesting_principal);
830 g_free( object_key );
832 g_free( requesting_principal );
835 /** The format of a GIOP 1.2 RequestHeader message is
836 * (CORBA 2.4, sec. 15.4.2):
838 * struct RequestHeader_1_2 {
839 * unsigned long request_id;
840 * octet response_flags;
842 * TargetAddress target;
844 * IOP::ServiceContextList service_context;
845 * // requesting_principal not in GIOP 1.2
849 dissect_giop_request_1_2 (tvbuff_t * tvb, packet_info * pinfo,
850 proto_tree * tree, proto_tree * clnp_tree,
851 MessageHeader * header, gboolean stream_is_big_endian)
856 guint8 response_flags;
857 gchar *reserved = NULL;
858 gchar *operation = NULL;
859 proto_tree *request_tree = NULL;
864 tf = proto_tree_add_text (tree, tvb, offset,
866 "General Inter-ORB Protocol Request");
867 if (request_tree == NULL)
869 request_tree = proto_item_add_subtree (tf, ett_giop_reply);
874 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
877 proto_tree_add_text (request_tree, tvb, offset-4, 4,
878 "Request id: %d", request_id);
881 response_flags = tvb_get_guint8( tvb, offset );
885 proto_tree_add_text (request_tree, tvb, offset-1, 1,
886 "Response flags: %s (%d)",
887 match_strval(response_flags, sync_scope),
891 get_CDR_octet_seq( tvb, &reserved, &offset, 3);
894 proto_tree_add_text (request_tree, tvb, offset-3, 3,
895 "Reserved: %x %x %x", reserved[0], reserved[1], reserved[2]);
898 dissect_target_address(tvb, &offset, request_tree, header, stream_is_big_endian);
900 /* length of operation string */
901 len = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
904 proto_tree_add_text (request_tree, tvb, offset -4, 4,
905 /**/ "Operation length: %d", len);
910 get_CDR_octet_seq(tvb, &operation, &offset, len);
913 proto_tree_add_text (request_tree, tvb, offset - len, len,
914 /**/ "Operation: %s", operation);
923 dissect_giop_locate_request( tvbuff_t * tvb, proto_tree * tree,
924 MessageHeader * header, gboolean stream_is_big_endian)
929 gchar *object_key = NULL;
930 proto_tree *locate_request_tree = NULL;
935 tf = proto_tree_add_text (tree, tvb, offset,
937 "General Inter-ORB Locate Request");
938 if (locate_request_tree == NULL)
940 locate_request_tree = proto_item_add_subtree (tf, ett_giop_locate_request);
945 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
946 if (locate_request_tree)
948 proto_tree_add_text (locate_request_tree, tvb, offset-4, 4,
949 "Request id: %d", request_id);
952 if(header->GIOP_version.minor < 2)
954 len = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
955 get_CDR_octet_seq(tvb, &object_key, &offset, len);
957 if(locate_request_tree)
960 proto_tree_add_text (locate_request_tree, tvb, offset-len, len,
961 "Object Key: %s", object_key);
967 else // GIOP 1.2 and higher
969 dissect_target_address(tvb, &offset, locate_request_tree, header,
970 stream_is_big_endian);
973 g_free( object_key );
977 dissect_giop_locate_reply( tvbuff_t * tvb, proto_tree * tree,
978 MessageHeader * header, gboolean stream_is_big_endian)
982 guint32 locate_status;
983 proto_tree *locate_reply_tree = NULL;
988 tf = proto_tree_add_text (tree, tvb, offset,
990 "General Inter-ORB Locate Reply");
991 if (locate_reply_tree == NULL)
993 locate_reply_tree = proto_item_add_subtree (tf, ett_giop_locate_reply);
998 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
999 if (locate_reply_tree)
1001 proto_tree_add_text (locate_reply_tree, tvb, offset-4, 4,
1002 "Request id: %d", request_id);
1005 locate_status = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
1006 if (locate_reply_tree)
1008 proto_tree_add_text (locate_reply_tree, tvb, offset-4, 4,
1009 "Locate status: %s",
1010 match_strval(locate_status, giop_locate_status_types)
1018 dissect_giop_fragment( tvbuff_t * tvb, proto_tree * tree,
1019 MessageHeader * header, gboolean stream_is_big_endian)
1023 proto_tree *fragment_tree = NULL;
1028 tf = proto_tree_add_text (tree, tvb, offset,
1030 "General Inter-ORB Fragment");
1031 if (fragment_tree == NULL)
1033 fragment_tree = proto_item_add_subtree (tf, ett_giop_fragment);
1038 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
1041 proto_tree_add_text (fragment_tree, tvb, offset-4, 4,
1042 "Request id: %d", request_id);
1049 /* main entry point */
1051 dissect_giop (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1054 MessageHeader header;
1055 tvbuff_t *giop_header_tvb;
1056 tvbuff_t *payload_tvb;
1058 proto_tree *clnp_tree = NULL;
1061 u_int minor_version;
1062 gboolean stream_is_big_endian;
1064 if( !proto_is_protocol_enabled( proto_giop ))
1065 return FALSE; /* GIOP has been disabled */
1067 pinfo->current_proto = "GIOP";
1069 /* check magic number and version */
1072 if (check_col (pinfo->fd, COL_PROTOCOL))
1074 col_add_str (pinfo->fd, COL_PROTOCOL, "GIOP");
1078 /*define END_OF_GIOP_MESSAGE (offset - first_offset - GIOP_HEADER_SIZE) */
1080 giop_header_tvb = tvb_new_subset (tvb, 0, GIOP_HEADER_SIZE, -1);
1081 payload_tvb = tvb_new_subset (tvb, GIOP_HEADER_SIZE, -1, -1);
1083 /* memcpy(&header, &pd[offset], sizeof(header)); */
1084 tvb_memcpy (giop_header_tvb, (guint8 *)&header, 0, sizeof (header));
1086 if (memcmp (header.magic, GIOP_MAGIC, sizeof (header.magic)) != 0)
1088 /* Not a GIOP message. */
1092 if (header.GIOP_version.major != GIOP_MAJOR ||
1093 ((minor_version = header.GIOP_version.minor) > GIOP_MINOR))
1095 /* Bad version number; should we note that and dissect the rest
1096 as data, or should we return FALSE on the theory that it
1097 might have been some other packet that happened to begin with
1099 if (check_col (pinfo->fd, COL_INFO))
1101 col_add_fstr (pinfo->fd, COL_INFO, "Version %d.%d",
1102 header.GIOP_version.major, header.GIOP_version.minor);
1106 ti = proto_tree_add_item (tree, proto_giop, tvb, 0,
1107 tvb_length (tvb), FALSE);
1108 clnp_tree = proto_item_add_subtree (ti, ett_giop);
1109 proto_tree_add_text (clnp_tree, giop_header_tvb, 0,
1110 tvb_length (giop_header_tvb),
1111 "Version %d.%d not supported",
1112 header.GIOP_version.major,
1113 header.GIOP_version.minor);
1115 dissect_data (payload_tvb, pinfo, tree);
1119 stream_is_big_endian = is_big_endian (&header);
1121 if (stream_is_big_endian)
1122 message_size = pntohl (&header.message_size);
1124 message_size = pletohl (&header.message_size);
1128 ti = proto_tree_add_item (tree, proto_giop, tvb, 0, 12, FALSE);
1129 clnp_tree = proto_item_add_subtree (ti, ett_giop);
1130 proto_tree_add_text (clnp_tree, giop_header_tvb, offset, 4,
1131 "Magic number: %s", GIOP_MAGIC);
1132 proto_tree_add_text (clnp_tree, giop_header_tvb, 4, 2,
1134 header.GIOP_version.major,
1135 header.GIOP_version.minor);
1136 switch (minor_version)
1140 proto_tree_add_text (clnp_tree, giop_header_tvb, 6, 1,
1141 "Flags: 0x%02x (%s %s)",
1143 (stream_is_big_endian) ? "big-endian" : "little-endian",
1144 (header.flags & 0x02) ? " fragment" : "");
1147 proto_tree_add_text (clnp_tree, giop_header_tvb, 6, 1,
1148 "Byte ordering: %s-endian",
1149 (stream_is_big_endian) ? "big" : "little");
1153 } /* minor_version */
1155 proto_tree_add_uint_format (clnp_tree,
1156 hf_giop_message_type,
1157 giop_header_tvb, 7, 1,
1158 header.message_type,
1159 "Message type: %s", match_strval(header.message_type, giop_message_types));
1161 proto_tree_add_uint (clnp_tree,
1162 hf_giop_message_size,
1163 giop_header_tvb, 8, 4, message_size);
1167 if (check_col (pinfo->fd, COL_INFO))
1169 col_add_fstr (pinfo->fd, COL_INFO, "GIOP %d.%d %s",
1170 header.GIOP_version.major, header.GIOP_version.minor,
1171 match_strval(header.message_type, giop_message_types));
1174 switch (header.message_type)
1178 if(header.GIOP_version.minor < 2)
1180 dissect_giop_request_1_1 (payload_tvb, pinfo, tree, clnp_tree,
1181 &header, stream_is_big_endian);
1185 dissect_giop_request_1_2 (payload_tvb, pinfo, tree, clnp_tree,
1186 &header, stream_is_big_endian);
1193 if(header.GIOP_version.minor < 2)
1195 dissect_giop_reply (payload_tvb, pinfo, tree, clnp_tree, &header,
1196 stream_is_big_endian);
1200 dissect_giop_reply_1_2 (payload_tvb, pinfo, tree, clnp_tree,
1201 &header, stream_is_big_endian);
1205 dissect_giop_cancel_request(payload_tvb, pinfo, tree, clnp_tree,
1206 &header, stream_is_big_endian);
1209 dissect_giop_locate_request(payload_tvb, tree, &header,
1210 stream_is_big_endian);
1213 dissect_giop_locate_reply(payload_tvb, tree, &header,
1214 stream_is_big_endian);
1217 dissect_giop_fragment(payload_tvb, tree, &header,
1218 stream_is_big_endian);
1223 } /* switch message_type */
1228 proto_register_giop (void)
1230 static hf_register_info hf[] = {
1232 &hf_giop_message_type,
1234 "Message type", "giop.type",
1235 FT_UINT8, BASE_DEC, NULL, 0x0, ""}
1239 &hf_giop_message_size,
1241 "Message size", "giop.len",
1242 FT_UINT32, BASE_DEC, NULL, 0x0, ""}
1246 static gint *ett[] = {
1250 &ett_giop_cancel_request,
1251 &ett_giop_locate_request,
1252 &ett_giop_locate_reply,
1255 proto_giop = proto_register_protocol ("General Inter-ORB Protocol", "giop");
1256 proto_register_field_array (proto_giop, hf, array_length (hf));
1257 proto_register_subtree_array (ett, array_length (ett));
1261 proto_reg_handoff_giop (void)
1263 heur_dissector_add ("tcp", dissect_giop);