2 * Routines for CORBA GIOP/IIOP packet disassembly
4 * Laurent Deniel <deniel@worldnet.fr>
6 * $Id: packet-giop.c,v 1.1 1998/11/18 03:04:25 gerald 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.
40 #ifdef HAVE_SYS_TYPES_H
41 # include <sys/types.h>
48 * GIOP / IIOP types definition - OMG CORBA 2.x / GIOP 1.[01]
49 * See OMG WEB site <http://www.omg.org> - CORBA+IIOP 2.2 (98-02-01.ps)
53 * <sequence> : unsigned int (# elts) + elements
54 * <string> : unsigned int (string length) + length characters (with '\0')
55 * <enum> : unsigned int (from 0 to n)
58 #define GIOP_MAGIC "GIOP"
62 #define GIOP_HEADER_SIZE 12
64 typedef struct OctetSequence{
65 u_int sequence_length;
66 u_char sequence_data[1]; /* of length bytes */
69 typedef OctetSequence Principal;
70 typedef OctetSequence String;
73 * Some structures that contain sequences can not be directly used
74 * (alignment problem on 64 bit architectures)
77 typedef struct ServiceContext {
79 OctetSequence context_data;
82 typedef struct ServiceContextList{
84 ServiceContext service_context[1]; /* nr_context elements */
87 typedef enum MsgType {
95 Fragment /* GIOP 1.1 only */
98 typedef struct Version {
103 typedef struct MessageHeader {
105 Version GIOP_version;
106 u_char flags; /* byte_order in 1.0 */
111 typedef struct RequestHeader_1_0 {
112 /* ServiceContextList service_context;*/
114 u_char response_expected;
115 OctetSequence object_key;
116 /* String operation; */
117 /* Principal requesting_principal; */
120 typedef struct RequestHeader_1_1 {
121 /* ServiceContextList service_context;*/
123 u_char response_expected;
125 OctetSequence object_key;
126 /* String operation; */
127 /* Principal requesting_principal; */
130 typedef enum ReplyStatusType {
137 typedef struct ReplyHeader {
138 /* ServiceContext service_context; */
143 typedef struct SystemExceptionReplyBody {
145 u_int minor_code_value;
146 u_int completion_status;
147 } SystemExceptionReplyBody;
149 typedef struct CancelRequestHeader {
151 } CancelRequestHeader;
153 typedef struct LocateRequestHeader {
155 OctetSequence object_key;
156 } LocateRequestHeader;
158 typedef enum LocateStatusType {
164 typedef struct LocateReplyHeader {
170 u_char *print_object_key(int length, u_char *from)
172 #define MAX_OBJECT_KEY_LENGTH 64
173 static u_char buffer[MAX_OBJECT_KEY_LENGTH];
176 length = MIN(MAX_OBJECT_KEY_LENGTH - 3, length);
178 while(i++ < length) {
179 *to = (isprint(*from)) ? *from : '.';
188 /* main entry point */
190 void dissect_giop(const u_char *pd, int offset, frame_data *fd, GtkTree *tree)
193 MessageHeader header;
194 GtkWidget *clnp_tree = NULL, *ti;
195 u_char response_expected = 0;
196 u_int first_offset = offset;
197 u_int big_endian = FALSE;
198 u_int request_id = 0;
204 u_int sequence_length;
206 RequestHeader_1_1 request_1_1;
207 RequestHeader_1_0 request_1_0;
209 LocateReplyHeader locate_rep;
210 LocateRequestHeader locate_req;
213 #define END_OF_GIOP_MESSAGE (offset - first_offset - GIOP_HEADER_SIZE)
215 if (fd->cap_len < offset + GIOP_HEADER_SIZE) {
216 dissect_data(pd, offset, fd, tree);
220 /* avoid alignment problem */
222 memcpy(&header, &pd[offset], sizeof(header));
224 /* check magic number and version */
226 if (memcmp(header.magic, GIOP_MAGIC, sizeof(header.magic)) != 0) {
227 dissect_data(pd, offset, fd, tree);
231 if (header.GIOP_version.major != GIOP_MAJOR ||
232 ((minor_version = header.GIOP_version.minor) > GIOP_MINOR)) {
233 dissect_data(pd, offset, fd, tree);
237 switch(minor_version) {
239 if (header.flags & 0x01)
255 message_size = pntohl(&header.message_size);
257 message_size = pletohl(&header.message_size);
259 if (check_col(fd, COL_PROTOCOL)) {
260 col_add_str(fd, COL_PROTOCOL, "GIOP");
264 ti = add_item_to_tree(GTK_WIDGET(tree), offset,
265 GIOP_HEADER_SIZE + message_size,
266 "General Inter-ORB Protocol");
267 clnp_tree = gtk_tree_new();
268 add_subtree(ti, clnp_tree, ETT_GIOP);
269 add_item_to_tree(clnp_tree, offset, 4,
270 "Magic number: %s", GIOP_MAGIC);
271 add_item_to_tree(clnp_tree, offset + 4, 2,
273 header.GIOP_version.major,
274 header.GIOP_version.minor);
275 switch(minor_version) {
277 add_item_to_tree(clnp_tree, offset + 6, 1,
278 "Flags: 0x%02x (%s%s)",
280 (big_endian) ? "little" : "big",
281 (header.flags & 0x02) ? " fragment" : "");
284 add_item_to_tree(clnp_tree, offset + 6, 1,
285 "Byte ordering: %s endian",
286 (big_endian) ? "little" : "big");
290 } /* minor_version */
292 add_item_to_tree(clnp_tree, offset + 7, 1,
294 (header.message_type == Request) ? "Request" :
295 (header.message_type == Reply) ? "Reply" :
296 (header.message_type == CancelRequest) ? "CancelRequest" :
297 (header.message_type == LocateRequest) ? "LocateRequest" :
298 (header.message_type == LocateReply) ? "LocateReply" :
299 (header.message_type == CloseConnection) ? "CloseConnection" :
300 (header.message_type == MessageError) ? "MessageError" :
301 (header.message_type == Fragment) ? "Fragment" : "?");
303 add_item_to_tree(clnp_tree, offset + 8, 4,
304 "Message size: %d", message_size);
308 offset += GIOP_HEADER_SIZE;
310 if (fd->cap_len < offset + message_size) {
311 dissect_data(pd, offset, fd, tree);
315 /* skip service_context in Request/Reply messages */
317 switch(header.message_type) {
322 nr_seq = (big_endian) ? pntohl(&pd[offset]) : pletohl(&pd[offset]);
324 offset += sizeof(nr_seq);
326 for (i = 0 ; i < nr_seq ; i++) {
329 context_id = pntohl(&pd[offset]);
330 sequence_length = pntohl(&pd[offset + sizeof(context_id)]);
333 context_id = pletohl(&pd[offset]);
334 sequence_length = pletohl(&pd[offset + sizeof(context_id)]);
338 add_item_to_tree(clnp_tree, offset, sizeof(context_id),
339 "Context id: %d", context_id);
340 add_item_to_tree(clnp_tree, offset + sizeof(context_id),
341 sizeof(sequence_length),
342 "Sequence length: %d", sequence_length);
343 add_item_to_tree(clnp_tree,
345 sizeof(context_id) + sizeof(sequence_length),
347 "Sequence data: <not shown>");
350 offset += sizeof(context_id) + sizeof(sequence_length) + sequence_length;
351 offset += (sequence_length %4) ? 4 - (sequence_length%4) : 0 ;
358 } /* switch message_type */
360 /* decode next parts according to message type */
362 switch(header.message_type) {
366 switch(minor_version) {
368 memcpy(&request_1_1, &pd[offset], sizeof(request_1_1));
369 response_expected = request_1_1.response_expected;
370 request_id = (big_endian)? pntohl(&request_1_1.request_id) :
371 pletohl(&request_1_1.request_id);
373 add_item_to_tree(clnp_tree, offset, sizeof(request_id),
374 "Request id: %d", request_id);
375 add_item_to_tree(clnp_tree, offset + sizeof(request_id),
376 sizeof(request_1_1.response_expected),
377 "Response expected: %d",
379 add_item_to_tree(clnp_tree, offset + sizeof(request_id) +
380 sizeof(request_1_1.response_expected),
384 offset += sizeof(request_id) +
385 sizeof(request_1_1.response_expected) + 3;
388 memcpy(&request_1_0, &pd[offset], sizeof(request_1_0));
389 response_expected = request_1_0.response_expected;
390 request_id = (big_endian)? pntohl(&request_1_0.request_id) :
391 pletohl(&request_1_0.request_id);
393 add_item_to_tree(clnp_tree, offset, sizeof(request_id),
394 "Request id: %d", request_id);
395 add_item_to_tree(clnp_tree, offset + sizeof(request_id),
396 sizeof(request_1_0.response_expected),
397 "Response expected: %d",
401 offset += sizeof(request_id) +
402 sizeof(request_1_0.response_expected);
408 /* strange thing here with some ORBs/IIOP1.0 ? */
409 if ((offset - first_offset) % 4)
410 offset += 4 - (offset - first_offset)%4;
414 sequence_length = (big_endian) ?
415 pntohl(&pd[offset]) : pletohl(&pd[offset]);
418 add_item_to_tree(clnp_tree, offset, sizeof(sequence_length),
419 "Object key length: %d", sequence_length);
420 add_item_to_tree(clnp_tree, offset + sizeof(sequence_length),
423 print_object_key(sequence_length,
424 (u_char *)&pd[offset + sizeof(sequence_length)]));
427 /* operation & requesting_principal */
429 offset += sizeof(sequence_length) + sequence_length;
430 offset += (sequence_length %4) ? 4 - (sequence_length%4) : 0 ;
432 sequence_length = (big_endian) ?
433 pntohl(&pd[offset]) : pletohl(&pd[offset]);
435 if (sequence_length > message_size) {
436 dissect_data(pd, offset, fd, tree);
441 add_item_to_tree(clnp_tree, offset, sizeof(sequence_length),
442 "Operation length: %d", sequence_length);
443 add_item_to_tree(clnp_tree, offset + sizeof(sequence_length),
446 &pd[offset+sizeof(sequence_length)]);
447 add_item_to_tree(clnp_tree, offset +
448 sizeof(sequence_length)+ sequence_length,
449 message_size - END_OF_GIOP_MESSAGE -
450 sizeof(sequence_length) - sequence_length,
451 "Requesting principal: <not shown>");
454 if (check_col(fd, COL_INFO)) {
455 col_add_fstr(fd, COL_INFO, "Request %s %d: %s",
456 response_expected ? "two-way" : "one-way" ,
458 &pd[offset+sizeof(sequence_length)]);
465 memcpy(&reply, &pd[offset], sizeof(reply));
466 request_id = (big_endian) ?
467 pntohl(&reply.request_id) : pletohl(&reply.request_id);
468 reply_status = (big_endian) ?
469 pntohl(&reply.reply_status) : pletohl(&reply.reply_status);
472 add_item_to_tree(clnp_tree, offset, sizeof(request_id),
473 "Request id: %d", request_id);
474 add_item_to_tree(clnp_tree, offset + sizeof(request_id),
475 sizeof(reply_status),
477 reply_status == NO_EXCEPTION ? "no exception" :
478 reply_status == USER_EXCEPTION ? "user exception" :
479 reply_status == SYSTEM_EXCEPTION ? "system exception" :
480 reply_status == LOCATION_FORWARD ? "location forward" :
484 if (check_col(fd, COL_INFO)) {
485 col_add_fstr(fd, COL_INFO, "Reply %d: %s",
487 reply_status == NO_EXCEPTION ? "no exception" :
488 reply_status == USER_EXCEPTION ? "user exception" :
489 reply_status == SYSTEM_EXCEPTION ? "system exception" :
490 reply_status == LOCATION_FORWARD ? "location forward" :
494 offset += sizeof(request_id) + sizeof(reply_status);
496 if (reply_status == SYSTEM_EXCEPTION) {
498 u_int minor_code_value;
499 u_int completion_status;
501 sequence_length = (big_endian) ?
502 pntohl(&pd[offset]) : pletohl(&pd[offset]);
504 if (sequence_length > message_size) {
505 dissect_data(pd, offset, fd, tree);
510 add_item_to_tree(clnp_tree, offset, sizeof(sequence_length),
511 "Exception length: %d", sequence_length);
512 add_item_to_tree(clnp_tree, offset + sizeof(sequence_length),
515 &pd[offset+sizeof(sequence_length)]);
519 offset += sizeof(sequence_length) + sequence_length;
521 minor_code_value = (big_endian) ?
522 pntohl(&pd[offset]) : pletohl(&pd[offset]);
523 completion_status = (big_endian) ?
524 pntohl(&pd[offset+sizeof(minor_code_value)]) :
525 pletohl(&pd[offset+sizeof(minor_code_value)]);
528 add_item_to_tree(clnp_tree, offset, sizeof(minor_code_value),
529 "Minor code value: %d", minor_code_value);
530 add_item_to_tree(clnp_tree, offset + sizeof(minor_code_value),
531 sizeof(completion_status),
532 "Completion Status: %d",
538 else if (reply_status == USER_EXCEPTION) {
540 sequence_length = (big_endian) ?
541 pntohl(&pd[offset]) : pletohl(&pd[offset]);
543 if (sequence_length > message_size) {
544 dissect_data(pd, offset, fd, tree);
549 add_item_to_tree(clnp_tree, offset, sizeof(sequence_length),
550 "Exception length: %d", sequence_length);
551 add_item_to_tree(clnp_tree, offset + sizeof(sequence_length),
554 &pd[offset+sizeof(sequence_length)]);
558 offset += sizeof(sequence_length) + sequence_length;
560 sequence_length = (big_endian) ?
561 pntohl(&pd[offset]) : pletohl(&pd[offset]);
563 if (sequence_length > message_size) {
564 dissect_data(pd, offset, fd, tree);
568 if (tree && sequence_length) {
569 add_item_to_tree(clnp_tree, offset, sizeof(sequence_length),
570 "Exception member length: %d", sequence_length);
571 add_item_to_tree(clnp_tree, offset + sizeof(sequence_length),
573 "Exception member: %s",
574 &pd[offset+sizeof(sequence_length)]);
577 offset += sizeof(sequence_length) + sequence_length;
583 add_item_to_tree(clnp_tree, offset,
584 message_size - END_OF_GIOP_MESSAGE,
585 "Reply body: <not shown>");
594 memcpy(&locate_req, &pd[offset], sizeof(locate_req));
595 request_id = (big_endian) ?
596 pntohl(&locate_req.request_id) : pletohl(&locate_req.request_id);
598 sequence_length = (big_endian) ?
599 pntohl(&pd[offset+sizeof(request_id)]) :
600 pletohl(&pd[offset+sizeof(request_id)]);
603 add_item_to_tree(clnp_tree, offset, sizeof(request_id),
604 "Request id: %d", request_id);
605 add_item_to_tree(clnp_tree, offset + sizeof(request_id),
606 sizeof(sequence_length),
607 "Object key length: %d", sequence_length);
608 offset += sizeof(request_id) + sizeof(sequence_length);
609 add_item_to_tree(clnp_tree,
613 print_object_key(sequence_length,
614 (u_char *)&pd[offset]));
617 if (check_col(fd, COL_INFO)) {
618 col_add_fstr(fd, COL_INFO, "LocateRequest %d", request_id);
625 memcpy(&locate_rep, &pd[offset], sizeof(locate_rep));
626 request_id = (big_endian) ?
627 pntohl(&locate_rep.request_id) : pletohl(&locate_rep.request_id);
628 locate_status = (big_endian) ?
629 pntohl(&locate_rep.locate_status) : pletohl(&locate_rep.locate_status);
632 add_item_to_tree(clnp_tree, offset, sizeof(request_id),
633 "Request id: %d", request_id);
634 add_item_to_tree(clnp_tree, offset + sizeof(request_id),
635 sizeof(locate_status),
636 "Locate status: %d", locate_status);
637 offset += sizeof(request_id) + sizeof(locate_status);
638 if (locate_status == OBJECT_FORWARD) {
639 add_item_to_tree(clnp_tree, offset,
640 message_size - END_OF_GIOP_MESSAGE,
641 "Locate reply body: <not shown>");
645 if (check_col(fd, COL_INFO)) {
646 col_add_fstr(fd, COL_INFO, "LocateReply %d: %s",
648 (locate_status == UNKNOWN_OBJECT) ? "Unknown object" :
649 (locate_status == OBJECT_HERE) ? "Object here" :
650 (locate_status == OBJECT_FORWARD) ? "Object forward" : "?");
657 request_id = (big_endian) ?
658 pntohl(&pd[offset]) : pletohl(&pd[offset]);
661 add_item_to_tree(clnp_tree, offset, sizeof(request_id),
662 "Request id: %d", request_id);
665 if (check_col(fd, COL_INFO)) {
666 col_add_fstr(fd, COL_INFO, "CancelRequest %d", request_id);
671 case CloseConnection :
672 if (check_col(fd, COL_INFO)) {
673 col_add_str(fd, COL_INFO, "CloseConnection");
678 if (check_col(fd, COL_INFO)) {
679 col_add_str(fd, COL_INFO, "MessageError");
684 if (check_col(fd, COL_INFO)) {
685 col_add_str(fd, COL_INFO, "Fragment");
692 } /* switch message_type */
695 offset = first_offset + GIOP_HEADER_SIZE + message_size;
697 if (offset < fd->cap_len) {
698 dissect_data(pd, offset, fd, tree);