2 * Routines for CORBA GIOP/IIOP packet disassembly
4 * Laurent Deniel <deniel@worldnet.fr>
6 * $Id: packet-giop.c,v 1.2 1999/03/23 03:14:37 gram Exp $
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@zing.org>
10 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #ifdef HAVE_SYS_TYPES_H
35 # include <sys/types.h>
44 * GIOP / IIOP types definition - OMG CORBA 2.x / GIOP 1.[01]
45 * See OMG WEB site <http://www.omg.org> - CORBA+IIOP 2.2 (98-02-01.ps)
49 * <sequence> : unsigned int (# elts) + elements
50 * <string> : unsigned int (string length) + length characters (with '\0')
51 * <enum> : unsigned int (from 0 to n)
54 #define GIOP_MAGIC "GIOP"
58 #define GIOP_HEADER_SIZE 12
60 typedef struct OctetSequence{
61 u_int sequence_length;
62 u_char sequence_data[1]; /* of length bytes */
65 typedef OctetSequence Principal;
66 typedef OctetSequence String;
69 * Some structures that contain sequences can not be directly used
70 * (alignment problem on 64 bit architectures)
73 typedef struct ServiceContext {
75 OctetSequence context_data;
78 typedef struct ServiceContextList{
80 ServiceContext service_context[1]; /* nr_context elements */
83 typedef enum MsgType {
91 Fragment /* GIOP 1.1 only */
94 typedef struct Version {
99 typedef struct MessageHeader {
101 Version GIOP_version;
102 u_char flags; /* byte_order in 1.0 */
107 typedef struct RequestHeader_1_0 {
108 /* ServiceContextList service_context;*/
110 u_char response_expected;
111 OctetSequence object_key;
112 /* String operation; */
113 /* Principal requesting_principal; */
116 typedef struct RequestHeader_1_1 {
117 /* ServiceContextList service_context;*/
119 u_char response_expected;
121 OctetSequence object_key;
122 /* String operation; */
123 /* Principal requesting_principal; */
126 typedef enum ReplyStatusType {
133 typedef struct ReplyHeader {
134 /* ServiceContext service_context; */
139 typedef struct SystemExceptionReplyBody {
141 u_int minor_code_value;
142 u_int completion_status;
143 } SystemExceptionReplyBody;
145 typedef struct CancelRequestHeader {
147 } CancelRequestHeader;
149 typedef struct LocateRequestHeader {
151 OctetSequence object_key;
152 } LocateRequestHeader;
154 typedef enum LocateStatusType {
160 typedef struct LocateReplyHeader {
166 u_char *print_object_key(int length, u_char *from)
168 #define MAX_OBJECT_KEY_LENGTH 64
169 static u_char buffer[MAX_OBJECT_KEY_LENGTH];
172 length = MIN(MAX_OBJECT_KEY_LENGTH - 3, length);
174 while(i++ < length) {
175 *to = (isprint(*from)) ? *from : '.';
184 /* main entry point */
186 void dissect_giop(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
189 MessageHeader header;
190 proto_tree *clnp_tree = NULL;
192 u_char response_expected = 0;
193 u_int first_offset = offset;
194 u_int big_endian = FALSE;
195 u_int request_id = 0;
201 u_int sequence_length;
203 RequestHeader_1_1 request_1_1;
204 RequestHeader_1_0 request_1_0;
206 LocateReplyHeader locate_rep;
207 LocateRequestHeader locate_req;
210 #define END_OF_GIOP_MESSAGE (offset - first_offset - GIOP_HEADER_SIZE)
212 if (fd->cap_len < offset + GIOP_HEADER_SIZE) {
213 dissect_data(pd, offset, fd, tree);
217 /* avoid alignment problem */
219 memcpy(&header, &pd[offset], sizeof(header));
221 /* check magic number and version */
223 if (memcmp(header.magic, GIOP_MAGIC, sizeof(header.magic)) != 0) {
224 dissect_data(pd, offset, fd, tree);
228 if (header.GIOP_version.major != GIOP_MAJOR ||
229 ((minor_version = header.GIOP_version.minor) > GIOP_MINOR)) {
230 dissect_data(pd, offset, fd, tree);
234 switch(minor_version) {
236 if (header.flags & 0x01)
252 message_size = pntohl(&header.message_size);
254 message_size = pletohl(&header.message_size);
256 if (check_col(fd, COL_PROTOCOL)) {
257 col_add_str(fd, COL_PROTOCOL, "GIOP");
261 ti = proto_tree_add_item(tree, offset,
262 GIOP_HEADER_SIZE + message_size,
263 "General Inter-ORB Protocol");
264 clnp_tree = proto_tree_new();
265 proto_item_add_subtree(ti, clnp_tree, ETT_GIOP);
266 proto_tree_add_item(clnp_tree, offset, 4,
267 "Magic number: %s", GIOP_MAGIC);
268 proto_tree_add_item(clnp_tree, offset + 4, 2,
270 header.GIOP_version.major,
271 header.GIOP_version.minor);
272 switch(minor_version) {
274 proto_tree_add_item(clnp_tree, offset + 6, 1,
275 "Flags: 0x%02x (%s%s)",
277 (big_endian) ? "little" : "big",
278 (header.flags & 0x02) ? " fragment" : "");
281 proto_tree_add_item(clnp_tree, offset + 6, 1,
282 "Byte ordering: %s endian",
283 (big_endian) ? "little" : "big");
287 } /* minor_version */
289 proto_tree_add_item(clnp_tree, offset + 7, 1,
291 (header.message_type == Request) ? "Request" :
292 (header.message_type == Reply) ? "Reply" :
293 (header.message_type == CancelRequest) ? "CancelRequest" :
294 (header.message_type == LocateRequest) ? "LocateRequest" :
295 (header.message_type == LocateReply) ? "LocateReply" :
296 (header.message_type == CloseConnection) ? "CloseConnection" :
297 (header.message_type == MessageError) ? "MessageError" :
298 (header.message_type == Fragment) ? "Fragment" : "?");
300 proto_tree_add_item(clnp_tree, offset + 8, 4,
301 "Message size: %d", message_size);
305 offset += GIOP_HEADER_SIZE;
307 if (fd->cap_len < offset + message_size) {
308 dissect_data(pd, offset, fd, tree);
312 /* skip service_context in Request/Reply messages */
314 switch(header.message_type) {
319 nr_seq = (big_endian) ? pntohl(&pd[offset]) : pletohl(&pd[offset]);
321 offset += sizeof(nr_seq);
323 for (i = 0 ; i < nr_seq ; i++) {
326 context_id = pntohl(&pd[offset]);
327 sequence_length = pntohl(&pd[offset + sizeof(context_id)]);
330 context_id = pletohl(&pd[offset]);
331 sequence_length = pletohl(&pd[offset + sizeof(context_id)]);
335 proto_tree_add_item(clnp_tree, offset, sizeof(context_id),
336 "Context id: %d", context_id);
337 proto_tree_add_item(clnp_tree, offset + sizeof(context_id),
338 sizeof(sequence_length),
339 "Sequence length: %d", sequence_length);
340 proto_tree_add_item(clnp_tree,
342 sizeof(context_id) + sizeof(sequence_length),
344 "Sequence data: <not shown>");
347 offset += sizeof(context_id) + sizeof(sequence_length) + sequence_length;
348 offset += (sequence_length %4) ? 4 - (sequence_length%4) : 0 ;
355 } /* switch message_type */
357 /* decode next parts according to message type */
359 switch(header.message_type) {
363 switch(minor_version) {
365 memcpy(&request_1_1, &pd[offset], sizeof(request_1_1));
366 response_expected = request_1_1.response_expected;
367 request_id = (big_endian)? pntohl(&request_1_1.request_id) :
368 pletohl(&request_1_1.request_id);
370 proto_tree_add_item(clnp_tree, offset, sizeof(request_id),
371 "Request id: %d", request_id);
372 proto_tree_add_item(clnp_tree, offset + sizeof(request_id),
373 sizeof(request_1_1.response_expected),
374 "Response expected: %d",
376 proto_tree_add_item(clnp_tree, offset + sizeof(request_id) +
377 sizeof(request_1_1.response_expected),
381 offset += sizeof(request_id) +
382 sizeof(request_1_1.response_expected) + 3;
385 memcpy(&request_1_0, &pd[offset], sizeof(request_1_0));
386 response_expected = request_1_0.response_expected;
387 request_id = (big_endian)? pntohl(&request_1_0.request_id) :
388 pletohl(&request_1_0.request_id);
390 proto_tree_add_item(clnp_tree, offset, sizeof(request_id),
391 "Request id: %d", request_id);
392 proto_tree_add_item(clnp_tree, offset + sizeof(request_id),
393 sizeof(request_1_0.response_expected),
394 "Response expected: %d",
398 offset += sizeof(request_id) +
399 sizeof(request_1_0.response_expected);
405 /* strange thing here with some ORBs/IIOP1.0 ? */
406 if ((offset - first_offset) % 4)
407 offset += 4 - (offset - first_offset)%4;
411 sequence_length = (big_endian) ?
412 pntohl(&pd[offset]) : pletohl(&pd[offset]);
415 proto_tree_add_item(clnp_tree, offset, sizeof(sequence_length),
416 "Object key length: %d", sequence_length);
417 proto_tree_add_item(clnp_tree, offset + sizeof(sequence_length),
420 print_object_key(sequence_length,
421 (u_char *)&pd[offset + sizeof(sequence_length)]));
424 /* operation & requesting_principal */
426 offset += sizeof(sequence_length) + sequence_length;
427 offset += (sequence_length %4) ? 4 - (sequence_length%4) : 0 ;
429 sequence_length = (big_endian) ?
430 pntohl(&pd[offset]) : pletohl(&pd[offset]);
432 if (sequence_length > message_size) {
433 dissect_data(pd, offset, fd, tree);
438 proto_tree_add_item(clnp_tree, offset, sizeof(sequence_length),
439 "Operation length: %d", sequence_length);
440 proto_tree_add_item(clnp_tree, offset + sizeof(sequence_length),
443 &pd[offset+sizeof(sequence_length)]);
444 proto_tree_add_item(clnp_tree, offset +
445 sizeof(sequence_length)+ sequence_length,
446 message_size - END_OF_GIOP_MESSAGE -
447 sizeof(sequence_length) - sequence_length,
448 "Requesting principal: <not shown>");
451 if (check_col(fd, COL_INFO)) {
452 col_add_fstr(fd, COL_INFO, "Request %s %d: %s",
453 response_expected ? "two-way" : "one-way" ,
455 &pd[offset+sizeof(sequence_length)]);
462 memcpy(&reply, &pd[offset], sizeof(reply));
463 request_id = (big_endian) ?
464 pntohl(&reply.request_id) : pletohl(&reply.request_id);
465 reply_status = (big_endian) ?
466 pntohl(&reply.reply_status) : pletohl(&reply.reply_status);
469 proto_tree_add_item(clnp_tree, offset, sizeof(request_id),
470 "Request id: %d", request_id);
471 proto_tree_add_item(clnp_tree, offset + sizeof(request_id),
472 sizeof(reply_status),
474 reply_status == NO_EXCEPTION ? "no exception" :
475 reply_status == USER_EXCEPTION ? "user exception" :
476 reply_status == SYSTEM_EXCEPTION ? "system exception" :
477 reply_status == LOCATION_FORWARD ? "location forward" :
481 if (check_col(fd, COL_INFO)) {
482 col_add_fstr(fd, COL_INFO, "Reply %d: %s",
484 reply_status == NO_EXCEPTION ? "no exception" :
485 reply_status == USER_EXCEPTION ? "user exception" :
486 reply_status == SYSTEM_EXCEPTION ? "system exception" :
487 reply_status == LOCATION_FORWARD ? "location forward" :
491 offset += sizeof(request_id) + sizeof(reply_status);
493 if (reply_status == SYSTEM_EXCEPTION) {
495 u_int minor_code_value;
496 u_int completion_status;
498 sequence_length = (big_endian) ?
499 pntohl(&pd[offset]) : pletohl(&pd[offset]);
501 if (sequence_length > message_size) {
502 dissect_data(pd, offset, fd, tree);
507 proto_tree_add_item(clnp_tree, offset, sizeof(sequence_length),
508 "Exception length: %d", sequence_length);
509 proto_tree_add_item(clnp_tree, offset + sizeof(sequence_length),
512 &pd[offset+sizeof(sequence_length)]);
516 offset += sizeof(sequence_length) + sequence_length;
518 minor_code_value = (big_endian) ?
519 pntohl(&pd[offset]) : pletohl(&pd[offset]);
520 completion_status = (big_endian) ?
521 pntohl(&pd[offset+sizeof(minor_code_value)]) :
522 pletohl(&pd[offset+sizeof(minor_code_value)]);
525 proto_tree_add_item(clnp_tree, offset, sizeof(minor_code_value),
526 "Minor code value: %d", minor_code_value);
527 proto_tree_add_item(clnp_tree, offset + sizeof(minor_code_value),
528 sizeof(completion_status),
529 "Completion Status: %d",
535 else if (reply_status == USER_EXCEPTION) {
537 sequence_length = (big_endian) ?
538 pntohl(&pd[offset]) : pletohl(&pd[offset]);
540 if (sequence_length > message_size) {
541 dissect_data(pd, offset, fd, tree);
546 proto_tree_add_item(clnp_tree, offset, sizeof(sequence_length),
547 "Exception length: %d", sequence_length);
548 proto_tree_add_item(clnp_tree, offset + sizeof(sequence_length),
551 &pd[offset+sizeof(sequence_length)]);
555 offset += sizeof(sequence_length) + sequence_length;
557 sequence_length = (big_endian) ?
558 pntohl(&pd[offset]) : pletohl(&pd[offset]);
560 if (sequence_length > message_size) {
561 dissect_data(pd, offset, fd, tree);
565 if (tree && sequence_length) {
566 proto_tree_add_item(clnp_tree, offset, sizeof(sequence_length),
567 "Exception member length: %d", sequence_length);
568 proto_tree_add_item(clnp_tree, offset + sizeof(sequence_length),
570 "Exception member: %s",
571 &pd[offset+sizeof(sequence_length)]);
574 offset += sizeof(sequence_length) + sequence_length;
580 proto_tree_add_item(clnp_tree, offset,
581 message_size - END_OF_GIOP_MESSAGE,
582 "Reply body: <not shown>");
591 memcpy(&locate_req, &pd[offset], sizeof(locate_req));
592 request_id = (big_endian) ?
593 pntohl(&locate_req.request_id) : pletohl(&locate_req.request_id);
595 sequence_length = (big_endian) ?
596 pntohl(&pd[offset+sizeof(request_id)]) :
597 pletohl(&pd[offset+sizeof(request_id)]);
600 proto_tree_add_item(clnp_tree, offset, sizeof(request_id),
601 "Request id: %d", request_id);
602 proto_tree_add_item(clnp_tree, offset + sizeof(request_id),
603 sizeof(sequence_length),
604 "Object key length: %d", sequence_length);
605 offset += sizeof(request_id) + sizeof(sequence_length);
606 proto_tree_add_item(clnp_tree,
610 print_object_key(sequence_length,
611 (u_char *)&pd[offset]));
614 if (check_col(fd, COL_INFO)) {
615 col_add_fstr(fd, COL_INFO, "LocateRequest %d", request_id);
622 memcpy(&locate_rep, &pd[offset], sizeof(locate_rep));
623 request_id = (big_endian) ?
624 pntohl(&locate_rep.request_id) : pletohl(&locate_rep.request_id);
625 locate_status = (big_endian) ?
626 pntohl(&locate_rep.locate_status) : pletohl(&locate_rep.locate_status);
629 proto_tree_add_item(clnp_tree, offset, sizeof(request_id),
630 "Request id: %d", request_id);
631 proto_tree_add_item(clnp_tree, offset + sizeof(request_id),
632 sizeof(locate_status),
633 "Locate status: %d", locate_status);
634 offset += sizeof(request_id) + sizeof(locate_status);
635 if (locate_status == OBJECT_FORWARD) {
636 proto_tree_add_item(clnp_tree, offset,
637 message_size - END_OF_GIOP_MESSAGE,
638 "Locate reply body: <not shown>");
642 if (check_col(fd, COL_INFO)) {
643 col_add_fstr(fd, COL_INFO, "LocateReply %d: %s",
645 (locate_status == UNKNOWN_OBJECT) ? "Unknown object" :
646 (locate_status == OBJECT_HERE) ? "Object here" :
647 (locate_status == OBJECT_FORWARD) ? "Object forward" : "?");
654 request_id = (big_endian) ?
655 pntohl(&pd[offset]) : pletohl(&pd[offset]);
658 proto_tree_add_item(clnp_tree, offset, sizeof(request_id),
659 "Request id: %d", request_id);
662 if (check_col(fd, COL_INFO)) {
663 col_add_fstr(fd, COL_INFO, "CancelRequest %d", request_id);
668 case CloseConnection :
669 if (check_col(fd, COL_INFO)) {
670 col_add_str(fd, COL_INFO, "CloseConnection");
675 if (check_col(fd, COL_INFO)) {
676 col_add_str(fd, COL_INFO, "MessageError");
681 if (check_col(fd, COL_INFO)) {
682 col_add_str(fd, COL_INFO, "Fragment");
689 } /* switch message_type */
692 offset = first_offset + GIOP_HEADER_SIZE + message_size;
694 if (offset < fd->cap_len) {
695 dissect_data(pd, offset, fd, tree);