- fix potential buffer overflow problems.
[obnox/wireshark/wip.git] / packet-giop.c
1 /* packet-giop.c
2  * Routines for CORBA GIOP/IIOP packet disassembly
3  *
4  * Laurent Deniel <deniel@worldnet.fr>
5  *
6  * $Id: packet-giop.c,v 1.17 2000/08/13 14:08:11 deniel Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@zing.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * 
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.
17  * 
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.
22  * 
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.
26  *
27  *
28  */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #ifdef HAVE_SYS_TYPES_H
35 # include <sys/types.h>
36 #endif
37
38 #include <string.h>
39 #include <ctype.h>
40 #include <glib.h>
41 #include "packet.h"
42
43 static int proto_giop = -1;
44 static int hf_giop_message_type = -1;
45 static int hf_giop_message_size = -1;
46
47 static gint ett_giop = -1;
48
49 /*
50  * GIOP / IIOP types definition - OMG CORBA 2.x / GIOP 1.[01]
51  * See OMG WEB site <http://www.omg.org> - CORBA+IIOP 2.2 (98-02-01.ps)
52  *
53  * Notes on mapping:
54  *
55  * <sequence> : unsigned int (# elts) + elements
56  * <string>   : unsigned int (string length) + length characters (with '\0')
57  * <enum>     : unsigned int (from 0 to n)
58  */
59
60 #define GIOP_MAGIC       "GIOP"
61 #define GIOP_MAJOR       1
62 #define GIOP_MINOR       1
63
64 #define GIOP_HEADER_SIZE 12
65
66 typedef struct OctetSequence{
67   u_int         sequence_length;
68   u_char        sequence_data[1];               /* of length bytes */
69 } OctetSequence;
70
71 typedef OctetSequence Principal;
72 typedef OctetSequence String;
73
74 /* 
75  * Some structures that contain sequences can not be directly used 
76  * (alignment problem on 64 bit architectures)
77  */
78
79 typedef struct ServiceContext {
80   u_int         context_id;
81   OctetSequence context_data;
82 } ServiceContext;
83
84 typedef struct ServiceContextList{
85   u_int           nr_context;
86   ServiceContext  service_context[1];           /* nr_context elements */
87 } ServiceContextList;
88
89 typedef enum MsgType {
90   Request,
91   Reply,
92   CancelRequest, 
93   LocateRequest,
94   LocateReply, 
95   CloseConnection,
96   MessageError,
97   Fragment                                      /* GIOP 1.1 only */
98 } MsgType;
99
100 typedef struct Version {
101   u_char        major;
102   u_char        minor;
103 } Version;
104
105 typedef struct MessageHeader {
106   char          magic[4];
107   Version       GIOP_version;
108   u_char        flags;                          /* byte_order in 1.0 */
109   u_char        message_type;
110   u_int         message_size;
111 } MessageHeader;
112
113 typedef struct RequestHeader_1_0 {
114   /* ServiceContextList service_context;*/
115   u_int         request_id;
116   u_char        response_expected;
117   OctetSequence object_key;
118   /* String     operation;              */
119   /* Principal  requesting_principal;   */
120 } RequestHeader_1_0;
121
122 typedef struct RequestHeader_1_1 {
123   /* ServiceContextList service_context;*/
124   u_int         request_id;
125   u_char        response_expected;
126   u_char        reserved[3];
127   OctetSequence object_key;
128   /* String     operation;              */
129   /* Principal  requesting_principal;   */
130 } RequestHeader_1_1;
131
132 typedef enum ReplyStatusType {
133   NO_EXCEPTION, 
134   USER_EXCEPTION, 
135   SYSTEM_EXCEPTION, 
136   LOCATION_FORWARD
137 } ReplyStatusType;
138
139 typedef struct ReplyHeader {
140   /* ServiceContext service_context;    */
141   u_int         request_id;
142   u_int         reply_status;
143 } ReplyHeader;
144
145 typedef struct SystemExceptionReplyBody {
146   String        exception_id; 
147   u_int         minor_code_value;
148   u_int         completion_status;
149 } SystemExceptionReplyBody;
150
151 typedef struct CancelRequestHeader {
152   u_int         request_id;
153 } CancelRequestHeader;
154
155 typedef struct LocateRequestHeader {
156   u_int         request_id;
157   OctetSequence object_key;
158 } LocateRequestHeader;
159
160 typedef enum LocateStatusType {
161   UNKNOWN_OBJECT, 
162   OBJECT_HERE, 
163   OBJECT_FORWARD
164 } LocateStatusType;
165
166 typedef struct LocateReplyHeader {
167   u_int         request_id;
168   u_int         locate_status;
169 } LocateReplyHeader;
170
171
172 static u_char *print_object_key(int length, u_char *from) 
173 {
174 #define MAX_OBJECT_KEY_LENGTH 64
175   static u_char buffer[MAX_OBJECT_KEY_LENGTH];
176   u_char *to = buffer;
177   int i = 0;
178   length = MIN(MAX_OBJECT_KEY_LENGTH - 3, length);
179   *to++ = '"';
180   while(i++ < length) {
181     *to = (isprint(*from)) ? *from : '.'; 
182     to++;
183     from++;
184   }  
185   *to++ = '"';
186   *to = '\0';
187   return buffer;
188 }
189
190 /* main entry point */
191
192 static gboolean
193 dissect_giop(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) 
194 {
195
196   MessageHeader header;
197   proto_tree *clnp_tree = NULL;
198   proto_item *ti;
199   u_char response_expected = 0;
200   u_int first_offset = offset;
201   u_int big_endian = FALSE;
202   u_int request_id = 0;
203   u_int message_size;
204   u_int minor_version;
205   u_int context_id;
206   u_int reply_status;
207   u_int locate_status;
208   u_int sequence_length;
209   u_int nr_seq;
210   RequestHeader_1_1 request_1_1;
211   RequestHeader_1_0 request_1_0;
212   ReplyHeader reply;
213   LocateReplyHeader locate_rep;
214   LocateRequestHeader locate_req;
215   int i;
216
217   if (!proto_is_protocol_enabled(proto_giop))
218     return FALSE;
219
220 #define END_OF_GIOP_MESSAGE (offset - first_offset - GIOP_HEADER_SIZE)
221
222   if (!BYTES_ARE_IN_FRAME(offset, GIOP_HEADER_SIZE)) {
223     /* Not enough data, or not enough captured data; perhaps it was
224        a GIOP message, but we can't tell. */
225     return FALSE;
226   }
227
228   /* avoid alignment problem */
229
230   memcpy(&header, &pd[offset], sizeof(header));
231
232   /* check magic number and version */
233
234   if (memcmp(header.magic, GIOP_MAGIC, sizeof(header.magic)) != 0) {
235     /* Not a GIOP message. */
236     return FALSE;
237   }
238
239   if (check_col(fd, COL_PROTOCOL)) {
240     col_add_str(fd, COL_PROTOCOL, "GIOP");
241   }
242
243
244   if (header.GIOP_version.major != GIOP_MAJOR ||
245       ((minor_version = header.GIOP_version.minor) >  GIOP_MINOR)) {
246     /* Bad version number; should we note that and dissect the rest
247        as data, or should we return FALSE on the theory that it
248        might have been some other packet that happened to begin with
249        "GIOP"? */
250     if (check_col(fd, COL_INFO)) {
251       col_add_fstr(fd, COL_INFO, "Version %d.%d",
252                 header.GIOP_version.major, header.GIOP_version.minor);
253     }
254     if (tree) {
255       ti = proto_tree_add_item(tree, proto_giop, NullTVB, offset, 
256                           GIOP_HEADER_SIZE, FALSE);
257       clnp_tree = proto_item_add_subtree(ti, ett_giop);
258       proto_tree_add_text(clnp_tree, NullTVB, offset, GIOP_HEADER_SIZE,
259                 "Version %d.%d not supported", 
260                 header.GIOP_version.major, header.GIOP_version.minor);
261     }
262     old_dissect_data(pd, offset + GIOP_HEADER_SIZE, fd, tree);
263     return TRUE;
264   }
265
266   switch(minor_version) {
267     case 1  :
268       if (header.flags & 0x01)
269         big_endian = FALSE;
270       else
271         big_endian = TRUE;
272       break;
273     case 0  :
274       if (header.flags)
275         big_endian = FALSE;
276       else
277         big_endian = TRUE;
278       break;
279     default :
280       break;
281   }
282   
283   if (big_endian)
284     message_size = pntohl(&header.message_size);
285   else
286     message_size = pletohl(&header.message_size);
287
288   if (tree) {
289     ti = proto_tree_add_item(tree, proto_giop, NullTVB, offset, 
290                           GIOP_HEADER_SIZE + message_size, FALSE);
291     clnp_tree = proto_item_add_subtree(ti, ett_giop);
292     proto_tree_add_text(clnp_tree, NullTVB, offset,      4,
293                      "Magic number: %s", GIOP_MAGIC);
294     proto_tree_add_text(clnp_tree, NullTVB, offset +  4, 2, 
295                      "Version: %d.%d", 
296                      header.GIOP_version.major,
297                      header.GIOP_version.minor);
298     switch(minor_version) {
299       case 1  :
300         proto_tree_add_text(clnp_tree, NullTVB, offset +  6, 1, 
301                          "Flags: 0x%02x (%s%s)", 
302                          header.flags,
303                          (big_endian) ? "little" : "big",
304                          (header.flags & 0x02) ? " fragment" : "");
305         break;
306       case 0  :
307         proto_tree_add_text(clnp_tree, NullTVB, offset +  6, 1, 
308                          "Byte ordering: %s endian",
309                          (big_endian) ? "little" : "big");
310         break;
311       default :
312         break;
313     } /* minor_version */
314
315     proto_tree_add_uint_format(clnp_tree, 
316                                hf_giop_message_type,
317                                NullTVB, offset +  7, 1, 
318                                header.message_type,
319                                "Message type: %s",
320                                (header.message_type == Request) ? "Request" :
321                                (header.message_type == Reply) ? "Reply" :
322                                (header.message_type == CancelRequest) ? "CancelRequest" :
323                                (header.message_type == LocateRequest) ? "LocateRequest" :
324                                (header.message_type == LocateReply) ? "LocateReply" :
325                                (header.message_type == CloseConnection) ? "CloseConnection" :
326                                (header.message_type == MessageError) ? "MessageError" :
327                                (header.message_type == Fragment) ? "Fragment" : "?");
328
329     proto_tree_add_uint(clnp_tree, 
330                         hf_giop_message_size,
331                         NullTVB, offset +  8, 4, 
332                         message_size);
333
334   } /* tree */
335
336   offset += GIOP_HEADER_SIZE;
337
338   if (!BYTES_ARE_IN_FRAME(offset, message_size)) {
339     old_dissect_data(pd, offset, fd, tree);
340     return TRUE;
341   }
342
343   /* skip service_context in Request/Reply messages */
344
345   switch(header.message_type) {
346
347     case Request:
348     case Reply :
349
350       nr_seq = (big_endian) ? pntohl(&pd[offset]) : pletohl(&pd[offset]);
351
352       offset += sizeof(nr_seq);
353
354       for (i = 0 ; i < nr_seq ; i++) {
355
356         if (big_endian) {       
357           context_id = pntohl(&pd[offset]);
358           sequence_length = pntohl(&pd[offset + sizeof(context_id)]);
359         }
360         else {
361           context_id = pletohl(&pd[offset]);
362           sequence_length = pletohl(&pd[offset + sizeof(context_id)]);
363         }
364
365         if (tree) {
366           proto_tree_add_text(clnp_tree, NullTVB, offset, sizeof(context_id),
367                            "Context id: %d", context_id);
368           proto_tree_add_text(clnp_tree, NullTVB, offset + sizeof(context_id),
369                            sizeof(sequence_length),
370                            "Sequence length: %d", sequence_length);
371           proto_tree_add_text(clnp_tree, NullTVB,
372                            offset + 
373                            sizeof(context_id) + sizeof(sequence_length),
374                            sequence_length,
375                            "Sequence data: <not shown>");
376         }
377
378         offset += sizeof(context_id) + sizeof(sequence_length) + sequence_length;
379         offset += (sequence_length %4) ? 4 - (sequence_length%4) : 0 ;
380
381       } /* for */
382
383     default :
384       break;
385
386   } /* switch message_type */
387
388   /* decode next parts according to message type */
389
390   switch(header.message_type) {
391
392     case Request:
393
394       switch(minor_version) {
395         case 1  :
396           memcpy(&request_1_1, &pd[offset], sizeof(request_1_1));
397           response_expected = request_1_1.response_expected;
398           request_id = (big_endian)? pntohl(&request_1_1.request_id) :
399             pletohl(&request_1_1.request_id);
400           if (tree) {
401             proto_tree_add_text(clnp_tree, NullTVB, offset, sizeof(request_id),
402                              "Request id: %d", request_id);
403             proto_tree_add_text(clnp_tree, NullTVB, offset + sizeof(request_id),
404                              sizeof(request_1_1.response_expected),
405                              "Response expected: %d", 
406                              response_expected);
407             proto_tree_add_text(clnp_tree, NullTVB, offset + sizeof(request_id) +
408                              sizeof(request_1_1.response_expected),
409                              3,
410                              "Reserved");
411           }
412           offset += sizeof(request_id) + 
413             sizeof(request_1_1.response_expected) + 3;
414           break;
415         case 0  :
416           memcpy(&request_1_0, &pd[offset], sizeof(request_1_0));
417           response_expected = request_1_0.response_expected;
418           request_id = (big_endian)? pntohl(&request_1_0.request_id) :
419             pletohl(&request_1_0.request_id);
420           if (tree) {
421             proto_tree_add_text(clnp_tree, NullTVB, offset, sizeof(request_id),
422                              "Request id: %d", request_id);
423             proto_tree_add_text(clnp_tree, NullTVB, offset + sizeof(request_id),
424                              sizeof(request_1_0.response_expected),
425                              "Response expected: %d", 
426                              response_expected);
427           }
428
429           offset += sizeof(request_id) + 
430             sizeof(request_1_0.response_expected);
431           break;
432         default :
433           break;
434       }
435
436       /* strange thing here with some ORBs/IIOP1.0 ? */
437       if ((offset - first_offset) % 4)
438         offset += 4 - (offset - first_offset)%4;
439
440       /* object_key */
441
442       sequence_length = (big_endian) ? 
443         pntohl(&pd[offset]) : pletohl(&pd[offset]);
444
445       if (tree) {
446         proto_tree_add_text(clnp_tree, NullTVB, offset, sizeof(sequence_length),
447                          "Object key length: %d", sequence_length);
448         proto_tree_add_text(clnp_tree, NullTVB, offset + sizeof(sequence_length),
449                          sequence_length,
450                          "Object key: %s",
451                          print_object_key(sequence_length, 
452                            (u_char *)&pd[offset + sizeof(sequence_length)]));
453       }
454
455       /* operation & requesting_principal */
456
457       offset += sizeof(sequence_length) + sequence_length;
458       offset += (sequence_length %4) ? 4 - (sequence_length%4) : 0 ;
459
460       sequence_length = (big_endian) ? 
461         pntohl(&pd[offset]) : pletohl(&pd[offset]);
462
463       if (sequence_length > message_size) {
464         old_dissect_data(pd, offset, fd, tree);
465         return TRUE;
466       }
467        
468       if (tree) {
469         proto_tree_add_text(clnp_tree, NullTVB, offset, sizeof(sequence_length),
470                          "Operation length: %d", sequence_length);
471         proto_tree_add_text(clnp_tree, NullTVB, offset + sizeof(sequence_length), 
472                          sequence_length,
473                          "Operation: %s",
474                          &pd[offset+sizeof(sequence_length)]);
475         proto_tree_add_text(clnp_tree, NullTVB, offset +
476                          sizeof(sequence_length)+ sequence_length,
477                          message_size - END_OF_GIOP_MESSAGE - 
478                          sizeof(sequence_length) - sequence_length,
479                          "Requesting principal: <not shown>");
480       }
481
482       if (check_col(fd, COL_INFO)) {
483         col_add_fstr(fd, COL_INFO, "Request %s %d: %s",
484                 response_expected ? "two-way" : "one-way" ,
485                 request_id,
486                 &pd[offset+sizeof(sequence_length)]);
487       }
488
489       break;
490
491     case Reply :
492
493       memcpy(&reply, &pd[offset], sizeof(reply));
494       request_id =  (big_endian) ? 
495         pntohl(&reply.request_id) : pletohl(&reply.request_id);
496       reply_status = (big_endian) ? 
497         pntohl(&reply.reply_status) : pletohl(&reply.reply_status);
498
499       if (tree) {
500         proto_tree_add_text(clnp_tree, NullTVB, offset, sizeof(request_id),
501                          "Request id: %d", request_id);
502         proto_tree_add_text(clnp_tree, NullTVB, offset + sizeof(request_id), 
503                          sizeof(reply_status),
504                          "Reply status: %s",
505                          reply_status == NO_EXCEPTION ? "no exception" :
506                          reply_status == USER_EXCEPTION ? "user exception" :
507                          reply_status == SYSTEM_EXCEPTION ? "system exception" :
508                          reply_status == LOCATION_FORWARD ? "location forward" :
509                          "?");
510       }
511
512       if (check_col(fd, COL_INFO)) {
513         col_add_fstr(fd, COL_INFO, "Reply %d: %s",
514                 request_id,
515                 reply_status == NO_EXCEPTION ? "no exception" :
516                 reply_status == USER_EXCEPTION ? "user exception" :
517                 reply_status == SYSTEM_EXCEPTION ? "system exception" :
518                 reply_status == LOCATION_FORWARD ? "location forward" :
519                 "?");
520       }
521
522       offset += sizeof(request_id) + sizeof(reply_status);
523
524       if (reply_status == SYSTEM_EXCEPTION) {
525
526         u_int minor_code_value;
527         u_int completion_status;
528
529         sequence_length = (big_endian) ? 
530           pntohl(&pd[offset]) : pletohl(&pd[offset]);
531
532         if (sequence_length > message_size) {
533           old_dissect_data(pd, offset, fd, tree);
534           return TRUE;
535         }
536
537         if (tree) {
538           proto_tree_add_text(clnp_tree, NullTVB, offset, sizeof(sequence_length),
539                            "Exception length: %d", sequence_length);
540           proto_tree_add_text(clnp_tree, NullTVB, offset + sizeof(sequence_length), 
541                            sequence_length,
542                            "Exception id: %s",
543                            &pd[offset+sizeof(sequence_length)]);
544
545         }
546
547         offset += sizeof(sequence_length) + sequence_length;
548
549         minor_code_value = (big_endian) ? 
550           pntohl(&pd[offset]) : pletohl(&pd[offset]);
551         completion_status = (big_endian) ? 
552           pntohl(&pd[offset+sizeof(minor_code_value)]) :
553           pletohl(&pd[offset+sizeof(minor_code_value)]);
554         
555         if (tree) {
556           proto_tree_add_text(clnp_tree, NullTVB, offset, sizeof(minor_code_value),
557                            "Minor code value: %d", minor_code_value);
558           proto_tree_add_text(clnp_tree, NullTVB, offset + sizeof(minor_code_value),
559                            sizeof(completion_status),
560                            "Completion Status: %d",
561                            completion_status);
562           
563         }
564
565       }
566       else if (reply_status == USER_EXCEPTION) {
567
568         sequence_length = (big_endian) ? 
569           pntohl(&pd[offset]) : pletohl(&pd[offset]);
570
571         if (sequence_length > message_size) {
572           old_dissect_data(pd, offset, fd, tree);
573           return TRUE;
574         }
575
576         if (tree) {
577           proto_tree_add_text(clnp_tree, NullTVB, offset, sizeof(sequence_length),
578                            "Exception length: %d", sequence_length);
579           proto_tree_add_text(clnp_tree, NullTVB, offset + sizeof(sequence_length), 
580                            sequence_length,
581                            "Exception id: %s",
582                            &pd[offset+sizeof(sequence_length)]);
583
584         }
585
586         offset += sizeof(sequence_length) + sequence_length;
587
588         sequence_length = (big_endian) ? 
589           pntohl(&pd[offset]) : pletohl(&pd[offset]);
590
591         if (sequence_length > message_size) {
592           old_dissect_data(pd, offset, fd, tree);
593           return TRUE;
594         }
595
596         if (tree && sequence_length) {
597           proto_tree_add_text(clnp_tree, NullTVB, offset, sizeof(sequence_length),
598                            "Exception member length: %d", sequence_length);
599           proto_tree_add_text(clnp_tree, NullTVB, offset + sizeof(sequence_length), 
600                            sequence_length,
601                            "Exception member: %s",
602                            &pd[offset+sizeof(sequence_length)]);
603         }
604
605         offset += sizeof(sequence_length) + sequence_length;
606
607       }
608       else {
609         
610         if (tree) {
611           proto_tree_add_text(clnp_tree, NullTVB, offset,
612                            message_size - END_OF_GIOP_MESSAGE,
613                            "Reply body: <not shown>");
614         }
615
616       } /* reply_status */
617
618       break;
619
620     case LocateRequest :
621
622       memcpy(&locate_req, &pd[offset], sizeof(locate_req));
623       request_id =  (big_endian) ? 
624         pntohl(&locate_req.request_id) : pletohl(&locate_req.request_id);
625
626       sequence_length = (big_endian) ? 
627         pntohl(&pd[offset+sizeof(request_id)]) : 
628         pletohl(&pd[offset+sizeof(request_id)]);
629
630       if (tree) {
631         proto_tree_add_text(clnp_tree, NullTVB, offset, sizeof(request_id),
632                          "Request id: %d", request_id);
633         proto_tree_add_text(clnp_tree, NullTVB, offset + sizeof(request_id), 
634                          sizeof(sequence_length),
635                          "Object key length: %d", sequence_length);
636         offset += sizeof(request_id) + sizeof(sequence_length);
637         proto_tree_add_text(clnp_tree, NullTVB,
638                          offset,
639                          sequence_length,
640                          "Object key: %s", 
641                          print_object_key(sequence_length, 
642                                           (u_char *)&pd[offset]));
643       }
644
645       if (check_col(fd, COL_INFO)) {
646         col_add_fstr(fd, COL_INFO, "LocateRequest %d", request_id);
647       }
648
649       break;
650
651     case LocateReply :
652
653       memcpy(&locate_rep, &pd[offset], sizeof(locate_rep));
654       request_id =  (big_endian) ? 
655         pntohl(&locate_rep.request_id) : pletohl(&locate_rep.request_id);
656       locate_status = (big_endian) ? 
657         pntohl(&locate_rep.locate_status) : pletohl(&locate_rep.locate_status);
658
659       if (tree) {
660         proto_tree_add_text(clnp_tree, NullTVB, offset, sizeof(request_id),
661                          "Request id: %d", request_id);
662         proto_tree_add_text(clnp_tree, NullTVB, offset + sizeof(request_id), 
663                          sizeof(locate_status),
664                          "Locate status: %d", locate_status);
665         offset += sizeof(request_id) + sizeof(locate_status);
666         if (locate_status == OBJECT_FORWARD) {
667           proto_tree_add_text(clnp_tree, NullTVB, offset,
668                            message_size - END_OF_GIOP_MESSAGE,
669                            "Locate reply body: <not shown>");
670         }
671       }
672
673       if (check_col(fd, COL_INFO)) {
674         col_add_fstr(fd, COL_INFO, "LocateReply %d: %s",
675                 request_id, 
676                 (locate_status == UNKNOWN_OBJECT) ? "Unknown object" :
677                 (locate_status == OBJECT_HERE) ? "Object here" :
678                 (locate_status == OBJECT_FORWARD) ? "Object forward" : "?");
679       }
680
681       break;
682
683     case CancelRequest :
684
685       request_id =  (big_endian) ? 
686         pntohl(&pd[offset]) : pletohl(&pd[offset]);
687
688       if (tree) {
689         proto_tree_add_text(clnp_tree, NullTVB, offset, sizeof(request_id),
690                          "Request id: %d", request_id);
691       }
692
693       if (check_col(fd, COL_INFO)) {
694         col_add_fstr(fd, COL_INFO, "CancelRequest %d", request_id);
695       }
696
697       break;
698
699     case CloseConnection :
700       if (check_col(fd, COL_INFO)) {
701         col_add_str(fd, COL_INFO, "CloseConnection");
702       }
703       break;
704
705     case MessageError :
706       if (check_col(fd, COL_INFO)) {
707         col_add_str(fd, COL_INFO, "MessageError");
708       }
709       break;
710
711     case Fragment :
712       if (check_col(fd, COL_INFO)) {
713         col_add_str(fd, COL_INFO, "Fragment");
714       }
715       break;
716
717     default :
718       break;
719
720   } /* switch message_type */
721
722
723   offset = first_offset + GIOP_HEADER_SIZE + message_size;
724
725   if (IS_DATA_IN_FRAME(offset)) {
726     old_dissect_data(pd, offset, fd, tree);
727   }
728
729   return TRUE;
730 } /* dissect_giop */
731
732 void 
733 proto_register_giop(void)
734 {
735   static hf_register_info hf[] = {
736     { &hf_giop_message_type,
737       { "Message type",         "giop.type",    FT_UINT8,       BASE_DEC, NULL, 0x0,
738         "" }},
739     { &hf_giop_message_size,
740       { "Message size",         "giop.len",     FT_UINT32,      BASE_DEC, NULL, 0x0,
741         "" }},
742   };
743   static gint *ett[] = {
744     &ett_giop,
745   };
746
747   proto_giop = proto_register_protocol("General Inter-ORB Protocol", "giop");
748   proto_register_field_array(proto_giop, hf, array_length(hf));
749   proto_register_subtree_array(ett, array_length(ett));
750 }
751
752 void
753 proto_reg_handoff_giop(void)
754 {
755   old_heur_dissector_add("tcp", dissect_giop);
756 }