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.29 2001/01/16 23:35:58 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( (unsigned char)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 short values must be aligned on a 2 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);
347 /* Copy a 2 octet sequence from the tvbuff
348 * which represents a signed short value, and convert
349 * it to a signed short value, taking into account byte order.
350 * offset is first incremented so that it falls on a proper alignment
351 * boundary for unsigned short values.
352 * offset is then incremented by 2, to indicate the 2 octets which
353 * have been processed.
357 get_CDR_short(tvbuff_t *tvb, int *offset, gboolean stream_is_big_endian)
361 /* short values must be aligned on a 2 byte boundary */
362 while( ( (*offset + GIOP_HEADER_SIZE) % 2) != 0)
365 val = (stream_is_big_endian) ? tvb_get_ntohs (tvb, *offset) :
366 tvb_get_letohs (tvb, *offset);
374 /* Copy a sequence of octets from the tvbuff.
375 * Caller of this function must remember to free the
376 * array pointed to by seq.
377 * This function also increments offset by len.
380 get_CDR_octet_seq(tvbuff_t *tvb, gchar **seq, int *offset, int len)
382 *seq = g_new0(gchar, len + 1);
383 tvb_memcpy( tvb, *seq, *offset, len);
388 * Dissects a TargetAddress which is defined in (CORBA 2.4, section 15.4.2)
390 * typedef short AddressingDisposition;
391 * const short KeyAddr = 0;
392 * const short ProfileAddr = 1;
393 * const short ReferenceAddr = 2;
394 * struct IORAddressingInfo {
395 * unsigned long selected_profile_index;
399 * union TargetAddress switch (AddressingDisposition) {
400 * case KeyAddr: sequence <octet> object_key;
401 * case ProfileAddr: IOP::TaggedProfile profile;
402 * case ReferenceAddr: IORAddressingInfo ior;
406 dissect_target_address(tvbuff_t * tvb, int *offset, proto_tree * sub_tree,
407 MessageHeader * header, gboolean stream_is_big_endian)
409 guint16 discriminant;
410 gchar *object_key = NULL;
413 discriminant = get_CDR_ushort(tvb, offset, stream_is_big_endian);
416 proto_tree_add_text (sub_tree, tvb, *offset -2, 2,
417 "TargetAddress Discriminant: %u", discriminant);
420 switch (discriminant)
423 len = get_CDR_ulong(tvb, offset, stream_is_big_endian);
424 get_CDR_octet_seq(tvb, &object_key, offset, len);
425 printable_string( object_key, len );
429 proto_tree_add_text (sub_tree, tvb, *offset -len -4, 4,
430 "KeyAddr (object key length): %u", len);
431 proto_tree_add_text (sub_tree, tvb, *offset -len, len,
432 "KeyAddr (object key): %s", object_key);
438 proto_tree_add_text (sub_tree, tvb, *offset, tvb_length(tvb) - *offset,
439 "ProfileAddr (not implemented) %s", object_key);
445 proto_tree_add_text (sub_tree, tvb, *offset, tvb_length(tvb) - *offset,
446 "ReferenceAddr (not implemented) %s", object_key);
452 g_free( object_key );
456 dissect_reply_body (tvbuff_t *tvb, u_int offset, packet_info *pinfo,
457 proto_tree *tree, gboolean stream_is_big_endian,
458 guint32 reply_status)
460 u_int sequence_length;
461 u_int minor_code_value;
462 u_int completion_status;
464 switch (reply_status)
466 case SYSTEM_EXCEPTION:
469 sequence_length = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
471 proto_tree_add_text(tree, tvb, offset-4, 4,
472 "Exception length: %u", sequence_length);
474 if (sequence_length != 0)
476 proto_tree_add_text(tree, tvb, offset, sequence_length,
478 tvb_format_text(tvb, offset, sequence_length - 1));
479 offset += sequence_length;
482 minor_code_value = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
483 completion_status = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
485 proto_tree_add_text(tree, tvb, offset-8, 4,
486 "Minor code value: %u", minor_code_value);
487 proto_tree_add_text(tree, tvb, offset-4, 4,
488 "Completion Status: %u", completion_status);
495 sequence_length = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
497 proto_tree_add_text(tree, tvb, offset-4, 4,
498 "Exception length: %u", sequence_length);
500 if (sequence_length != 0)
502 proto_tree_add_text(tree, tvb, offset, sequence_length,
504 tvb_format_text(tvb, offset, sequence_length));
506 offset += sequence_length;
509 sequence_length = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
510 proto_tree_add_text(tree, tvb, offset-4, 4,
511 "Exception member length: %u", sequence_length);
513 if (sequence_length != 0)
515 proto_tree_add_text(tree, tvb, offset, sequence_length,
516 "Exception member: %s",
517 tvb_format_text(tvb, offset, sequence_length - 1));
526 proto_tree_add_text(tree, tvb, offset,
527 tvb_length_remaining(tvb, offset),
528 "Reply body: <not shown>");
533 /* The format of the Reply Header for GIOP 1.0 and 1.1
534 * is documented in Section 15.4.3.1 * of the CORBA 2.4 standard.
536 struct ReplyHeader_1_0 {
537 IOP::ServiceContextList service_context;
538 unsigned long request_id;
539 ReplyStatusType_1_0 reply_status;
543 dissect_giop_reply (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
544 proto_tree * clnp_tree, MessageHeader * header,
545 gboolean stream_is_big_endian)
550 guint32 sequence_length;
552 guint32 reply_status;
554 proto_tree *reply_tree = NULL;
559 big_endian = is_big_endian (header);
561 /* From Section 15.3.2.5 of the CORBA 2.4 standard, a sequence
562 * is an unsigned long value (4 octets) indicating the number of
563 * items in the sequence, followed by the items in the sequence
566 /* The format of the IOP::ServiceContextList struct is defined in
567 * section 13.7 of the CORBA 2.4 standard as:
569 typedef unsigned long ServiceId;
571 struct ServiceContext {
572 ServiceId context_id;
573 sequence <octet> context_data;
575 typedef sequence <ServiceContext>ServiceContextList;
580 tf = proto_tree_add_text (tree, tvb, offset,
582 "General Inter-ORB Protocol Reply");
583 if (reply_tree == NULL)
585 reply_tree = proto_item_add_subtree (tf, ett_giop_reply);
590 nr_seq = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
592 for (i = 1; i <= nr_seq; i++)
597 context_id = tvb_get_ntohl (tvb, offset);
598 sequence_length = tvb_get_ntohl (tvb, offset + 4);
602 context_id = tvb_get_letohl (tvb, offset);
603 sequence_length = tvb_get_letohl (tvb, offset + 4);
606 context_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
610 proto_tree_add_text (reply_tree, tvb, offset -4, 4,
611 "Context id: %u", context_id);
614 sequence_length = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
617 proto_tree_add_text (reply_tree, tvb, offset -4,
618 4, "Sequence length: %u", sequence_length);
623 if (sequence_length > 0)
625 proto_tree_add_text (reply_tree, tvb, offset,
627 "Sequence data: <not shown>");
631 offset += sequence_length;
635 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
636 if (check_col(pinfo->fd, COL_INFO))
638 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
642 proto_tree_add_text (reply_tree, tvb, offset-4, 4,
643 "Request id: %u", request_id);
646 reply_status = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
647 if (check_col(pinfo->fd, COL_INFO))
649 col_append_fstr(pinfo->fd, COL_INFO, ": %s",
650 val_to_str(reply_status, reply_status_types, "Unknown (%u)"));
654 proto_tree_add_text (reply_tree, tvb, offset-4, 4,
656 val_to_str(reply_status, reply_status_types, "Unknown (%u)"));
660 dissect_reply_body(tvb, offset, pinfo, reply_tree, stream_is_big_endian,
664 /** The format of the GIOP 1.2 Reply header is very similar to the 1.0
665 * and 1.1 header, only the fields have been rearranged. From Section
666 * 15.4.3.1 of the CORBA 2.4 specification:
668 * struct ReplyHeader_1_2 {
669 unsigned long request_id;
670 ReplyStatusType_1_2 reply_status;
671 IOP:ServiceContextList service_context; // 1.2 change
675 dissect_giop_reply_1_2 (tvbuff_t * tvb, packet_info * pinfo,
676 proto_tree * tree, proto_tree * clnp_tree,
677 MessageHeader * header,
678 gboolean stream_is_big_endian)
683 guint32 sequence_length;
685 guint32 reply_status;
686 proto_tree *reply_tree = NULL;
692 tf = proto_tree_add_text (tree, tvb, offset,
694 "General Inter-ORB Protocol Reply");
695 if (reply_tree == NULL)
697 reply_tree = proto_item_add_subtree (tf, ett_giop_reply);
702 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
703 if (check_col(pinfo->fd, COL_INFO))
705 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
709 proto_tree_add_text (reply_tree, tvb, offset-4, 4,
710 "Request id: %u", request_id);
713 reply_status = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
714 if (check_col(pinfo->fd, COL_INFO))
716 col_append_fstr(pinfo->fd, COL_INFO, ": %s",
717 val_to_str(reply_status, reply_status_types, "Unknown (%u)"));
721 proto_tree_add_text (reply_tree, tvb, offset-4, 4,
723 val_to_str(reply_status, reply_status_types, "Unknown (%u)"));
727 nr_seq = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
729 for (i = 1; i <= nr_seq; i++)
732 context_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
735 proto_tree_add_text (reply_tree, tvb, offset -4, 4,
736 "Context id: %u", context_id);
739 sequence_length = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
742 proto_tree_add_text (reply_tree, tvb, offset- 4,
743 4, "Sequence length: %u", sequence_length);
746 offset += sequence_length;
749 if (sequence_length > 0)
751 proto_tree_add_text (reply_tree, tvb, offset - sequence_length,
753 "Sequence data: <not shown>");
759 dissect_reply_body(tvb, offset, pinfo, reply_tree, stream_is_big_endian,
764 dissect_giop_cancel_request (tvbuff_t * tvb, packet_info * pinfo,
765 proto_tree * tree, proto_tree * clnp_tree,
766 MessageHeader * header, gboolean stream_is_big_endian)
770 proto_tree *cancel_request_tree = NULL;
775 tf = proto_tree_add_text (tree, tvb, offset,
777 "General Inter-ORB Protocol CancelRequest");
778 if (cancel_request_tree == NULL)
780 cancel_request_tree = proto_item_add_subtree (tf, ett_giop_cancel_request);
785 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
786 if (check_col(pinfo->fd, COL_INFO))
788 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
792 proto_tree_add_text (cancel_request_tree, tvb, offset-4, 4,
793 "Request id: %u", request_id);
799 /** The formats for GIOP 1.0 and 1.1 Request messages are defined
800 * in section 15.4.2.1 of the CORBA 2.4 specification.
802 * struct RequestHeader{
803 * IOP::ServiceContextList service_context;
804 * unsigned long request_id;
805 * boolean response_expected;
806 * octet reserved[3]; // Only in GIOP 1.1
807 * sequence<octet> object_key;
809 * CORBA::OctetSeq requesting_principal;
813 dissect_giop_request_1_1 (tvbuff_t * tvb, packet_info * pinfo,
814 proto_tree * tree, proto_tree * clnp_tree,
815 MessageHeader * header, gboolean stream_is_big_endian)
820 guint32 sequence_length;
823 gchar *object_key = NULL;
824 gchar *operation = NULL;
825 gchar *requesting_principal = NULL;
826 guint8 response_expected;
827 gchar *reserved = NULL;
828 proto_tree *request_tree = NULL;
835 tf = proto_tree_add_text (tree, tvb, offset,
837 "General Inter-ORB Protocol Request");
838 if (request_tree == NULL)
840 request_tree = proto_item_add_subtree (tf, ett_giop_request);
845 nr_seq = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
847 for (i = 1; i <= nr_seq; i++)
850 context_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
853 proto_tree_add_text (request_tree, tvb, offset-4, 4,
854 "Context id: %u", context_id);
857 sequence_length = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
860 proto_tree_add_text (request_tree, tvb, offset-4, 4,
861 "Sequence length: %u", sequence_length);
864 offset += sequence_length;
865 if (sequence_length > 0)
867 proto_tree_add_text (request_tree, tvb, offset - sequence_length,
869 "Sequence data: <not shown>");
875 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
876 if (check_col(pinfo->fd, COL_INFO))
878 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
882 proto_tree_add_text (request_tree, tvb, offset-4, 4,
883 "Request id: %u", request_id);
886 response_expected = tvb_get_guint8( tvb, offset );
888 if (check_col(pinfo->fd, COL_INFO))
890 col_append_fstr(pinfo->fd, COL_INFO, " (%s)",
891 response_expected ? "two-way" : "one-way");
895 proto_tree_add_text (request_tree, tvb, offset-1, 1,
896 "Response expected: %u", response_expected);
899 if( header->GIOP_version.minor > 0)
901 get_CDR_octet_seq( tvb, &reserved, &offset, 3);
904 proto_tree_add_text (request_tree, tvb, offset-3, 3,
905 "Reserved: %x %x %x", reserved[0], reserved[1], reserved[2]);
909 /* Length of object_key sequence */
910 len = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
914 proto_tree_add_text (request_tree, tvb, offset-4, 4,
915 /**/ "Object Key length: %u", len);
920 get_CDR_octet_seq(tvb, &object_key, &offset, len);
921 printable_string( object_key, len );
925 proto_tree_add_text (request_tree, tvb, offset - len, len,
926 /**/ "Object Key: %s", object_key);
931 /* length of operation string */
932 len = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
935 proto_tree_add_text (request_tree, tvb, offset -4, 4,
936 /**/ "Operation length: %u", len);
941 get_CDR_octet_seq(tvb, &operation, &offset, len);
942 if (check_col(pinfo->fd, COL_INFO))
944 col_append_fstr(pinfo->fd, COL_INFO, ": %s", operation);
948 proto_tree_add_text (request_tree, tvb, offset - len, len,
949 /**/ "Operation: %s", operation);
954 /* length of requesting_principal string */
955 len = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
958 proto_tree_add_text (request_tree, tvb, offset-4, 4,
959 /**/ "Requesting Principal Length: %u", len);
964 get_CDR_octet_seq(tvb, &requesting_principal, &offset, len);
967 proto_tree_add_text (request_tree, tvb, offset - len, len,
968 /**/ "Requesting Principal: %s", requesting_principal);
973 g_free( object_key );
975 g_free( requesting_principal );
978 /** The format of a GIOP 1.2 RequestHeader message is
979 * (CORBA 2.4, sec. 15.4.2):
981 * struct RequestHeader_1_2 {
982 * unsigned long request_id;
983 * octet response_flags;
985 * TargetAddress target;
987 * IOP::ServiceContextList service_context;
988 * // requesting_principal not in GIOP 1.2
992 dissect_giop_request_1_2 (tvbuff_t * tvb, packet_info * pinfo,
993 proto_tree * tree, proto_tree * clnp_tree,
994 MessageHeader * header, gboolean stream_is_big_endian)
999 guint8 response_flags;
1000 gchar *reserved = NULL;
1001 gchar *operation = NULL;
1002 proto_tree *request_tree = NULL;
1007 tf = proto_tree_add_text (tree, tvb, offset,
1009 "General Inter-ORB Protocol Request");
1010 if (request_tree == NULL)
1012 request_tree = proto_item_add_subtree (tf, ett_giop_reply);
1017 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
1018 if (check_col(pinfo->fd, COL_INFO))
1020 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
1024 proto_tree_add_text (request_tree, tvb, offset-4, 4,
1025 "Request id: %u", request_id);
1028 response_flags = tvb_get_guint8( tvb, offset );
1032 proto_tree_add_text (request_tree, tvb, offset-1, 1,
1033 "Response flags: %s (%u)",
1034 match_strval(response_flags, sync_scope),
1038 get_CDR_octet_seq( tvb, &reserved, &offset, 3);
1041 proto_tree_add_text (request_tree, tvb, offset-3, 3,
1042 "Reserved: %x %x %x", reserved[0], reserved[1], reserved[2]);
1045 dissect_target_address(tvb, &offset, request_tree, header, stream_is_big_endian);
1047 /* length of operation string */
1048 len = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
1051 proto_tree_add_text (request_tree, tvb, offset -4, 4,
1052 /**/ "Operation length: %u", len);
1057 get_CDR_octet_seq(tvb, &operation, &offset, len);
1058 if (check_col(pinfo->fd, COL_INFO))
1060 col_append_fstr(pinfo->fd, COL_INFO, ": %s", operation);
1064 proto_tree_add_text (request_tree, tvb, offset - len, len,
1065 /**/ "Operation: %s", operation);
1074 dissect_giop_locate_request( tvbuff_t * tvb, packet_info * pinfo,
1075 proto_tree * tree, MessageHeader * header,
1076 gboolean stream_is_big_endian)
1081 gchar *object_key = NULL;
1082 proto_tree *locate_request_tree = NULL;
1087 tf = proto_tree_add_text (tree, tvb, offset,
1089 "General Inter-ORB Locate Request");
1090 if (locate_request_tree == NULL)
1092 locate_request_tree = proto_item_add_subtree (tf, ett_giop_locate_request);
1097 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
1098 if (check_col(pinfo->fd, COL_INFO))
1100 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
1102 if (locate_request_tree)
1104 proto_tree_add_text (locate_request_tree, tvb, offset-4, 4,
1105 "Request id: %u", request_id);
1108 if(header->GIOP_version.minor < 2)
1110 len = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
1111 get_CDR_octet_seq(tvb, &object_key, &offset, len);
1113 if(locate_request_tree)
1116 proto_tree_add_text (locate_request_tree, tvb, offset-len, len,
1117 "Object Key: %s", object_key);
1123 else // GIOP 1.2 and higher
1125 dissect_target_address(tvb, &offset, locate_request_tree, header,
1126 stream_is_big_endian);
1129 g_free( object_key );
1133 dissect_giop_locate_reply( tvbuff_t * tvb, packet_info * pinfo,
1134 proto_tree * tree, MessageHeader * header,
1135 gboolean stream_is_big_endian)
1139 guint32 locate_status;
1140 proto_tree *locate_reply_tree = NULL;
1145 tf = proto_tree_add_text (tree, tvb, offset,
1147 "General Inter-ORB Locate Reply");
1148 if (locate_reply_tree == NULL)
1150 locate_reply_tree = proto_item_add_subtree (tf, ett_giop_locate_reply);
1155 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
1156 if (check_col(pinfo->fd, COL_INFO))
1158 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
1160 if (locate_reply_tree)
1162 proto_tree_add_text (locate_reply_tree, tvb, offset-4, 4,
1163 "Request id: %u", request_id);
1166 locate_status = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
1167 if (locate_reply_tree)
1169 proto_tree_add_text (locate_reply_tree, tvb, offset-4, 4,
1170 "Locate status: %s",
1171 match_strval(locate_status, giop_locate_status_types)
1179 dissect_giop_fragment( tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
1180 MessageHeader * header, gboolean stream_is_big_endian)
1184 proto_tree *fragment_tree = NULL;
1189 tf = proto_tree_add_text (tree, tvb, offset,
1191 "General Inter-ORB Fragment");
1192 if (fragment_tree == NULL)
1194 fragment_tree = proto_item_add_subtree (tf, ett_giop_fragment);
1199 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian);
1200 if (check_col(pinfo->fd, COL_INFO))
1202 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
1206 proto_tree_add_text (fragment_tree, tvb, offset-4, 4,
1207 "Request id: %u", request_id);
1214 /* main entry point */
1216 dissect_giop (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1219 MessageHeader header;
1220 tvbuff_t *giop_header_tvb;
1221 tvbuff_t *payload_tvb;
1223 proto_tree *clnp_tree = NULL;
1226 u_int minor_version;
1227 gboolean stream_is_big_endian;
1229 if( !proto_is_protocol_enabled( proto_giop ))
1230 return FALSE; /* GIOP has been disabled */
1232 pinfo->current_proto = "GIOP";
1234 /* check magic number and version */
1237 /*define END_OF_GIOP_MESSAGE (offset - first_offset - GIOP_HEADER_SIZE) */
1239 if (tvb_length_remaining(tvb, 0) < GIOP_HEADER_SIZE)
1241 /* Not enough data captured to hold the GIOP header; don't try
1242 to interpret it as GIOP. */
1246 giop_header_tvb = tvb_new_subset (tvb, 0, GIOP_HEADER_SIZE, -1);
1247 payload_tvb = tvb_new_subset (tvb, GIOP_HEADER_SIZE, -1, -1);
1249 /* memcpy(&header, &pd[offset], sizeof(header)); */
1250 tvb_memcpy (giop_header_tvb, (guint8 *)&header, 0, sizeof (header));
1252 if (memcmp (header.magic, GIOP_MAGIC, sizeof (header.magic)) != 0)
1254 /* Not a GIOP message. */
1258 if (check_col (pinfo->fd, COL_PROTOCOL))
1260 col_set_str (pinfo->fd, COL_PROTOCOL, "GIOP");
1263 if (header.GIOP_version.major != GIOP_MAJOR ||
1264 ((minor_version = header.GIOP_version.minor) > GIOP_MINOR))
1266 /* Bad version number; should we note that and dissect the rest
1267 as data, or should we return FALSE on the theory that it
1268 might have been some other packet that happened to begin with
1269 "GIOP"? We shouldn't do *both*, so we return TRUE, for now.
1270 If we should return FALSE, we should do so *without* setting
1271 the "Info" column, *without* setting the "Protocol" column,
1272 and *without* adding anything to the protocol tree. */
1273 if (check_col (pinfo->fd, COL_INFO))
1275 col_add_fstr (pinfo->fd, COL_INFO, "Version %u.%u",
1276 header.GIOP_version.major, header.GIOP_version.minor);
1280 ti = proto_tree_add_item (tree, proto_giop, tvb, 0,
1281 tvb_length (tvb), FALSE);
1282 clnp_tree = proto_item_add_subtree (ti, ett_giop);
1283 proto_tree_add_text (clnp_tree, giop_header_tvb, 0,
1284 tvb_length (giop_header_tvb),
1285 "Version %u.%u not supported",
1286 header.GIOP_version.major,
1287 header.GIOP_version.minor);
1289 dissect_data (payload_tvb, 0, pinfo, tree);
1293 stream_is_big_endian = is_big_endian (&header);
1295 if (stream_is_big_endian)
1296 message_size = pntohl (&header.message_size);
1298 message_size = pletohl (&header.message_size);
1302 ti = proto_tree_add_item (tree, proto_giop, tvb, 0, 12, FALSE);
1303 clnp_tree = proto_item_add_subtree (ti, ett_giop);
1304 proto_tree_add_text (clnp_tree, giop_header_tvb, offset, 4,
1305 "Magic number: %s", GIOP_MAGIC);
1306 proto_tree_add_text (clnp_tree, giop_header_tvb, 4, 2,
1308 header.GIOP_version.major,
1309 header.GIOP_version.minor);
1310 switch (minor_version)
1314 proto_tree_add_text (clnp_tree, giop_header_tvb, 6, 1,
1315 "Flags: 0x%02x (%s %s)",
1317 (stream_is_big_endian) ? "big-endian" : "little-endian",
1318 (header.flags & 0x02) ? " fragment" : "");
1321 proto_tree_add_text (clnp_tree, giop_header_tvb, 6, 1,
1322 "Byte ordering: %s-endian",
1323 (stream_is_big_endian) ? "big" : "little");
1327 } /* minor_version */
1329 proto_tree_add_uint_format (clnp_tree,
1330 hf_giop_message_type,
1331 giop_header_tvb, 7, 1,
1332 header.message_type,
1333 "Message type: %s", match_strval(header.message_type, giop_message_types));
1335 proto_tree_add_uint (clnp_tree,
1336 hf_giop_message_size,
1337 giop_header_tvb, 8, 4, message_size);
1341 if (check_col (pinfo->fd, COL_INFO))
1343 col_add_fstr (pinfo->fd, COL_INFO, "GIOP %u.%u %s",
1344 header.GIOP_version.major, header.GIOP_version.minor,
1345 match_strval(header.message_type, giop_message_types));
1348 switch (header.message_type)
1352 if(header.GIOP_version.minor < 2)
1354 dissect_giop_request_1_1 (payload_tvb, pinfo, tree, clnp_tree,
1355 &header, stream_is_big_endian);
1359 dissect_giop_request_1_2 (payload_tvb, pinfo, tree, clnp_tree,
1360 &header, stream_is_big_endian);
1367 if(header.GIOP_version.minor < 2)
1369 dissect_giop_reply (payload_tvb, pinfo, tree, clnp_tree, &header,
1370 stream_is_big_endian);
1374 dissect_giop_reply_1_2 (payload_tvb, pinfo, tree, clnp_tree,
1375 &header, stream_is_big_endian);
1379 dissect_giop_cancel_request(payload_tvb, pinfo, tree, clnp_tree,
1380 &header, stream_is_big_endian);
1383 dissect_giop_locate_request(payload_tvb, pinfo, tree, &header,
1384 stream_is_big_endian);
1387 dissect_giop_locate_reply(payload_tvb, pinfo, tree, &header,
1388 stream_is_big_endian);
1391 dissect_giop_fragment(payload_tvb, pinfo, tree, &header,
1392 stream_is_big_endian);
1397 } /* switch message_type */
1402 proto_register_giop (void)
1404 static hf_register_info hf[] = {
1406 &hf_giop_message_type,
1408 "Message type", "giop.type",
1409 FT_UINT8, BASE_DEC, NULL, 0x0, ""}
1413 &hf_giop_message_size,
1415 "Message size", "giop.len",
1416 FT_UINT32, BASE_DEC, NULL, 0x0, ""}
1420 static gint *ett[] = {
1424 &ett_giop_cancel_request,
1425 &ett_giop_locate_request,
1426 &ett_giop_locate_reply,
1429 proto_giop = proto_register_protocol("General Inter-ORB Protocol", "GIOP",
1431 proto_register_field_array (proto_giop, hf, array_length (hf));
1432 proto_register_subtree_array (ett, array_length (ett));
1436 proto_reg_handoff_giop (void)
1438 heur_dissector_add ("tcp", dissect_giop, proto_giop);