2 * Routines for CORBA GIOP/IIOP packet disassembly
5 * Laurent Deniel <deniel@worldnet.fr>
6 * Craig Rodrigues <rodrigc@mediaone.net>
8 * GIOP API extensions by,
9 * Frank Singleton <frank.singleton@ericsson.com>
10 * Trevor Shepherd <eustrsd@am1.ericsson.se>
12 * $Id: packet-giop.c,v 1.35 2001/06/18 05:27:16 guy Exp $
14 * Ethereal - Network traffic analyzer
15 * By Gerald Combs <gerald@ethereal.com>
16 * Copyright 1998 Gerald Combs
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 * 1. heuristic giop dissector table [started]
39 * 2. GUI options, see 20
40 * 3. Remove unneccessary reply_status in heuristic dissector calls (now
41 * part of MessageHeader) [done]
42 * 4. get_CDR_xxx should be passed an alignment offset value
43 * rather than GIOP_HEADER_SIZE, as alignment can also change in a
44 * octet stream when eg: encapsulation is used [done]
45 * 5. GIOP users should eventually get there own tvbuff, and
46 * not rely on the GIOP tvbuff, more robust
47 * 6. get_CDR_string,wchar,wstring etc should handle different
48 * GIOP versions [started]
49 * 7. Fix situation where req_id is not unique in a logfile [done, use FN/MFN, needs improving.]
51 * 8. Keep request_1_2 in step with request_1_1 [started]
52 * 9. Explicit module name dissection [done]
53 * 10. Decode IOR and put in a useful struct [IOR decode started]
54 * 11. Fix encapsulation of IOR etc and boundary [done]
55 * 12. handle get_CDR_typeCode() [started]
56 * 13. Handle different IOR profiles
57 * 14. Change printable_string to RETURN a new string, not to modify the old.
58 * or, new function, make_printable_string [done, make_printable_string]
60 * 15. Handle "TCKind", and forget about eg: enum translation to symbolic values
61 * otherwise need knowledge of sub dissectors data - YUK [done]
62 * 16. Handle multiple RepoId representations, besides IDL:Echo:1.0 (see 13.)
63 * 17. Pass subset of RepoID to explicit dissector.
64 * eg : If IDL:Mod1/Mod2/Int3:1.0 then pass "Mod1/Mode2/Int3" to sub dissector[done]
65 * 18. Better hashing algorithms
66 * 19. Handle hash collision properly .
67 * 20. Allow users to paste a stringified IOR into the GUI, and tie it
69 * 21. Add complete_request_packet_list and complete_reply_packet_hash.[done]
70 * 22. Handle case where users click in any order, AND try and match
71 * REPLY msg to the correct REQUEST msg when we have a request_id collision.[done]
72 * 23. Clean up memory management for all those g_malloc's etc
73 * 24. register_giop_user_module could return a key for every distinct Module/Interface
74 * the sub_dissector uses. So, instead of strcmp()'s when handling the
75 * namespace of an operation, we could have a lookup table instead.
76 * 25. A few typedefs in the right place.
77 * 26 Improve handling of gchar * and use const gchar * where possible.
78 * 27. Read/write IOR etc to/from file, allows objkey hash to be built from
79 * external data [read done, write incomplete]
80 * 28. Call sub dissector only if tvb_offset_exists(). [Done, this is checked
81 * inside try_explicit_giop_dissector() ]
83 * 29. Make add/delete routine for objkey hash as it may be useful when say reading
84 * stringified IOR's from a file to add them to our hash. ie: There are other ways
85 * to populate our object key hash besides REPLY's to RESOLVE(request) [done]
87 * 30. Add routine to encode/decode stringified IOR's [decode done]
88 * 31. Add routine to read IOR's from file [done]
89 * 32. TypeCode -none-, needs decoding.
90 * 33. Complete dissect_data_for_typecode.
91 * 34. For complex TypeCodes need to check final offset against original offset + sequence length.
92 * 35. Update REQUEST/REPLY 1_2 according to IDL (eg; ServiceContextList etc).
93 * 36. Adding decode_ServiceContextList, incomplete.
94 * 37. Helper functions should not ALWAYS rely on header to find current endianess. It should
95 * be passed from user, eg Use stream_is_big_endian. [started]
96 * 38. Remove unwanted/unused function parameters, see decode_IOR [started]
97 * 40. Add sequence <IOP::TaggedComponent> components to IIOP IOR profile. Perhaps
98 * decode_IOP_TaggedComponents as a helper function. [done - NOT helper]
100 * 41. Make important field searchable from Message header. ie: Remove add_text_
101 * 42. Use sub-tree for decode_ServiceContextList, looks better.
102 * 43. dissect_reply_body, no exception dissector calls
103 * - call subdiss directly, as we already have handle.
104 * - add repoid to heuristic call also.
106 * 44. typedef using xxx_t in .h file.
107 * 45. Subdissectors should not be passed MessageHeader to find endianness and
108 * version, they should be passed directly ?
109 * 46. get_CDR_wchar and wstring need wide chars decoded (just dumped in
110 * any readable form at present, not handled well at all, suggestions welcome -- FS
111 * 47. Change ...add_text to ...add_xxx (ie use hf fields).
113 * 48. BUG - file load with a GIOP filter set, causes the FN/MFN data struct to be
114 * not initiated properly. Hit "Reload" as a workaround, til I fix this -- FS
121 * Intended Decode strategy:
122 * =========================
126 * REQUEST: objkey -> Repo_ID -> Module/Interface -> giop_sub_handle_t
127 * and populate complete_request_packet_hash
129 * REPLY: FN -> MFN (via complete_reply_packet_hash) = Request FN -> giop_sub_handle_t
134 * REQUEST: FN -> giop_sub_handle_t directly (via complete_request_packet_hash)
136 * REPLY: FN -> MFN (via complete_reply_packet_hash) = Request FN -> giop_sub_handle_t
137 * (via complete_request_packet_hash
143 * 1. Request_ID's are unique only per connection.
145 * 2. You must be monitoring the network when the client does
146 * a REQUEST(resolve), otherwise I have no knowledge of the
147 * association between object_key and REPOID. I could talk to
148 * a Nameserver, but then I would start "generating" packets.
149 * This is probably not a good thing for a protocol analyser.
150 * Also, how could I decode logfiles offline.
152 * TODO -- Read stringified IORs from an input file.[done]
154 * 3. User clicks (REQUEST) is currently handle the same as
155 * the initial pass handling.
157 * ie: objkey -> Repo_ID -> Module/Interface -> giop_sub_handle_t
162 * Important Data Structures:
167 * This is a hash table that maps IDL Module/Interface Names (Key)
168 * to sub_dissector handles, giop_sub_handle_t. It is populated
169 * by subdissectors, via register_giop_user_module(). This
170 * table is used when we have a REPOID, and explicitly wish to
171 * call the subdissector that has registered responsibility for
172 * that IDL module/interface.
178 * This singly linked list is used to hold entries for
179 * heuristic based subdissectors. It is populated by sub_dissectors
180 * wishing to be called via heuristic mechanisms. They do this
181 * via the register_giop_user() function.
187 * This hash table maps object_key's (key) onto REPOID's (val).
188 * Once a client has REQUEST(resolve) an object , it knows about
189 * an object (interface) via its object_key (see IOR). So in order to follow
190 * packets that contain an object_key only, and to be able to forward it
191 * to the correct explicit subdissector, we need this table.
193 * So, I listen in on REQUEST(resolve) messages between client and
194 * Nameserver, and store the respones (REPLY/Objkey,Repo_ID) here.
196 * Also, stringified IOR's can be read from a file "IOR.txt" and used
197 * to populate this hash also.
200 * Other Data structures
201 * =======================
203 * These structures have been added to minimise the possibility
204 * of incorrectly interpreted packets when people click all
205 * over the place, in no particular order, when the request_id's are
206 * not unique as captured. If all request_is'd are unique, as captured, then
207 * we would not have to deal with this problem.
210 * When the logfile or packets are initially being processed, I will
211 * build 2 structures. The intent is to be able to map a REPLY message
212 * back to the most recent REQUEST message with the same Request_ID
213 * (TODO and matching port and IP address ??)
219 * MFN - Matching Frame Number
222 * complete_request_packet_list
223 * ----------------------------
225 * This is a list that contains ALL the FN's that are REQUEST's, along with
226 * operation,request_id and giop_sub_handle_t
228 * complete_reply_packet_hash
229 * --------------------------
231 * This is a hash table. It is populated with FN (key) and MFN (val).
232 * This allows me to handle the case, where if you click on any REPLY
233 * message, I can lookup the matching request. This can improve
234 * the match rate between REQUEST and REPLY when people click in
235 * any old fashion, but is NOT foolproof.
237 * The algorithm I use to populate this hash during initial pass,
240 * If packet is a REPLY, note the reqid, and then traverse backwards
241 * through the complete_request_packet_list from its tail, looking
242 * for a FN that has the same Request_id. Once found, take the found FN
243 * from complete_reply_packet_hash, and insert it into the MFN field
244 * of the complete_reply_packet_hash.
247 * See TODO for improvements to above algorithm.
249 * So now when people click on a REQUEST packet, I can call lookup the
250 * giop_sub_handle_t directly from complete_request_packet_list.
252 * And, when they click on a REPLY, I grab the MFN of this FN from
253 * complete_reply_packet_hash, then look that up in the complete_request_packet_list
254 * and call the sub_dissector directly.
256 * So, how do I differentiate between the initial processing of incoming
257 * packets, and a user clickin on one ? Good question.
259 * I leverage the pinfo_fd->flags.visited on a per frame
262 * To quote from the ever helpful development list
264 * " When a capture file is initially loaded, all "visited" flags
265 * are 0. Ethereal then makes the first pass through file,
266 * sequentially dissecting each packet. After the packet is
267 * dissected the first time, "visited" is 1. (See the end of
268 * dissect_packet() in epan/packet.c; that's the code that
269 * sets "visited" to 1).
271 * By the time a user clicks on a packet, "visited" will already
272 * be 1 because Ethereal will have already done its first pass
273 * through the packets.
275 * Reload acts just like a normal Close/Open, except that it
276 * doesn't need to ask for a filename. So yes, the reload button
277 * clears the flags and re-dissects the file, just as if the file
278 * had been "opened". "
287 #ifdef HAVE_SYS_TYPES_H
288 # include <sys/types.h>
297 #include "strerror.h"
300 #include "packet-giop.h"
303 * This affects how we handle context_data inside ServiceContext structs.
304 * According to CORBA 2.4.2, Context data is encapsulated in octet sequences,
305 * but so far I haven't seen the that on the wire. But, maybe its me -- FS
309 #define CONTEXT_DATA_IS_ENCAPSULATED 0
313 * Set to 1 for DEBUG output
319 * To allow calling (or not) of subdissectors, for testing buggy stuff.
322 #define DEBUG_CALL_SUB_DISSECTORS 1
326 * ------------------------------------------------------------------------------------------+
327 * Private Helper function Declarations
328 * ------------------------------------------------------------------------------------------+
332 static void decode_IIOP_IOR_profile(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset,
333 guint32 boundary, gboolean new_endianess, gchar *repobuf,
334 gboolean store_flag);
336 static void decode_ServiceContextList(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset,
337 gboolean stream_is_be, guint32 boundary);
339 static void decode_TaggedProfile(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset,
340 guint32 boundary, gboolean stream_is_big_endian, gchar *repobuf);
342 static void decode_IOR(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset,
343 guint32 boundary, gboolean stream_is_big_endian );
345 static void decode_SystemExceptionReplyBody (tvbuff_t *tvb, proto_tree *tree, gint *offset,
346 gboolean stream_is_big_endian,
349 static void dissect_tk_objref_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
350 gboolean stream_is_big_endian, guint32 boundary,
351 MessageHeader * header);
353 static void dissect_tk_struct_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
354 gboolean stream_is_big_endian, guint32 boundary,
355 MessageHeader * header);
357 static void dissect_tk_union_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
358 gboolean stream_is_big_endian, guint32 boundary,
359 MessageHeader * header );
361 static void dissect_tk_enum_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
362 gboolean stream_is_big_endian, guint32 boundary,
363 MessageHeader * header);
365 static void dissect_tk_sequence_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
366 gboolean stream_is_big_endian, guint32 boundary,
367 MessageHeader * header);
369 static void dissect_tk_array_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
370 gboolean stream_is_big_endian, guint32 boundary,
371 MessageHeader * header);
373 static void dissect_tk_alias_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
374 gboolean stream_is_big_endian, guint32 boundary,
375 MessageHeader * header);
377 static void dissect_tk_except_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
378 gboolean stream_is_big_endian, guint32 boundary,
379 MessageHeader * header);
381 static void dissect_tk_value_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
382 gboolean stream_is_big_endian, guint32 boundary,
383 MessageHeader * header);
385 static void dissect_tk_value_box_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
386 gboolean stream_is_big_endian, guint32 boundary,
387 MessageHeader * header);
389 static void dissect_tk_native_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
390 gboolean stream_is_big_endian, guint32 boundary,
391 MessageHeader * header);
393 static void dissect_tk_abstract_interface_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
394 gboolean stream_is_big_endian, guint32 boundary,
395 MessageHeader * header);
398 static void dissect_typecode_string_param(tvbuff_t *tvb, proto_tree *tree, gint *offset,
399 gboolean new_stream_is_big_endian, guint32 new_boundary, int hf_id );
401 static void dissect_data_for_typecode(tvbuff_t *tvb, proto_tree *tree, gint *offset,
402 gboolean stream_is_big_endian, guint32 boundary,
403 MessageHeader * header, guint32 data_type );
409 * ------------------------------------------------------------------------------------------+
410 * Data/Variables/Structs
411 * ------------------------------------------------------------------------------------------+
415 static int proto_giop = -1;
416 static int hf_giop_message_type = -1;
417 static int hf_giop_message_size = -1;
418 static int hf_giop_repoid = -1;
419 static int hf_giop_string_length = -1;
420 static int hf_giop_sequence_length = -1;
421 static int hf_giop_profile_id = -1;
422 static int hf_giop_type_id = -1;
423 static int hf_giop_iiop_v_maj = -1;
424 static int hf_giop_iiop_v_min = -1;
425 static int hf_giop_endianess = -1; /* esp encapsulations */
426 static int hf_giop_IOR_tag = -1;
427 static int hf_giop_IIOP_tag = -1;
429 static int hf_giop_TCKind = -1;
430 static int hf_giop_typecode_count = -1;
431 static int hf_giop_typecode_default_used = -1;
432 static int hf_giop_typecode_digits = -1;
433 static int hf_giop_typecode_length = -1;
434 static int hf_giop_typecode_max_length = -1;
435 static int hf_giop_typecode_member_name = -1;
436 static int hf_giop_typecode_name = -1;
437 static int hf_giop_typecode_scale = -1;
438 static int hf_giop_typecode_ValueModifier = -1;
439 static int hf_giop_typecode_Visibility = -1;
441 static int hf_giop_type_boolean = -1;
442 static int hf_giop_type_char = -1;
443 static int hf_giop_type_double = -1;
444 static int hf_giop_type_enum = -1;
445 static int hf_giop_type_float = -1;
446 static int hf_giop_type_long = -1;
447 static int hf_giop_type_octet = -1;
448 static int hf_giop_type_short = -1;
449 static int hf_giop_type_string = -1;
450 static int hf_giop_type_ulong = -1;
451 static int hf_giop_type_ushort = -1;
453 static int hf_giop_iiop_host = -1;
454 static int hf_giop_iiop_port = -1;
455 static int hf_giop_iop_vscid = -1;
456 static int hf_giop_iop_scid = -1;
462 static gint ett_giop = -1;
463 static gint ett_giop_reply = -1;
464 static gint ett_giop_request = -1;
465 static gint ett_giop_cancel_request = -1;
466 static gint ett_giop_locate_request = -1;
467 static gint ett_giop_locate_reply = -1;
468 static gint ett_giop_fragment = -1;
473 static const value_string giop_endianess_vals[] = {
474 { 0x0, "Big Endian" },
475 { 0x1, "Little Endian" },
479 static const value_string sync_scope[] = {
480 { 0x0, "SYNC_NONE" },
481 { 0x1, "SYNC_WITH_TRANSPORT"},
482 { 0x2, "SYNC_WITH_SERVER"},
483 { 0x3, "SYNC_WITH_TARGET"},
489 static const value_string profile_id_vals[] = {
490 { 0x0, "TAG_INTERNET_IOP" },
491 { 0x1, "TAG_MULTIPLE_COMPONENTS"},
492 { 0x2, "TAG_SCCP_IOP"},
496 static const value_string giop_message_types[] = {
499 { 0x2, "CancelRequest"},
500 { 0x3, "LocateRequest"},
501 { 0x4, "LocateReply"},
502 { 0x5, "CloseConnection"},
503 { 0x6, "MessageError"},
508 static const value_string giop_locate_status_types[] = {
509 { 0x0, "Unknown Object" },
510 { 0x1, "Object Here"},
511 { 0x2, "Object Forward"},
512 { 0x3, "Object Forward Perm"},
513 { 0x4, "Loc System Exception"},
514 { 0x5, "Loc Needs Addressing Mode"},
518 static const value_string tckind_vals[] = {
531 { 12, "tk_TypeCode"},
532 { 13, "tk_Principal"},
538 { 19, "tk_sequence"},
542 { 23, "tk_longlong"},
543 { 24, "tk_ulonglong"},
544 { 25, "tk_longdouble"},
549 { 30, "tk_value_box"},
551 { 32, "tk_abstract_interface"},
557 #define GIOP_MAGIC "GIOP"
560 * TAGS for IOR Profiles
562 * Chapter 13 Corba 2.4.2
566 #define IOP_TAG_INTERNET_IOP 0
567 #define IOP_TAG_MULTIPLE_COMPONENTS 1
570 /* Max Supported versions */
572 static const guint GIOP_MAJOR = 1;
573 static const guint GIOP_MINOR = 2;
576 static const int KeyAddr = 0;
577 static const int ProfileAddr = 1;
578 static const int ReferenceAddr = 2;
582 static const value_string reply_status_types[] = {
583 { NO_EXCEPTION, "No Exception" } ,
584 { USER_EXCEPTION, "User Exception" } ,
585 { SYSTEM_EXCEPTION, "System Exception" } ,
586 { LOCATION_FORWARD, "Location Forward" } ,
587 { LOCATION_FORWARD_PERM, "Location Forward Perm" } ,
588 { NEEDS_ADDRESSING_MODE, "Needs Addressing Mode" } ,
594 typedef enum LocateStatusType
599 OBJECT_FORWARD_PERM, /* new value for GIOP 1.2 */
600 LOC_SYSTEM_EXCEPTION, /* new value for GIOP 1.2 */
601 LOC_NEEDS_ADDRESSING_MODE /* new value for GIOP 1.2 */
605 typedef struct LocateReplyHeader
608 guint32 locate_status;
614 * DATA - complete_request_list
617 static GList *giop_complete_request_list;
619 struct comp_req_list_entry {
620 guint32 fn; /* frame number */
621 gchar * operation; /* echo echoString */
622 giop_sub_handle_t *subh; /* handle to sub dissector */
623 guint32 reqid; /* request id */
624 gchar * repoid; /* repository ID */
627 typedef struct comp_req_list_entry comp_req_list_entry_t;
631 * DATA - complete_reply_hash
633 * Maps reply FN to request MFN
636 static int complete_reply_hash_count = 1000; /* storage size for our permanent data */
637 /* ie: 1000 entries -- needs tweaking -- FS */
639 struct complete_reply_hash_key {
640 guint32 fn; /* reply frame number */
643 struct complete_reply_hash_val {
644 guint32 mfn; /* matching frame number (request) */
647 GHashTable *giop_complete_reply_hash = NULL; /* hash */
648 GMemChunk *giop_complete_reply_keys = NULL; /* key storage */
649 GMemChunk *giop_complete_reply_vals = NULL; /* val storage */
653 * DATA - Module Hash stuff to store data from register_giop_user_module
655 * ie: module (or interface ?) name, and ptr to sub_dissector handle
657 * With this knowledge, we can call a sub dissector directly,
660 * objkey -> repoid -> sub_dissector via registered module/interface
665 static int giop_module_init_count = 100; /* storage size for our permanent data */
666 /* ie: 100 entries -- needs tweaking -- FS */
668 struct giop_module_key {
669 gchar *module; /* module (interface?) name */
672 struct giop_module_val {
673 giop_sub_handle_t *subh; /* handle to sub dissector */
674 /* gchar *idlname; */ /* idl dissector name */
677 GHashTable *giop_module_hash = NULL; /* hash */
678 GMemChunk *giop_module_keys = NULL; /* key storage */
679 GMemChunk *giop_module_vals = NULL; /* val storage */
683 * DATA - GSList to store list of function (dissector) pointers.
684 * for heuristic dissection.
688 static GSList *giop_sub_list = NULL;
691 * DATA - Hash stuff to follow request/reply. This is so if we get a REPLY
692 * to a REQUEST (resolve), we can dump/store the RepoId and Object Key.
694 * With this knowledge, we can call a sub dissector directly later
697 * objkey -> repoid -> sub_dissector via registered module/interface
699 * rather than heuristic calls that do not provide operation context.
700 * (unless we pass the RepoID for a given objkey -- hmmm)
705 * Interesting operation list, add more if you want to save
709 static const char giop_op_resolve[] = "resolve";
710 static const char giop_op_bind_new_context[] = "bind_new_context";
711 static const char giop_op_bind[] = "bind";
714 * Enums for interesting local operations, that we may need to monitor
715 * with their subsequent replies
720 request_resolve_op_val, /* REQUEST (resolve) to get RepoID etc*/
721 request_bind_new_context_op_val, /* bind_new_context */
722 request_bind_op_val, /* bind */
723 request_get_INIT_op_val, /* finding Nameserver */
729 * hash for mapping object keys onto object namespaces, so
730 * I can call the correct dissector.
736 * Where did I get the IOR from.
740 req_res = 0, /* REQUEST (resolve) */
741 file, /* stringified IOR' in a file */
745 typedef enum ior_src ior_src_t;
750 * Enums for my lists and hash's
753 enum collection_data {
754 cd_heuristic_users = 0,
757 cd_complete_request_list,
758 cd_complete_reply_hash
761 typedef enum collection_data collection_data_t;
766 static int giop_objkey_init_count = 100; /* storage size for our permanent data */
767 /* ie: 100 entries -- needs tweaking -- FS */
769 struct giop_object_key {
770 guint8 *objkey; /* ptr to object key */
771 guint32 objkey_len; /* length */
774 struct giop_object_val {
775 guint8 *repo_id; /* ptr to Repository ID string */
776 ior_src_t src; /* where did Iget this IOR from */
779 GHashTable *giop_objkey_hash = NULL; /* hash */
780 GMemChunk *giop_objkey_keys = NULL; /* key storage */
781 GMemChunk *giop_objkey_vals = NULL; /* val storage */
786 * ------------------------------------------------------------------------------------------+
787 * Private helper functions
788 * ------------------------------------------------------------------------------------------+
794 * Insert FN,reqid,operation and sub handle in list. DOES not check for duplicates yet.
797 static GList *insert_in_comp_req_list(GList *list, guint32 fn, guint32 reqid, gchar * op, giop_sub_handle_t *sh ) {
798 GList * newlist_start;
799 comp_req_list_entry_t * entry = NULL;
802 entry = g_malloc(sizeof(comp_req_list_entry_t));
803 opn = g_strdup(op); /* duplicate operation for storage */
806 entry->reqid = reqid;
808 entry->operation = opn;
809 entry->repoid = NULL; /* dont have yet */
811 newlist_start = g_list_append (list, entry); /* append */
813 return newlist_start;
818 * Used to find an entry with matching Frame Number FN
819 * in the complete_request_list list.
822 static comp_req_list_entry_t * find_fn_in_list(guint32 fn) {
824 GList * element; /* entry in list */
825 comp_req_list_entry_t * entry_ptr = NULL;
827 element = g_list_last(giop_complete_request_list); /* start from last */
829 while(element) { /* valid list entry */
830 entry_ptr = element->data; /* grab data pointer */
831 if (entry_ptr->fn == fn) { /* similar FN */
834 element = g_list_previous(element); /* try next previous */
837 return NULL; /* no match so return NULL */
842 * Add/update a sub_dissector handle and repoid to a FN entry in the complete_request_list
844 * Call this when you know a FN and matching giop_sub_handle_t and repoid
846 * This is done in say, try_explicit_dissector for example.
850 static void add_sub_handle_repoid_to_comp_req_list(guint32 fn, giop_sub_handle_t *sh, gchar *repoid ) {
852 comp_req_list_entry_t * entry = NULL;
853 entry = find_fn_in_list(fn); /* grab FN data entry */
857 entry->repoid = g_strdup(repoid); /* copy and store */
865 /* giop_complete_reply_hash "EQUAL" Functions */
867 static gint complete_reply_equal_fn(gconstpointer v, gconstpointer w) {
868 struct complete_reply_hash_key *mk1 = (struct complete_reply_hash_key *)v;
869 struct complete_reply_hash_key *mk2 = (struct complete_reply_hash_key *)w;
871 if (mk1->fn == mk2->fn) {
875 return 0; /* found differences */
878 /* giop_complete_reply_hash "HASH" Functions */
880 static guint32 complete_reply_hash_fn(gconstpointer v) {
881 guint32 val; /* init hash value */
882 struct complete_reply_hash_key *key = (struct complete_reply_hash_key *)v;
884 val = key->fn; /* simple and unique */
891 * Insert the FN and MFN together in our complete_reply_hash.
894 static void insert_in_complete_reply_hash(guint32 fn, guint32 mfn) {
896 struct complete_reply_hash_key key, *new_key;
897 struct complete_reply_hash_val *val = NULL;
901 val = (struct complete_reply_hash_val *)g_hash_table_lookup(giop_complete_reply_hash, &key);
904 return; /* FN collision */
907 new_key = g_mem_chunk_alloc(giop_complete_reply_keys);
908 new_key->fn = fn; /* save FN */
910 val = g_mem_chunk_alloc(giop_complete_reply_vals);
911 val->mfn = mfn; /* and MFN */
913 g_hash_table_insert(giop_complete_reply_hash, new_key, val);
918 * Find the MFN values from a given FN key.
919 * Assumes the complete_reply_hash is already populated.
922 static guint32 get_mfn_from_fn(guint32 fn) {
924 struct complete_reply_hash_key key;
925 struct complete_reply_hash_val *val = NULL;
926 guint32 mfn = fn; /* save */
929 val = (struct complete_reply_hash_val *)g_hash_table_lookup(giop_complete_reply_hash, &key);
932 mfn = val->mfn; /* grab it */
935 return mfn; /* mfn or fn if not found */
940 * Attempt to find the MFN for this FN, and return it.
941 * Return MFN if found, or just FN if not. This is
942 * only used when we are building
945 static guint32 get_mfn_from_fn_and_reqid(guint32 fn, guint32 reqid) {
947 GList * element; /* last entry in list */
948 comp_req_list_entry_t * entry_ptr = NULL;
950 /* Need Some pretty snappy code */
952 /* Loop back from current end of complete_request_list looking for */
953 /* a FN with the same reqid -- TODO enhance with port/address checks -- FS */
956 * As this routine is only called during initial pass of data,
957 * and NOT when a user clicks, it is ok to start from Current
958 * end of complete_request_list when searching for a match.
959 * As that list is bing populated in the same order as FN's
962 * Also, can make check for same reqid more detailed, but I start
963 * with reqid. Could add say port or address checks etc later ??
967 element = g_list_last(giop_complete_request_list); /* get last */
969 while(element) { /* valid list entry */
970 entry_ptr = element->data; /* grab data pointer */
971 if (entry_ptr->reqid == reqid) { /* similar reqid */
972 return entry_ptr->fn; /* return MFN */
974 element = g_list_previous(element); /* try next previous */
977 return fn; /* no match so return FN */
981 /* Module Hash "EQUAL" Functions */
983 static gint giop_hash_module_equal(gconstpointer v, gconstpointer w) {
984 struct giop_module_key *mk1 = (struct giop_module_key *)v;
985 struct giop_module_key *mk2 = (struct giop_module_key *)w;
987 if (!strcmp(mk1->module, mk2->module)) {
991 return 0; /* found differences */
994 /* Module Hash "HASH" Functions */
996 static guint32 giop_hash_module_hash(gconstpointer v) {
999 guint32 val = 0; /* init hash value */
1001 struct giop_module_key *key = (struct giop_module_key *)v;
1004 * Hmm, try this simple hashing scheme for now.
1005 * ie: Simple summation, FIX later -- FS
1010 len = strlen(key->module);
1012 for (i=0; i<len; i++) {
1013 val += (guint8) key->module[i];
1022 * ------------------------------------------------------------------------------------------+
1023 * Public Utility functions
1024 * ------------------------------------------------------------------------------------------+
1031 * Routine to allow giop users to register their sub dissector function, name, and
1032 * IDL module/interface name. Store in giop_module_hash.
1034 * This is used by try_explicit_giop_dissector() to find the
1035 * correct sub-dissector.
1039 void register_giop_user_module(giop_sub_dissector_t *sub, gchar *name, gchar *module) {
1041 struct giop_module_key module_key, *new_module_key;
1042 struct giop_module_val *module_val = NULL;
1044 module_key.module = module; /* module name */
1046 module_val = (struct giop_module_val *)g_hash_table_lookup(giop_module_hash, &module_key);
1049 return; /* module name collision */
1052 /* So, passed module name should NOT exist in hash at this point.*/
1055 printf("giop:register_module: Adding Module %s to module hash \n", module);
1056 printf("giop:register_module: Module sub dissector name is %s \n", name);
1059 new_module_key = g_mem_chunk_alloc(giop_module_keys);
1060 new_module_key->module = module; /* save Module or interface name from IDL */
1062 module_val = g_mem_chunk_alloc(giop_module_vals);
1064 module_val->subh = g_malloc(sizeof (giop_sub_handle_t)); /* init subh */
1066 module_val->subh->sub_name = name; /* save dissector name */
1067 module_val->subh->sub_fn = sub; /* save subdissector*/
1069 g_hash_table_insert(giop_module_hash, new_module_key, module_val);
1076 /* Object Key Hash "EQUAL" Functions */
1078 static gint giop_hash_objkey_equal(gconstpointer v, gconstpointer w) {
1079 struct giop_object_key *v1 = (struct giop_object_key *)v;
1080 struct giop_object_key *v2 = (struct giop_object_key *)w;
1082 if (v1->objkey_len != v2->objkey_len)
1083 return 0; /* no match because different length */
1085 /* Now do a byte comaprison */
1087 if (!memcmp(v1->objkey,v2->objkey, v1->objkey_len)) {
1088 return 1; /* compares ok */
1092 printf("giop:giop_hash_objkey_equal: Objkey's DO NOT match");
1095 return 0; /* found differences */
1098 /* Object Key Hash "HASH" Functions */
1100 static guint32 giop_hash_objkey_hash(gconstpointer v) {
1101 struct giop_object_key *key = (struct giop_object_key *)v;
1104 guint32 val = 0; /* init hash value */
1108 * Hmm, try this simple hashing scheme for now.
1109 * ie: Simple summation
1115 printf("giop:hash_objkey: Key length = %u \n", key->objkey_len );
1118 for (i=0; i< key->objkey_len; i++) {
1119 val += (guint8) key->objkey[i];
1127 * Routine to take an object key octet sequence, and length, and ptr to
1128 * a (null terminated )repository ID string, and store them in the obect key hash.
1130 * Blindly Inserts even if it does exist, See TODO at top for reason.
1133 static void insert_in_objkey_hash(GHashTable *hash, gchar *obj, guint32 len, gchar *repoid, ior_src_t src) {
1135 struct giop_object_key objkey_key, *new_objkey_key;
1136 struct giop_object_val *objkey_val = NULL;
1138 objkey_key.objkey_len = len; /* length */
1139 objkey_key.objkey = obj; /* object key octet sequence */
1141 /* Look it up to see if it exists */
1143 objkey_val = (struct giop_object_val *)g_hash_table_lookup(hash, &objkey_key);
1145 /* CHANGED -- Same reqid, so abandon old entry */
1148 g_hash_table_remove(hash, &objkey_key);
1151 /* So, passed key should NOT exist in hash at this point.*/
1153 new_objkey_key = g_mem_chunk_alloc(giop_objkey_keys);
1154 new_objkey_key->objkey_len = len; /* save it */
1155 new_objkey_key->objkey = (guint8 *) g_memdup(obj,len); /* copy from object and allocate ptr */
1157 objkey_val = g_mem_chunk_alloc(giop_objkey_vals);
1158 objkey_val->repo_id = g_strdup(repoid); /* duplicate and store Respository ID string */
1159 objkey_val->src = src; /* where IOR came from */
1163 printf("giop: ******* Inserting Objkey with RepoID = %s and key length = %u into hash \n",
1164 objkey_val->repo_id, new_objkey_key->objkey_len);
1167 g_hash_table_insert(hash, new_objkey_key, objkey_val);
1174 * convert an ascii char representing a hex value,
1175 * to a numeric value.
1177 * returns value, or -1 if problem.
1181 static gint8 hex_char_to_val(guchar c){
1188 retval = c - 48; /* convert digit */
1192 c = toupper(c); /* convert to uppercase */
1193 if (c >= 'A' && c <= 'F') {
1204 * Convert from stringified IOR of the kind IOR:af4f7e459f....
1205 * to an IOR octet sequence.
1207 * User must free buffer.
1209 * Creates a new tvbuff and call decode_IOR with a NULL tree, just to
1210 * grab repoid etc for our objkey hash.
1214 static guint32 string_to_IOR(guchar *in, guint32 in_len, guint8 **out){
1217 gint8 tmpval; /* complete value */
1220 *out = g_new0(guint8, in_len); /* allocate buffer */
1226 /* skip past IOR: and convert character pairs to guint8 */
1228 for (i=4; i<in_len-1; i+=2) {
1229 if ( isxdigit(in[i]) && isxdigit(in[i+1]) ) { /* hex ? */
1231 if ( (tmpval_msb = hex_char_to_val(in[i])) < 0 ) {
1234 if ( (tmpval_lsb = hex_char_to_val(in[i+1])) < 0 ) {
1237 tmpval = tmpval_msb << 4;
1238 tmpval += tmpval_lsb;
1239 (*out)[(i-4)/2] = (guint8) tmpval;
1249 return (i-4)/2; /* length */
1256 * Simple getline, copied from somewhere :)
1260 static int getline(FILE *fp, gchar *line, int maxlen) {
1262 if (fgets(line,maxlen,fp) == NULL)
1265 return strlen(line);
1271 * Read a list of stringified IOR's from a named file, convert to IOR's
1272 * and store in object key hash
1275 static void read_IOR_strings_from_file(gchar *name, int max_iorlen) {
1276 guchar *buf = NULL; /* NOTE reused for every line */
1278 int ior_val_len; /* length after unstringifying. */
1280 guint8 *out = NULL; /* ptr to unstringified IOR */
1281 tvbuff_t *tvb = NULL; /* temp tvbuff for dissectin IORs */
1282 guint32 my_offset = 0;
1283 gboolean stream_is_big_endian;
1286 fp = fopen(name,"r"); /* open read only */
1289 if (errno == EACCES)
1290 fprintf(stderr, "Error opening file IOR.txt for reading: %s \n",strerror(errno));
1294 buf = g_malloc0(max_iorlen+1); /* input buf */
1296 while ((len = getline(fp,buf,max_iorlen+1)) > 0) {
1297 my_offset = 0; /* reset for every IOR read */
1299 ior_val_len = string_to_IOR(buf,len,&out); /* convert */
1303 /* Combination of tvb_new() and tvb_set_real_data(). Can throw ReportedBoundsError. */
1305 tvb = tvb_new_real_data(out,ior_val_len,ior_val_len, "GIOP FILE IOR");
1307 stream_is_big_endian = !get_CDR_octet(tvb,&my_offset);
1308 decode_IOR(tvb, NULL, NULL, &my_offset, 0, stream_is_big_endian);
1315 fclose(fp); /* be nice */
1324 * Init routine, setup our request hash stuff, or delete old ref's
1326 * Cannot setup the module hash here as my init() may not be called before
1327 * users start registering. So I will move the module_hash stuff to
1328 * proto_register_giop, as is done with packet-rpc
1332 * Also, setup our objectkey/repoid hash here.
1336 static void giop_init(void) {
1340 * Create objkey/repoid hash, use my "equal" and "hash" functions.
1344 if (giop_objkey_hash)
1345 g_hash_table_destroy(giop_objkey_hash);
1346 if (giop_objkey_keys)
1347 g_mem_chunk_destroy(giop_objkey_keys);
1348 if (giop_objkey_vals)
1349 g_mem_chunk_destroy(giop_objkey_vals);
1353 * Create hash, use my "equal" and "hash" functions.
1357 giop_objkey_hash = g_hash_table_new(giop_hash_objkey_hash, giop_hash_objkey_equal);
1359 giop_objkey_keys = g_mem_chunk_new("giop_objkey_keys",
1360 sizeof(struct giop_object_key),
1361 giop_objkey_init_count * sizeof(struct giop_object_key),
1364 giop_objkey_vals = g_mem_chunk_new("giop_objkey_vals",
1365 sizeof(struct giop_object_val),
1366 giop_objkey_init_count * sizeof(struct giop_object_val),
1371 * Create complete_reply_hash, use my "equal" and "hash" functions.
1375 if (giop_complete_reply_hash)
1376 g_hash_table_destroy(giop_complete_reply_hash);
1377 if (giop_complete_reply_keys)
1378 g_mem_chunk_destroy(giop_complete_reply_keys);
1379 if (giop_complete_reply_vals)
1380 g_mem_chunk_destroy(giop_complete_reply_vals);
1384 * Create hash, use my "equal" and "hash" functions.
1388 giop_complete_reply_hash = g_hash_table_new(complete_reply_hash_fn, complete_reply_equal_fn);
1390 giop_complete_reply_keys = g_mem_chunk_new("giop_complete_reply_keys",
1391 sizeof(struct complete_reply_hash_key),
1392 complete_reply_hash_count * sizeof(struct complete_reply_hash_key),
1395 giop_complete_reply_vals = g_mem_chunk_new("giop_complete_reply_vals",
1396 sizeof(struct complete_reply_hash_val),
1397 complete_reply_hash_count * sizeof(struct complete_reply_hash_val),
1402 read_IOR_strings_from_file("IOR.txt", 600); /* testing */
1409 * Insert an entry in the GIOP User table.
1411 * Uses giop_sub_handle_t to wrap giop user info.
1415 void register_giop_user(giop_sub_dissector_t *sub, gchar *name) {
1417 giop_sub_handle_t *subh;
1419 subh = g_malloc(sizeof (giop_sub_handle_t));
1421 subh->sub_name = name;
1424 giop_sub_list = g_slist_append (giop_sub_list, subh);
1430 * Lookup an object key in our object key hash, and return the corresponding
1435 static gchar * get_repoid_from_objkey(GHashTable *hash, guint8 *obj, guint32 len) {
1437 struct giop_object_key objkey_key;
1438 struct giop_object_val *objkey_val = NULL;
1440 objkey_key.objkey_len = len; /* length */
1441 objkey_key.objkey = obj; /* object key octet sequence */
1443 /* Look it up to see if it exists */
1445 objkey_val = (struct giop_object_val *)g_hash_table_lookup(hash, &objkey_key);
1449 printf("Lookup of object key returns RepoId = %s \n",objkey_val->repo_id );
1451 return objkey_val->repo_id; /* found */
1455 printf("FAILED Lookup of object key \n" );
1458 return NULL; /* not found */
1464 * Extract top level module/interface from repoid
1466 * eg from - "IDL:Echo/interface1:1.0"
1469 * Or, from "IDL:linux.org/Penguin/Teeth:1.0" get
1470 * get linux.org/Penguin/Teeth
1473 * User must free returned ptr after use.
1475 * TODO -- generalize for other Repoid encodings
1478 static gchar * get_modname_from_repoid(gchar *repoid) {
1480 gchar *modname = NULL;
1481 gchar *saved_repoid = NULL;
1483 guint8 stop_mod; /* Index of last character of modname in Repoid */
1484 guint8 start_mod = 4; /* Index where Module name starts in repoid */
1487 saved_repoid = g_strdup(repoid); /* make a copy */
1489 /* Must start with IDL: , otherwise I get confused */
1491 if (g_strncasecmp("IDL:",repoid,4))
1494 /* Looks like a RepoID to me, so get Module or interface name */
1496 /* TODO -- put some code here to get Module name */
1498 for(i=4; c != '\0'; i++) {
1500 stop_mod = i; /* save */
1501 if (c == ':' ) /* delimiters */
1506 /* Now create a new string based on start and stop and \0 */
1508 modname = g_strndup(repoid+4, stop_mod - start_mod);
1523 * Display a "module" hash entry
1526 static void display_module_hash(gpointer key, gpointer val, gpointer user_data) {
1528 struct giop_module_val *mv = (struct giop_module_val *) val;
1529 struct giop_module_key *mk = (struct giop_module_key *) key;
1531 printf("giop:module: Key = (%s) , Val = (%s) \n", mk->module, mv->subh->sub_name);
1538 * Display a "complete_reply " hash entry
1541 static void display_complete_reply_hash(gpointer key, gpointer val, gpointer user_data) {
1543 struct complete_reply_hash_val *mv = (struct complete_reply_hash_val *) val;
1544 struct complete_reply_hash_key *mk = (struct complete_reply_hash_key *) key;
1546 printf("giop:complete_reply: FN (key) = %8u , MFN (val) = %8u \n", mk->fn, mv->mfn);
1554 * Display an "objkey" hash entry
1557 static void display_objkey_hash(gpointer key, gpointer val, gpointer user_data) {
1559 struct giop_object_val *mv = (struct giop_object_val *) val;
1560 struct giop_object_key *mk = (struct giop_object_key *) key;
1563 printf("giop:objkey: Key->objkey_len = %u, Key->objkey ", mk->objkey_len);
1565 for (i=0; i<mk->objkey_len; i++) {
1566 printf("%.2x ", mk->objkey[i]);
1570 * If read from file, mark it as such..
1574 printf(", Repo ID = %s \n", mv->repo_id);
1577 printf(", Repo ID = %s , (file) \n", mv->repo_id);
1585 * Display all giop_sub_list (GSList) entries
1588 static void display_heuristic_user_list() {
1591 giop_sub_handle_t *subh; /* handle */
1593 /* Get length of list */
1594 len = g_slist_length(giop_sub_list); /* find length */
1599 for (i=0; i<len; i++) {
1600 subh = ( giop_sub_handle_t *) g_slist_nth_data(giop_sub_list,i); /* grab entry */
1601 printf("giop:heuristic_user: Element = %i, Val (user) = %s \n", i, subh->sub_name);
1607 * Display all complete_request_list (GList) entries
1610 static void display_complete_request_list() {
1613 comp_req_list_entry_t *entry;
1615 /* Get length of list */
1616 len = g_list_length(giop_complete_request_list); /* find length */
1621 for (i=0; i<len; i++) {
1622 entry = (comp_req_list_entry_t *) g_list_nth_data(giop_complete_request_list,i); /* grab entry */
1623 printf("giop:Index = %8i , FN = %8i, reqid = %8u , operation = %20s , repoid = %30s \n", i, entry->fn,
1624 entry->reqid,entry->operation, entry->repoid);
1632 /* Dump Hash/List contents
1634 * collection_type specifies the list or hash to dump
1638 static void giop_dump_collection(collection_data_t collection_type) {
1640 switch(collection_type) {
1641 case cd_heuristic_users:
1642 printf("+----------------------------------------------+ \n");
1643 printf("+-------------- Heuristic User (Begin) --------+ \n");
1644 printf("+----------------------------------------------+ \n");
1646 display_heuristic_user_list();
1648 printf("+----------------------------------------------+ \n");
1649 printf("+-------------- Heuristic User (End) ----------+ \n");
1650 printf("+----------------------------------------------+ \n");
1654 case cd_complete_request_list:
1655 printf("+----------------------------------------------+ \n");
1656 printf("+------------- Complete Request List (Begin) --+ \n");
1657 printf("+----------------------------------------------+ \n");
1659 display_complete_request_list();
1661 printf("+----------------------------------------------+ \n");
1662 printf("+------------ Complete Request List (End) -----+ \n");
1663 printf("+----------------------------------------------+ \n");
1667 case cd_module_hash:
1668 printf("+----------------------------------------------+ \n");
1669 printf("+-------------- Module (Begin) ----------------+ \n");
1670 printf("+----------------------------------------------+ \n");
1672 g_hash_table_foreach(giop_module_hash, display_module_hash, NULL);
1674 printf("+----------------------------------------------+ \n");
1675 printf("+-------------- Module ( End) -----------------+ \n");
1676 printf("+----------------------------------------------+ \n\n");
1680 case cd_objkey_hash:
1681 printf("+----------------------------------------------+ \n");
1682 printf("+-------------- Objkey (Begin) ----------------+ \n");
1683 printf("+----------------------------------------------+ \n");
1685 g_hash_table_foreach(giop_objkey_hash, display_objkey_hash,NULL);
1687 printf("+----------------------------------------------+ \n");
1688 printf("+-------------- Objkey (End) ------------------+ \n");
1689 printf("+----------------------------------------------+ \n\n");
1693 case cd_complete_reply_hash:
1694 printf("+----------------------------------------------+ \n");
1695 printf("+-------------- Complete_Reply_Hash (Begin) ---+ \n");
1696 printf("+----------------------------------------------+ \n");
1698 g_hash_table_foreach(giop_complete_reply_hash, display_complete_reply_hash, NULL);
1700 printf("+----------------------------------------------+ \n");
1701 printf("+------------- Complete_Reply_Hash (End) ------+ \n");
1702 printf("+----------------------------------------------+ \n");
1708 printf("giop: giop_dump_collection: Unknown type \n");
1719 * Loop through all subdissectors, and call them until someone
1720 * answers (returns TRUE). This function then returns TRUE, otherwise
1724 gboolean try_heuristic_giop_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset,
1725 MessageHeader *header, gchar *operation ) {
1728 gboolean res = FALSE; /* result of calling a heuristic sub dissector */
1729 giop_sub_handle_t *subh = NULL;
1731 len = g_slist_length(giop_sub_list); /* find length */
1736 for (i=0; i<len; i++) {
1737 subh = (giop_sub_handle_t *) g_slist_nth_data(giop_sub_list,i); /* grab dissector handle */
1738 res = (subh->sub_fn)(tvb,pinfo,tree,offset,header,operation,NULL); /* callit TODO - replace NULL */
1740 return TRUE; /* found one, lets return */
1743 return res; /* result */
1749 * Find the matching repoid in the module hash and call
1750 * the dissector function if offset exists.
1753 * Repoid is eg IDL:tux.antarctic/Penguin/Teeth:1.0 but subdissectors
1754 * will register possibly "tux.antarctic/Penguin" and "tux.antarctic/Penguin/Teeth".
1760 static void try_explicit_giop_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset,
1761 MessageHeader *header, gchar *operation, gchar *repoid ) {
1763 giop_sub_handle_t *subdiss = NULL; /* handle */
1765 gchar *modname = NULL;
1766 struct giop_module_key module_key;
1767 struct giop_module_val *module_val = NULL;
1771 * Get top level module/interface from complete repoid
1774 modname = get_modname_from_repoid(repoid);
1777 /* Search for Module or interface name */
1779 module_key.module = modname; /* module name */
1780 module_val = (struct giop_module_val *)g_hash_table_lookup(giop_module_hash, &module_key);
1782 if (module_val == NULL) {
1783 return; /* module not registered */
1786 subdiss = (giop_sub_handle_t *) module_val->subh; /* grab dissector handle */
1789 /* Add giop_sub_handle_t and repoid into complete_request_list, so REPLY can */
1790 /* look it up directly, later ie: FN -> MFN -> giop_sub_handle_t and repoid */
1791 /* but only if user not clicking */
1793 if (!pinfo->fd->flags.visited)
1794 add_sub_handle_repoid_to_comp_req_list(pinfo->fd->num,subdiss,repoid);
1797 /* Call subdissector if current offset exists */
1799 if (tvb_offset_exists(tvb, *offset)) {
1801 printf("giop:try_explicit_dissector calling sub = %s with module = (%s) \n", subdiss->sub_name , modname);
1803 res = (subdiss->sub_fn)(tvb,pinfo,tree,offset,header,operation, modname); /* callit, TODO replace NULL with idlname */
1804 } /* offset exists */
1812 /* Take in an array of char and create a new string.
1813 * Replace non-printable characters with periods.
1815 * The array may contain \0's so dont use strdup
1816 * The string is \0 terminated, and thus longer than
1817 * the initial sequence.
1818 * Caller must free the new string.
1821 static gchar * make_printable_string (gchar *in, guint32 len) {
1823 gchar *print_string = NULL;
1825 print_string = (gchar * )g_malloc0(len + 1); /* make some space and zero it */
1826 memcpy(print_string, in, len); /* and make a copy of input data */
1828 for(i=0; i < len; i++) {
1829 if( !isprint( (unsigned char)print_string[i] ) )
1830 print_string[i] = '.';
1833 return print_string; /* return ptr */
1836 /* Determine the byte order from the GIOP MessageHeader */
1838 gboolean is_big_endian (MessageHeader * header) {
1839 gboolean big_endian = FALSE;
1841 switch (header->GIOP_version.minor) {
1844 if (header->flags & 0x01)
1864 * Calculate new offset, based on the current offset, and user supplied
1865 * "offset delta" value, and the alignment requirement.
1869 * eg: Used for GIOP 1.2 where Request and Reply bodies are
1870 * aligned on 8 byte boundaries.
1873 static void set_new_alignment(int *offset, int delta, int alignment) {
1875 while( ( (*offset + delta) % alignment) != 0)
1884 * ------------------------------------------------------------------------------------------+
1885 * Public get_CDR_xxx functions.
1886 * ------------------------------------------------------------------------------------------+
1892 * Gets data of type any. This is encoded as a TypeCode
1893 * followed by the encoded value.
1896 void get_CDR_any(tvbuff_t *tvb, proto_tree *tree, gint *offset,
1897 gboolean stream_is_big_endian, int boundary,
1898 MessageHeader * header ) {
1900 guint32 TCKind; /* TypeCode */
1902 /* get TypeCode of any */
1903 TCKind = get_CDR_typeCode(tvb, tree, offset, stream_is_big_endian, boundary, header );
1905 /* dissect data of type TCKind */
1906 dissect_data_for_typecode(tvb, tree, offset, stream_is_big_endian, boundary, header, TCKind );
1910 /* Copy a 1 octet sequence from the tvbuff
1911 * which represents a boolean value, and convert
1912 * it to a boolean value.
1913 * Offset is then incremented by 1, to indicate the 1 octet which
1914 * has been processed.
1917 gboolean get_CDR_boolean(tvbuff_t *tvb, int *offset) {
1920 val = tvb_get_guint8(tvb, *offset); /* easy */
1925 /* Copy a 1 octet sequence from the tvbuff
1926 * which represents a char, and convert
1927 * it to an char value.
1928 * offset is then incremented by 1, to indicate the 1 octet which
1929 * has been processed.
1932 guint8 get_CDR_char(tvbuff_t *tvb, int *offset) {
1935 val = tvb_get_guint8(tvb, *offset); /* easy */
1943 * Floating Point Data Type double IEEE 754-1985
1945 * Copy an 8 octet sequence from the tvbuff
1946 * which represents a double value, and convert
1947 * it to a double value, taking into account byte order.
1948 * offset is first incremented so that it falls on a proper alignment
1949 * boundary for double values.
1950 * offset is then incremented by 8, to indicate the 8 octets which
1951 * have been processed.
1954 gdouble get_CDR_double(tvbuff_t *tvb, int *offset, gboolean stream_is_big_endian, int boundary) {
1957 guint8 e1,e2,f1,f2,f3,f4,f5,f6,f7;
1960 guint32 fract0, fract1;
1964 /* double values must be aligned on a 8 byte boundary */
1966 while( ( (*offset + boundary) % 8) != 0)
1970 if(stream_is_big_endian) {
1971 e1 = get_CDR_octet(tvb,offset);
1972 sign = e1 >> 7; /* sign value */
1973 e1 &= 0x7f; /* bottom 7 bits */
1974 f1 = get_CDR_octet(tvb,offset);
1976 f1 &= 0x0f; /* bottom 4 bits */
1977 f2 = get_CDR_octet(tvb,offset);
1978 f3 = get_CDR_octet(tvb,offset);
1979 f4 = get_CDR_octet(tvb,offset);
1980 f5 = get_CDR_octet(tvb,offset);
1981 f6 = get_CDR_octet(tvb,offset);
1982 f7 = get_CDR_octet(tvb,offset);
1986 f7 = get_CDR_octet(tvb,offset);
1987 f6 = get_CDR_octet(tvb,offset);
1988 f5 = get_CDR_octet(tvb,offset);
1989 f4 = get_CDR_octet(tvb,offset);
1990 f3 = get_CDR_octet(tvb,offset);
1991 f2 = get_CDR_octet(tvb,offset);
1992 f1 = get_CDR_octet(tvb,offset);
1994 f1 &= 0x0f; /* bottom 4 bits */
1995 e1 = get_CDR_octet(tvb,offset);
1996 sign = e1 >> 7; /* sign value */
1997 e1 &= 0x7f; /* bottom 7 bits */
2001 exp = (e1 << 4) + e2;
2003 /* Now lets do some 52 bit math with 32 bit constraint */
2005 fract0 = f7 + (f6 << 8) + (f5 << 16) + (f4 << 24); /* lower 32 bits of fractional part */
2006 fract1 = f3 + (f2 << 8) + (f1 << 16); /* top 20 bits of fractional part */
2008 d_fract = (fract1 / (pow(2,20))) + (fract0 / (pow(2,52))); /* 52 bits represent a fraction */
2010 val = pow(-1,sign) * pow(2,(exp - 1023)) * (1 + d_fract);
2012 return val; /* FIX rounding ?? */
2017 /* Copy a 4 octet sequence from the tvbuff
2018 * which represents an enum value, and convert
2019 * it to an enum value, taking into account byte order.
2020 * offset is first incremented so that it falls on a proper alignment
2021 * boundary for an enum (4)
2022 * offset is then incremented by 4, to indicate the 4 octets which
2023 * have been processed.
2025 * Enum values are encoded as unsigned long.
2029 guint32 get_CDR_enum(tvbuff_t *tvb, int *offset, gboolean stream_is_big_endian, int boundary) {
2031 return get_CDR_ulong(tvb, offset, stream_is_big_endian, boundary );
2037 * Copy an "n" octet sequence from the tvbuff
2038 * which represents a Fixed point decimal type, and convert
2039 * it to a Fixed point decimal type. There are no alignment restrictions.
2040 * Size of fixed decimal type is determined by IDL, but this routine
2041 * will just process octets until it hits the "sign configuration" as
2044 * This value is either
2045 * 0xd - positive value
2046 * 0xc - negative value
2048 * offset is then incremented past the sign octet.
2050 * TODO - pass in parameters from IDL, eg: scale etc..
2054 void get_CDR_fixed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint *offset, guint32 n) {
2061 * Floating Point Data Type float IEEE 754-1985
2063 * Copy an 4 octet sequence from the tvbuff
2064 * which represents a float value, and convert
2065 * it to a float value, taking into account byte order.
2066 * offset is first incremented so that it falls on a proper alignment
2067 * boundary for float values.
2068 * offset is then incremented by 4, to indicate the 4 octets which
2069 * have been processed.
2072 gfloat get_CDR_float(tvbuff_t *tvb, int *offset, gboolean stream_is_big_endian, int boundary) {
2075 guint8 e1,e2,f1,f2,f3;
2081 /* float values must be aligned on a 4 byte boundary */
2083 while( ( (*offset + boundary) % 4) != 0)
2086 if(stream_is_big_endian) {
2087 e1 = get_CDR_octet(tvb,offset);
2088 sign = e1 >> 7; /* sign value */
2089 e1 &= 0x7f; /* bottom 7 bits */
2090 f1 = get_CDR_octet(tvb,offset);
2092 f1 &= 0x7f; /* bottom 7 bits */
2093 f2 = get_CDR_octet(tvb,offset);
2094 f3 = get_CDR_octet(tvb,offset);
2098 f3 = get_CDR_octet(tvb,offset);
2099 f2 = get_CDR_octet(tvb,offset);
2100 f1 = get_CDR_octet(tvb,offset);
2102 f1 &= 0x7f; /* bottom 7 bits */
2103 e1 = get_CDR_octet(tvb,offset);
2104 sign = e1 >> 7; /* sign value */
2105 e1 &= 0x7f; /* bottom 7 bits */
2110 exp = (e1 << 1) + e2;
2111 fract = f3 + (f2 << 8) + (f1 << 16);
2113 d_fract = fract / (pow(2,23)); /* 23 bits represent a fraction */
2115 val = pow(-1,sign) * pow(2,(exp - 127)) * (1 + d_fract);
2117 return val; /* FIX rounding ?? */
2123 * Decode an Interface type, and display it on the tree.
2126 void get_CDR_interface(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset,
2127 gboolean stream_is_big_endian, int boundary) {
2130 decode_IOR(tvb, pinfo, tree, offset, boundary, stream_is_big_endian);
2136 /* Copy a 4 octet sequence from the tvbuff
2137 * which represents a signed long value, and convert
2138 * it to an signed long vaule, taking into account byte order.
2139 * offset is first incremented so that it falls on a proper alignment
2140 * boundary for long values.
2141 * offset is then incremented by 4, to indicate the 4 octets which
2142 * have been processed.
2145 gint32 get_CDR_long(tvbuff_t *tvb, int *offset, gboolean stream_is_big_endian, int boundary) {
2149 /* unsigned long values must be aligned on a 4 byte boundary */
2150 while( ( (*offset + boundary) % 4) != 0)
2153 val = (stream_is_big_endian) ? tvb_get_ntohl (tvb, *offset) :
2154 tvb_get_letohl (tvb, *offset);
2161 * Decode an Object type, and display it on the tree.
2164 void get_CDR_object(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset,
2165 gboolean stream_is_big_endian, int boundary) {
2167 decode_IOR(tvb, pinfo, tree, offset, boundary, stream_is_big_endian);
2173 /* Copy a 1 octet sequence from the tvbuff
2174 * which represents a octet, and convert
2175 * it to an octet value.
2176 * offset is then incremented by 1, to indicate the 1 octet which
2177 * has been processed.
2180 guint8 get_CDR_octet(tvbuff_t *tvb, int *offset) {
2183 val = tvb_get_guint8(tvb, *offset); /* easy */
2189 /* Copy a sequence of octets from the tvbuff.
2190 * Caller of this function must remember to free the
2191 * array pointed to by seq.
2192 * This function also increments offset by len.
2195 void get_CDR_octet_seq(tvbuff_t *tvb, gchar **seq, int *offset, int len) {
2197 if (! tvb_bytes_exist(tvb, *offset,len)) {
2198 tvb_get_guint8(tvb,100000); /* generate an exception, and stop processing */
2199 /* better than a core dump later */
2202 *seq = g_new0(gchar, len + 1);
2203 tvb_memcpy( tvb, *seq, *offset, len);
2208 /* Copy a 2 octet sequence from the tvbuff
2209 * which represents a signed short value, and convert
2210 * it to a signed short value, taking into account byte order.
2211 * offset is first incremented so that it falls on a proper alignment
2212 * boundary for short values.
2213 * offset is then incremented by 2, to indicate the 2 octets which
2214 * have been processed.
2217 gint16 get_CDR_short(tvbuff_t *tvb, int *offset, gboolean stream_is_big_endian, int boundary) {
2221 /* short values must be aligned on a 2 byte boundary */
2222 while( ( (*offset + boundary) % 2) != 0)
2225 val = (stream_is_big_endian) ? tvb_get_ntohs (tvb, *offset) :
2226 tvb_get_letohs (tvb, *offset);
2234 /* Copy an octet sequence from the tvbuff
2235 * which represents a string, and convert
2236 * it to an string value, taking into account byte order.
2237 * offset is first incremented so that it falls on a proper alignment
2238 * boundary for string values. (begins with an unsigned long LI)
2240 * String sequence is copied to a buffer "seq". This must
2241 * be freed by the calling program.
2242 * offset is then incremented, to indicate the octets which
2243 * have been processed.
2245 * returns number of octets in the sequence
2247 * Note: This function only supports single byte encoding at the
2248 * moment until I get a handle on multibyte encoding etc.
2253 guint32 get_CDR_string(tvbuff_t *tvb, gchar **seq, int *offset, gboolean stream_is_big_endian,
2258 slength = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary); /* get length first */
2260 /* Avoid crashing */
2262 if (! tvb_bytes_exist(tvb, *offset, slength)) {
2263 tvb_get_guint8(tvb,100000); /* generate an exception, and stop processing */
2264 /* better than a core dump later */
2268 (*offset)++; /* must step past \0 delimiter */
2272 get_CDR_octet_seq(tvb, seq, offset, slength);
2275 return slength; /* return length */
2279 /* Process a sequence of octets that represent the
2280 * Pseudo Object Type "TypeCode". Typecodes are used for example,
2282 * This function also increments offset to the correct position.
2284 * It will parse the TypeCode and output data to the "tree" provided
2287 * It returns a guint32 representing a TCKind value.
2290 guint32 get_CDR_typeCode(tvbuff_t *tvb, proto_tree *tree, gint *offset,
2291 gboolean stream_is_big_endian, int boundary,
2292 MessageHeader * header ) {
2295 gint16 s_octet2; /* signed int16 */
2296 guint16 u_octet2; /* unsigned int16 */
2297 guint32 u_octet4; /* unsigned int32 */
2299 val = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary); /* get TCKind enum */
2301 proto_tree_add_uint(tree,hf_giop_TCKind,tvb,
2302 *offset-sizeof(val),4,val);
2305 /* Grab the data according to Typecode Table - Corba Chapter 15 */
2308 case tk_null: /* empty parameter list */
2310 case tk_void: /* empty parameter list */
2312 case tk_short: /* empty parameter list */
2314 case tk_long: /* empty parameter list */
2316 case tk_ushort: /* empty parameter list */
2318 case tk_ulong: /* empty parameter list */
2320 case tk_float: /* empty parameter list */
2322 case tk_double: /* empty parameter list */
2324 case tk_boolean: /* empty parameter list */
2326 case tk_char: /* empty parameter list */
2328 case tk_octet: /* empty parameter list */
2330 case tk_any: /* empty parameter list */
2332 case tk_TypeCode: /* empty parameter list */
2334 case tk_Principal: /* empty parameter list */
2336 case tk_objref: /* complex parameter list */
2337 dissect_tk_objref_params(tvb, tree, offset, stream_is_big_endian, boundary, header );
2339 case tk_struct: /* complex parameter list */
2340 dissect_tk_struct_params(tvb, tree, offset, stream_is_big_endian, boundary, header );
2342 case tk_union: /* complex parameter list */
2343 dissect_tk_union_params(tvb, tree, offset, stream_is_big_endian, boundary, header );
2345 case tk_enum: /* complex parameter list */
2346 dissect_tk_enum_params(tvb, tree, offset, stream_is_big_endian, boundary, header );
2349 case tk_string: /* simple parameter list */
2350 u_octet4 = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary); /* get maximum length */
2352 proto_tree_add_uint(tree,hf_giop_typecode_max_length,tvb,
2353 *offset-sizeof(u_octet4),4,u_octet4);
2357 case tk_sequence: /* complex parameter list */
2358 dissect_tk_sequence_params(tvb, tree, offset, stream_is_big_endian, boundary, header );
2360 case tk_array: /* complex parameter list */
2361 dissect_tk_array_params(tvb, tree, offset, stream_is_big_endian, boundary, header );
2363 case tk_alias: /* complex parameter list */
2364 dissect_tk_alias_params(tvb, tree, offset, stream_is_big_endian, boundary, header );
2366 case tk_except: /* complex parameter list */
2367 dissect_tk_except_params(tvb, tree, offset, stream_is_big_endian, boundary, header );
2369 case tk_longlong: /* empty parameter list */
2371 case tk_ulonglong: /* empty parameter list */
2373 case tk_longdouble: /* empty parameter list */
2375 case tk_wchar: /* empty parameter list */
2377 case tk_wstring: /* simple parameter list */
2378 u_octet4 = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary); /* get maximum length */
2380 proto_tree_add_uint(tree,hf_giop_typecode_max_length,tvb,
2381 *offset-sizeof(u_octet4),4,u_octet4);
2385 case tk_fixed: /* simple parameter list */
2386 u_octet2 = get_CDR_ushort(tvb,offset,stream_is_big_endian,boundary); /* get digits */
2388 proto_tree_add_uint(tree,hf_giop_typecode_digits,tvb,
2389 *offset-sizeof(u_octet2),2,u_octet2);
2392 s_octet2 = get_CDR_short(tvb,offset,stream_is_big_endian,boundary); /* get scale */
2394 proto_tree_add_int(tree,hf_giop_typecode_scale,tvb,
2395 *offset-sizeof(s_octet2),2,s_octet2);
2399 case tk_value: /* complex parameter list */
2400 dissect_tk_value_params(tvb, tree, offset, stream_is_big_endian, boundary, header );
2402 case tk_value_box: /* complex parameter list */
2403 dissect_tk_value_box_params(tvb, tree, offset, stream_is_big_endian, boundary, header );
2405 case tk_native: /* complex parameter list */
2406 dissect_tk_native_params(tvb, tree, offset, stream_is_big_endian, boundary, header );
2408 case tk_abstract_interface: /* complex parameter list */
2409 dissect_tk_abstract_interface_params(tvb, tree, offset, stream_is_big_endian, boundary, header );
2412 g_warning("giop: Unknown TCKind %u \n", val);
2421 /* Copy a 4 octet sequence from the tvbuff
2422 * which represents an unsigned long value, and convert
2423 * it to an unsigned long vaule, taking into account byte order.
2424 * offset is first incremented so that it falls on a proper alignment
2425 * boundary for unsigned long values.
2426 * offset is then incremented by 4, to indicate the 4 octets which
2427 * have been processed.
2430 guint32 get_CDR_ulong(tvbuff_t *tvb, int *offset, gboolean stream_is_big_endian, int boundary) {
2434 /* unsigned long values must be aligned on a 4 byte boundary */
2435 while( ( (*offset + boundary) % 4) != 0)
2438 val = (stream_is_big_endian) ? tvb_get_ntohl (tvb, *offset) :
2439 tvb_get_letohl (tvb, *offset);
2446 /* Copy a 2 octet sequence from the tvbuff
2447 * which represents an unsigned short value, and convert
2448 * it to an unsigned short value, taking into account byte order.
2449 * offset is first incremented so that it falls on a proper alignment
2450 * boundary for unsigned short values.
2451 * offset is then incremented by 2, to indicate the 2 octets which
2452 * have been processed.
2455 guint16 get_CDR_ushort(tvbuff_t *tvb, int *offset, gboolean stream_is_big_endian, int boundary) {
2459 /* unsigned short values must be aligned on a 2 byte boundary */
2460 while( ( (*offset + boundary) % 2) != 0)
2463 val = (stream_is_big_endian) ? tvb_get_ntohs (tvb, *offset) :
2464 tvb_get_letohs (tvb, *offset);
2472 /* Copy a wchar from the tvbuff.
2473 * Caller of this function must remember to free the
2474 * array pointed to by seq.
2475 * This function also increments offset according to
2478 * For GIOP 1.1 read 2 octets and return size -2. The
2479 * negation means there is no size element in the packet
2480 * and therefore no size to add to the tree.
2482 * For GIOP 1.2 read size of wchar and the size
2483 * octets. size is returned as a gint8.
2485 * For both GIOP versions the wchar is returned
2486 * as a printable string.
2490 /* NOTE: This is very primitive in that it just reads
2491 * the wchar as a series of octets and returns them
2492 * to the user. No translation is attempted based on
2493 * byte orientation, nor on code set. I.e it only
2494 * really reads past the wchar and sets the offset
2498 /* The "decoding" is done according to CORBA chapter 15.
2499 * Wchar is not supported for GIOP 1.0.
2502 gint8 get_CDR_wchar(tvbuff_t *tvb, gchar **seq, int *offset, MessageHeader * header) {
2505 gchar *raw_wstring = NULL;
2507 /* CORBA chapter 15:
2508 * - prior to GIOP 1.2 wchar limited to two octet fixed length.
2509 * - GIOP 1.2 wchar is encoded as an unsigned binary octet
2510 * followed by the elements of the octet sequence representing
2511 * the encoded value of the wchar.
2514 *seq = NULL; /* set in case GIOP 1.2 length is 0 */
2515 slength = 2; /* set for GIOP 1.1 length in octets */
2517 if (header->GIOP_version.minor > 1) /* if GIOP 1.2 get length of wchar */
2518 slength = get_CDR_octet(tvb,offset);
2521 /* ??? assume alignment is ok for GIOP 1.1 ??? */
2522 get_CDR_octet_seq(tvb, &raw_wstring, offset, slength);
2524 /* now turn octets (wchar) into something that can be printed by the user */
2525 *seq = make_printable_string(raw_wstring, slength);
2528 /* if GIOP 1.1 negate length to indicate not an item to add to tree */
2529 if (header->GIOP_version.minor < 2)
2532 g_free(raw_wstring);
2534 return slength; /* return length */
2539 /* Copy a wstring from the tvbuff.
2540 * Caller of this function must remember to free the
2541 * array pointed to by seq.
2542 * This function also increments offset, according to
2543 * wstring length. length is returned as guint32
2546 /* NOTE: This is very primitive in that it just reads
2547 * the wstring as a series of octets and returns them
2548 * to the user. No translation is attempted based on
2549 * byte orientation, nor on code set. I.e it only
2550 * really reads past the wstring and sets the offset
2554 /* The "decoding" is done according to CORBA chapter 15.
2555 * Wstring is not supported for GIOP 1.0.
2559 guint32 get_CDR_wstring(tvbuff_t *tvb, gchar **seq, int *offset, gboolean stream_is_big_endian,
2560 int boundary, MessageHeader * header) {
2563 gchar *raw_wstring = NULL;
2565 /* CORBA chapter 15:
2566 * - prior to GIOP 1.2 wstring limited to two octet fixed length.
2567 * length and string are NUL terminated (length???).
2568 * - GIOP 1.2 length is total number of octets. wstring is NOT NUL
2572 *seq = NULL; /* set in case GIOP 1.2 length is 0 */
2574 /* get length, same for all GIOP versions,
2575 * although for 1.2 CORBA doesnt say, so assume.
2577 slength = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary);
2581 fprintf(stderr, "giop:get_CDR_wstring, length %u > 200, truncating to 5 \n", slength);
2582 slength = 5; /* better than core dumping during debug */
2586 if (header->GIOP_version.minor < 2) {
2588 (*offset)++; /* must step past \0 delimiter */
2590 /* assume length is number of characters and not octets, spec not clear */
2591 slength = slength * 2; /* length in octets is 2 * wstring length */
2595 get_CDR_octet_seq(tvb, &raw_wstring, offset, slength);
2597 /* now turn octets (wstring) into something that can be printed by the user */
2598 *seq = make_printable_string(raw_wstring, slength);
2601 g_free(raw_wstring);
2603 return slength; /* return length */
2610 * Dissects a TargetAddress which is defined in (CORBA 2.4, section 15.4.2)
2612 * typedef short AddressingDisposition;
2613 * const short KeyAddr = 0;
2614 * const short ProfileAddr = 1;
2615 * const short ReferenceAddr = 2;
2616 * struct IORAddressingInfo {
2617 * unsigned long selected_profile_index;
2621 * union TargetAddress switch (AddressingDisposition) {
2622 * case KeyAddr: sequence <octet> object_key;
2623 * case ProfileAddr: IOP::TaggedProfile profile;
2624 * case ReferenceAddr: IORAddressingInfo ior;
2629 dissect_target_address(tvbuff_t * tvb, packet_info *pinfo, int *offset, proto_tree * tree,
2630 MessageHeader * header, gboolean stream_is_big_endian)
2632 guint16 discriminant;
2633 gchar *object_key = NULL;
2634 gchar *p_object_key = NULL;
2638 discriminant = get_CDR_ushort(tvb, offset, stream_is_big_endian,GIOP_HEADER_SIZE);
2641 proto_tree_add_text (tree, tvb, *offset -2, 2,
2642 "TargetAddress Discriminant: %u", discriminant);
2645 switch (discriminant)
2647 case 0: /* KeyAddr */
2648 len = get_CDR_ulong(tvb, offset, stream_is_big_endian,GIOP_HEADER_SIZE);
2651 proto_tree_add_text (tree, tvb, *offset -4, 4,
2652 "KeyAddr (object key length): %u", len);
2657 get_CDR_octet_seq(tvb, &object_key, offset, len);
2658 p_object_key = make_printable_string( object_key, len );
2662 proto_tree_add_text (tree, tvb, *offset -len, len,
2663 "KeyAddr (object key): %s", p_object_key);
2667 case 1: /* ProfileAddr */
2668 decode_TaggedProfile(tvb, pinfo, tree, offset, GIOP_HEADER_SIZE,
2669 stream_is_big_endian, NULL);
2671 case 2: /* ReferenceAddr */
2672 u_octet4 = get_CDR_ulong(tvb, offset, stream_is_big_endian,GIOP_HEADER_SIZE);
2676 proto_tree_add_text (tree, tvb, *offset -len -4, 4,
2677 "ReferenceAddr (selected_profile_index): %u", u_octet4);
2680 decode_IOR(tvb, pinfo, tree, offset, GIOP_HEADER_SIZE, stream_is_big_endian);
2685 g_free( object_key );
2686 g_free( p_object_key );
2690 dissect_reply_body (tvbuff_t *tvb, u_int offset, packet_info *pinfo,
2691 proto_tree *tree, gboolean stream_is_big_endian,
2692 guint32 reply_status, MessageHeader *header, proto_tree *clnp_tree) {
2694 u_int sequence_length;
2696 gchar * repoid = NULL; /* Repositor ID looked up from objkey */
2699 * comp_req_list stuff
2702 comp_req_list_entry_t * entry = NULL; /* data element in our list */
2706 switch (reply_status)
2708 case SYSTEM_EXCEPTION:
2710 decode_SystemExceptionReplyBody (tvb, tree, &offset, stream_is_big_endian, GIOP_HEADER_SIZE);
2713 case USER_EXCEPTION:
2717 sequence_length = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
2719 proto_tree_add_text(tree, tvb, offset-4, 4,
2720 "Exception length: %u", sequence_length);
2722 if (sequence_length != 0)
2724 proto_tree_add_text(tree, tvb, offset, sequence_length,
2726 tvb_format_text(tvb, offset, sequence_length));
2730 header->exception_id = g_new0(gchar,sequence_length ); /* allocate buffer */
2732 /* read exception id from buffer and store in*/
2734 tvb_get_nstringz0(tvb,offset,sequence_length, header->exception_id );
2740 offset += sequence_length;
2748 * Now just fall through to the NO_EXCEPTION part
2749 * as this is common .
2757 /* lookup MFN in hash directly */
2759 mfn = get_mfn_from_fn(pinfo->fd->num);
2761 if (mfn == pinfo->fd->num)
2762 return; /* no matching frame number, what am I */
2764 /* get entry for this MFN */
2765 entry = find_fn_in_list(mfn); /* get data entry in complete_request_list */
2768 return; /* no matching entry */
2772 * If this packet is a REPLY to a RESOLVE(request)
2774 * TODO - make this lookup faster -- FS
2777 if (!strcmp(giop_op_resolve,entry->operation)) {
2778 decode_IOR(tvb, pinfo, tree, &offset, GIOP_HEADER_SIZE,stream_is_big_endian);
2782 /* TODO -- Put stuff here for other "interesting operations" */
2786 * Call sub dissector.
2787 * First try an find a explicit sub_dissector, then if that
2788 * fails, try the heuristic method.
2791 #if DEBUG_CALL_SUB_DISSECTORS
2794 try_explicit_giop_dissector(tvb,pinfo,clnp_tree, &offset, header, entry->operation, entry->repoid );
2798 try_heuristic_giop_dissector(tvb,pinfo,clnp_tree,&offset,header,entry->operation);
2805 case LOCATION_FORWARD:
2806 g_warning("giop: We don't yet dissect LOCATION_FORWARD\n");
2810 case LOCATION_FORWARD_PERM:
2811 g_warning("giop: We don't yet dissect LOCATION_FORWARD_PERM\n");
2815 case NEEDS_ADDRESSING_MODE:
2816 g_warning("giop: We don't yet dissect NEEDS_ADDRESSING_MODE\n");
2822 g_warning("giop: UNKNOWN_EXCEPTION %i request_id = %u\n",reply_status, header->req_id);
2828 g_free(repoid); /* free resource */
2838 /* The format of the Reply Header for GIOP 1.0 and 1.1
2839 * is documented in Section 15.4.3.1 of the CORBA 2.4 standard.
2841 struct ReplyHeader_1_0 {
2842 IOP::ServiceContextList service_context;
2843 unsigned long request_id;
2844 ReplyStatusType_1_0 reply_status;
2848 static void dissect_giop_reply (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
2849 proto_tree * clnp_tree, MessageHeader * header,
2850 gboolean stream_is_big_endian) {
2854 guint32 reply_status;
2855 proto_tree *reply_tree = NULL;
2857 guint32 mfn; /* matching frame number */
2860 tf = proto_tree_add_text (tree, tvb, offset,
2862 "General Inter-ORB Protocol Reply");
2863 if (reply_tree == NULL)
2865 reply_tree = proto_item_add_subtree (tf, ett_giop_reply);
2871 * Decode IOP::ServiceContextList
2874 decode_ServiceContextList(tvb, pinfo, reply_tree, &offset,stream_is_big_endian, GIOP_HEADER_SIZE);
2876 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
2878 if (check_col(pinfo->fd, COL_INFO)) {
2879 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
2883 proto_tree_add_text (reply_tree, tvb, offset-4, 4,
2884 "Request id: %u", request_id);
2887 reply_status = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
2889 if (check_col(pinfo->fd, COL_INFO)) {
2890 col_append_fstr(pinfo->fd, COL_INFO, ": %s",
2891 val_to_str(reply_status, reply_status_types, "Unknown (%u)"));
2896 proto_tree_add_text (reply_tree, tvb, offset-4, 4,
2898 val_to_str(reply_status, reply_status_types, "Unknown (%u)"));
2903 * Save FN and MFN in complete_reply_hash, only if user is NOT clicking
2906 if (! pinfo->fd->flags.visited) {
2907 mfn = get_mfn_from_fn_and_reqid(pinfo->fd->num,request_id); /* find MFN for this FN */
2908 if (mfn != pinfo->fd->num) { /* if mfn is not fn, good */
2909 insert_in_complete_reply_hash(pinfo->fd->num, mfn);
2913 header->req_id = request_id; /* save for sub dissector */
2914 header->rep_status = reply_status; /* save for sub dissector */
2916 dissect_reply_body(tvb, offset, pinfo, reply_tree, stream_is_big_endian,
2917 reply_status, header,tree);
2922 /** The format of the GIOP 1.2 Reply header is very similar to the 1.0
2923 * and 1.1 header, only the fields have been rearranged. From Section
2924 * 15.4.3.1 of the CORBA 2.4 specification:
2926 * struct ReplyHeader_1_2 {
2927 * unsigned long request_id;
2928 * ReplyStatusType_1_2 reply_status;
2929 * IOP:ServiceContextList service_context;
2933 static void dissect_giop_reply_1_2 (tvbuff_t * tvb, packet_info * pinfo,
2934 proto_tree * tree, proto_tree * clnp_tree,
2935 MessageHeader * header,
2936 gboolean stream_is_big_endian) {
2940 guint32 reply_status;
2941 proto_tree *reply_tree = NULL;
2943 guint32 mfn; /* matching frame number */
2946 tf = proto_tree_add_text (tree, tvb, offset,
2948 "General Inter-ORB Protocol Reply");
2949 reply_tree = proto_item_add_subtree (tf, ett_giop_reply);
2952 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
2954 if (check_col(pinfo->fd, COL_INFO)) {
2955 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
2959 proto_tree_add_text (reply_tree, tvb, offset-4, 4,
2960 "Request id: %u", request_id);
2963 reply_status = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
2965 if (check_col(pinfo->fd, COL_INFO)) {
2966 col_append_fstr(pinfo->fd, COL_INFO, ": %s",
2967 val_to_str(reply_status, reply_status_types, "Unknown (%u)"));
2972 proto_tree_add_text (reply_tree, tvb, offset-4, 4,
2974 val_to_str(reply_status, reply_status_types, "Unknown (%u)"));
2979 * Decode IOP::ServiceContextList
2982 decode_ServiceContextList(tvb, pinfo, reply_tree, &offset,stream_is_big_endian, GIOP_HEADER_SIZE);
2985 * GIOP 1.2 Reply body must fall on an 8 octet alignment.
2988 set_new_alignment(&offset, GIOP_HEADER_SIZE, 8);
2991 * Save FN and MFN in complete_reply_hash, only if user is NOT clicking
2994 if (! pinfo->fd->flags.visited) {
2995 mfn = get_mfn_from_fn_and_reqid(pinfo->fd->num,request_id); /* find MFN for this FN */
2996 if (mfn != pinfo->fd->num) { /* if mfn is not fn, good */
2997 insert_in_complete_reply_hash(pinfo->fd->num, mfn);
3002 * Add header to argument list so sub dissector can get header info.
3005 header->req_id = request_id; /* save for sub dissector */
3006 header->rep_status = reply_status; /* save for sub dissector */
3008 dissect_reply_body(tvb, offset, pinfo, reply_tree, stream_is_big_endian,
3009 reply_status,header,tree);
3015 static void dissect_giop_cancel_request (tvbuff_t * tvb, packet_info * pinfo,
3016 proto_tree * tree, proto_tree * clnp_tree,
3017 MessageHeader * header, gboolean stream_is_big_endian) {
3021 proto_tree *cancel_request_tree = NULL;
3025 tf = proto_tree_add_text (tree, tvb, offset,
3027 "General Inter-ORB Protocol CancelRequest");
3028 cancel_request_tree = proto_item_add_subtree (tf, ett_giop_cancel_request);
3031 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
3033 if (check_col(pinfo->fd, COL_INFO)) {
3034 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
3038 proto_tree_add_text (cancel_request_tree, tvb, offset-4, 4,
3039 "Request id: %u", request_id);
3045 /** The formats for GIOP 1.0 and 1.1 Request messages are defined
3046 * in section 15.4.2.1 of the CORBA 2.4 specification.
3048 * struct RequestHeader{
3049 * IOP::ServiceContextList service_context;
3050 * unsigned long request_id;
3051 * boolean response_expected;
3052 * octet reserved[3]; // Only in GIOP 1.1
3053 * sequence<octet> object_key;
3055 * CORBA::OctetSeq requesting_principal;
3059 dissect_giop_request_1_1 (tvbuff_t * tvb, packet_info * pinfo,
3060 proto_tree * tree, proto_tree * clnp_tree,
3061 MessageHeader * header, gboolean stream_is_big_endian)
3067 guint32 objkey_len = 0; /* object key length */
3068 gchar *objkey = NULL; /* object key sequence */
3069 gchar *print_objkey = NULL; /* printable object key sequence */
3071 gchar *operation = NULL;
3072 gchar *requesting_principal = NULL;
3073 gchar *print_requesting_principal = NULL;
3074 guint8 response_expected;
3075 gchar *reserved = NULL;
3076 proto_tree *request_tree = NULL;
3079 gchar *repoid = NULL; /* from object key lookup in objkey hash */
3084 tf = proto_tree_add_text (tree, tvb, offset,
3086 "General Inter-ORB Protocol Request");
3087 if (request_tree == NULL)
3089 request_tree = proto_item_add_subtree (tf, ett_giop_request);
3098 * Decode IOP::ServiceContextList
3101 decode_ServiceContextList(tvb, pinfo, request_tree, &offset,stream_is_big_endian, GIOP_HEADER_SIZE);
3104 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
3105 if (check_col(pinfo->fd, COL_INFO))
3107 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
3111 proto_tree_add_text (request_tree, tvb, offset-4, 4,
3112 "Request id: %u", request_id);
3115 response_expected = tvb_get_guint8( tvb, offset );
3117 if (check_col(pinfo->fd, COL_INFO))
3119 col_append_fstr(pinfo->fd, COL_INFO, " (%s)",
3120 response_expected ? "two-way" : "one-way");
3124 proto_tree_add_text (request_tree, tvb, offset-1, 1,
3125 "Response expected: %u", response_expected);
3128 if( header->GIOP_version.minor > 0)
3130 get_CDR_octet_seq( tvb, &reserved, &offset, 3);
3133 proto_tree_add_text (request_tree, tvb, offset-3, 3,
3134 "Reserved: %x %x %x", reserved[0], reserved[1], reserved[2]);
3140 /* Length of object_key sequence */
3141 objkey_len = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
3146 proto_tree_add_text (request_tree, tvb, offset-4, 4,
3147 /**/ "Object Key length: %u", objkey_len);
3152 get_CDR_octet_seq(tvb, &objkey, &offset, objkey_len);
3154 print_objkey = make_printable_string(objkey, objkey_len);
3158 proto_tree_add_text (request_tree, tvb, offset - objkey_len, objkey_len,
3159 /**/ "Object Key: %s", print_objkey);
3164 /* length of operation string and string */
3165 len = get_CDR_string(tvb, &operation, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
3168 proto_tree_add_text (request_tree, tvb, offset - 4 - len, 4,
3169 /**/ "Operation length: %u", len);
3174 if (check_col(pinfo->fd, COL_INFO))
3176 col_append_fstr(pinfo->fd, COL_INFO, ": %s", operation);
3180 proto_tree_add_text (request_tree, tvb, offset - len, len,
3181 /**/ "Operation: %s", operation);
3186 /* length of requesting_principal string */
3187 len = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
3190 proto_tree_add_text (request_tree, tvb, offset-4, 4,
3191 /**/ "Requesting Principal Length: %u", len);
3196 get_CDR_octet_seq(tvb, &requesting_principal, &offset, len);
3198 print_requesting_principal = make_printable_string(requesting_principal, len);
3202 proto_tree_add_text (request_tree, tvb, offset - len, len,
3203 /**/ "Requesting Principal: %s", print_requesting_principal);
3210 * Save FN,reqid,and operation for later. Add sub_handle later.
3211 * But only if user is NOT clicking.
3214 if (! pinfo->fd->flags.visited)
3215 giop_complete_request_list = insert_in_comp_req_list(giop_complete_request_list,pinfo->fd->num,
3216 request_id,operation,NULL);
3220 * Call subdissector here before freeing "operation" and "key"
3221 * pass request_id also. But only if anything remains in tvbuff.
3222 * First try an find an explicit sub_dissector, then if that
3223 * fails, try the heuristic method.
3228 header->req_id = request_id; /* save for sub dissector */
3229 repoid = get_repoid_from_objkey(giop_objkey_hash,objkey,objkey_len);
3231 #if DEBUG_CALL_SUB_DISSECTORS
3234 try_explicit_giop_dissector(tvb,pinfo,tree,&offset,header,operation,repoid);
3236 try_heuristic_giop_dissector(tvb,pinfo,tree,&offset,header,operation);
3241 g_free( print_objkey );
3243 g_free( operation );
3244 g_free( requesting_principal );
3245 g_free( print_requesting_principal );
3249 /** The format of a GIOP 1.2 RequestHeader message is
3250 * (CORBA 2.4, sec. 15.4.2):
3252 * struct RequestHeader_1_2 {
3253 * unsigned long request_id;
3254 * octet response_flags;
3255 * octet reserved[3];
3256 * TargetAddress target;
3258 * IOP::ServiceContextList service_context;
3259 * // requesting_principal not in GIOP 1.2
3263 dissect_giop_request_1_2 (tvbuff_t * tvb, packet_info * pinfo,
3264 proto_tree * tree, proto_tree * clnp_tree,
3265 MessageHeader * header, gboolean stream_is_big_endian)
3270 guint8 response_flags;
3271 gchar *reserved = NULL;
3272 gchar *operation = NULL;
3273 proto_tree *request_tree = NULL;
3276 gchar *repoid = NULL;
3281 tf = proto_tree_add_text (tree, tvb, offset,
3283 "General Inter-ORB Protocol Request");
3284 request_tree = proto_item_add_subtree (tf, ett_giop_reply);
3287 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
3288 if (check_col(pinfo->fd, COL_INFO))
3290 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
3294 proto_tree_add_text (request_tree, tvb, offset-4, 4,
3295 "Request id: %u", request_id);
3298 response_flags = tvb_get_guint8( tvb, offset );
3302 proto_tree_add_text (request_tree, tvb, offset-1, 1,
3303 "Response flags: %s (%u)",
3304 match_strval(response_flags, sync_scope),
3308 get_CDR_octet_seq( tvb, &reserved, &offset, 3);
3311 proto_tree_add_text (request_tree, tvb, offset-3, 3,
3312 "Reserved: %x %x %x", reserved[0], reserved[1], reserved[2]);
3315 dissect_target_address(tvb, pinfo, &offset, request_tree, header, stream_is_big_endian);
3317 /* length of operation string */
3318 len = get_CDR_string(tvb, &operation, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
3321 proto_tree_add_text (request_tree, tvb, offset - len - 4, 4,
3322 /**/ "Operation length: %u", len);
3327 if (check_col(pinfo->fd, COL_INFO))
3329 col_append_fstr(pinfo->fd, COL_INFO, ": %s", operation);
3333 proto_tree_add_text (request_tree, tvb, offset - len, len,
3334 /**/ "Operation: %s", operation);
3341 * Decode IOP::ServiceContextList
3344 decode_ServiceContextList(tvb, pinfo, request_tree, &offset, stream_is_big_endian, GIOP_HEADER_SIZE);
3347 * GIOP 1.2 Request body must fall on an 8 octet alignment, taking into
3348 * account we are in a new tvbuff, GIOP_HEADER_SIZE octets from the
3349 * GIOP octet stream start.
3352 set_new_alignment(&offset, GIOP_HEADER_SIZE, 8);
3355 * Save FN,reqid,and operation for later. Add sub_handle later.
3356 * But only if user is NOT clicking.
3359 if (! pinfo->fd->flags.visited)
3360 giop_complete_request_list = insert_in_comp_req_list(giop_complete_request_list,pinfo->fd->num,
3361 request_id,operation,NULL);
3363 #if DEBUG_CALL_SUB_DISSECTORS
3366 try_explicit_giop_dissector(tvb,pinfo,tree,&offset,header,operation,repoid);
3368 try_heuristic_giop_dissector(tvb,pinfo,tree,&offset,header,operation);
3379 dissect_giop_locate_request( tvbuff_t * tvb, packet_info * pinfo,
3380 proto_tree * tree, MessageHeader * header,
3381 gboolean stream_is_big_endian)
3386 gchar *object_key = NULL;
3387 gchar *p_object_key = NULL;
3388 proto_tree *locate_request_tree = NULL;
3393 tf = proto_tree_add_text (tree, tvb, offset,
3395 "General Inter-ORB Locate Request");
3396 if (locate_request_tree == NULL)
3398 locate_request_tree = proto_item_add_subtree (tf, ett_giop_locate_request);
3403 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
3404 if (check_col(pinfo->fd, COL_INFO))
3406 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
3408 if (locate_request_tree)
3410 proto_tree_add_text (locate_request_tree, tvb, offset-4, 4,
3411 "Request id: %u", request_id);
3414 if(header->GIOP_version.minor < 2)
3416 len = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
3417 if (locate_request_tree)
3419 proto_tree_add_text (locate_request_tree, tvb, offset-4, 4,
3420 "Object Key length: %u", len);
3424 get_CDR_octet_seq(tvb, &object_key, &offset, len);
3426 p_object_key = make_printable_string(object_key, len);
3428 if(locate_request_tree)
3431 proto_tree_add_text (locate_request_tree, tvb, offset-len, len,
3432 "Object Key: %s", p_object_key);
3436 else /* GIOP 1.2 and higher */
3438 dissect_target_address(tvb, pinfo, &offset, locate_request_tree, header,
3439 stream_is_big_endian);
3443 g_free(p_object_key);
3447 dissect_giop_locate_reply( tvbuff_t * tvb, packet_info * pinfo,
3448 proto_tree * tree, MessageHeader * header,
3449 gboolean stream_is_big_endian)
3453 guint32 locate_status;
3456 proto_tree *locate_reply_tree = NULL;
3461 tf = proto_tree_add_text (tree, tvb, offset,
3463 "General Inter-ORB Locate Reply");
3464 if (locate_reply_tree == NULL)
3466 locate_reply_tree = proto_item_add_subtree (tf, ett_giop_locate_reply);
3471 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
3472 if (check_col(pinfo->fd, COL_INFO))
3474 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
3476 if (locate_reply_tree)
3478 proto_tree_add_text (locate_reply_tree, tvb, offset-4, 4,
3479 "Request id: %u", request_id);
3482 locate_status = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
3483 if (locate_reply_tree)
3485 proto_tree_add_text (locate_reply_tree, tvb, offset-4, 4,
3486 "Locate status: %s",
3487 match_strval(locate_status, giop_locate_status_types)
3491 /* Decode the LocateReply body.
3493 * For GIOP 1.0 and 1.1 body immediately follows header.
3494 * For GIOP 1.2 it is aligned on 8 octet boundary so need to
3498 if (header->GIOP_version.minor > 1) {
3499 while( ( (offset + GIOP_HEADER_SIZE) % 8) != 0)
3503 switch(locate_status) {
3504 case OBJECT_FORWARD: /* fall through to OBJECT_FORWARD_PERM */
3505 case OBJECT_FORWARD_PERM:
3506 decode_IOR(tvb, pinfo, locate_reply_tree, &offset, GIOP_HEADER_SIZE, stream_is_big_endian);
3508 case LOC_SYSTEM_EXCEPTION:
3509 decode_SystemExceptionReplyBody (tvb, tree, &offset, stream_is_big_endian, GIOP_HEADER_SIZE);
3511 case LOC_NEEDS_ADDRESSING_MODE:
3512 addr_disp = get_CDR_ushort(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
3513 if(locate_reply_tree) {
3514 proto_tree_add_text (tree, tvb, offset -2, 2,
3515 "AddressingDisposition: %u", addr_disp);
3518 default: /* others have no reply body */
3525 dissect_giop_fragment( tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
3526 MessageHeader * header, gboolean stream_is_big_endian)
3530 proto_tree *fragment_tree = NULL;
3535 tf = proto_tree_add_text (tree, tvb, offset,
3537 "General Inter-ORB Fragment");
3538 if (fragment_tree == NULL)
3540 fragment_tree = proto_item_add_subtree (tf, ett_giop_fragment);
3545 request_id = get_CDR_ulong(tvb, &offset, stream_is_big_endian,GIOP_HEADER_SIZE);
3546 if (check_col(pinfo->fd, COL_INFO))
3548 col_append_fstr(pinfo->fd, COL_INFO, " %u", request_id);
3552 proto_tree_add_text (fragment_tree, tvb, offset-4, 4,
3553 "Request id: %u", request_id);
3559 /* Main entry point */
3561 gboolean dissect_giop (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) {
3563 MessageHeader header;
3564 tvbuff_t *giop_header_tvb;
3565 tvbuff_t *payload_tvb;
3567 proto_tree *clnp_tree = NULL;
3570 u_int minor_version;
3571 gboolean stream_is_big_endian;
3577 giop_dump_collection(cd_module_hash);
3578 giop_dump_collection(cd_objkey_hash);
3579 giop_dump_collection(cd_heuristic_users);
3580 giop_dump_collection(cd_complete_reply_hash);
3581 giop_dump_collection(cd_complete_request_list);
3585 /* check magic number and version */
3588 /*define END_OF_GIOP_MESSAGE (offset - first_offset - GIOP_HEADER_SIZE) */
3590 if (tvb_length_remaining(tvb, 0) < GIOP_HEADER_SIZE)
3592 /* Not enough data captured to hold the GIOP header; don't try
3593 to interpret it as GIOP. */
3597 giop_header_tvb = tvb_new_subset (tvb, 0, GIOP_HEADER_SIZE, -1);
3598 payload_tvb = tvb_new_subset (tvb, GIOP_HEADER_SIZE, -1, -1);
3601 * because I have added extra elements in MessageHeader struct
3602 * for sub dissectors. -- FS
3605 tvb_memcpy (giop_header_tvb, (guint8 *)&header, 0, GIOP_HEADER_SIZE );
3607 if (memcmp (header.magic, GIOP_MAGIC, sizeof (header.magic)) != 0)
3609 /* Not a GIOP message. */
3614 if (check_col (pinfo->fd, COL_PROTOCOL))
3616 col_set_str (pinfo->fd, COL_PROTOCOL, "GIOP");
3619 if (header.GIOP_version.major != GIOP_MAJOR ||
3620 ((minor_version = header.GIOP_version.minor) > GIOP_MINOR))
3622 /* Bad version number; should we note that and dissect the rest
3623 as data, or should we return FALSE on the theory that it
3624 might have been some other packet that happened to begin with
3625 "GIOP"? We shouldn't do *both*, so we return TRUE, for now.
3626 If we should return FALSE, we should do so *without* setting
3627 the "Info" column, *without* setting the "Protocol" column,
3628 and *without* adding anything to the protocol tree. */
3630 if (check_col (pinfo->fd, COL_INFO))
3632 col_add_fstr (pinfo->fd, COL_INFO, "Version %u.%u",
3633 header.GIOP_version.major, header.GIOP_version.minor);
3637 ti = proto_tree_add_item (tree, proto_giop, tvb, 0,
3638 tvb_length (tvb), FALSE);
3639 clnp_tree = proto_item_add_subtree (ti, ett_giop);
3640 proto_tree_add_text (clnp_tree, giop_header_tvb, 0,
3641 tvb_length (giop_header_tvb),
3642 "Version %u.%u not supported",
3643 header.GIOP_version.major,
3644 header.GIOP_version.minor);
3646 dissect_data (payload_tvb, 0, pinfo, tree);
3650 if (check_col (pinfo->fd, COL_INFO))
3652 col_add_fstr (pinfo->fd, COL_INFO, "GIOP %u.%u %s",
3653 header.GIOP_version.major, header.GIOP_version.minor,
3654 val_to_str(header.message_type, giop_message_types,
3655 "Unknown message type (0x%02x)"));
3658 stream_is_big_endian = is_big_endian (&header);
3660 if (stream_is_big_endian)
3661 message_size = pntohl (&header.message_size);
3663 message_size = pletohl (&header.message_size);
3667 ti = proto_tree_add_item (tree, proto_giop, tvb, 0, 12, FALSE);
3668 clnp_tree = proto_item_add_subtree (ti, ett_giop);
3669 proto_tree_add_text (clnp_tree, giop_header_tvb, offset, 4,
3670 "Magic number: %s", GIOP_MAGIC);
3671 proto_tree_add_text (clnp_tree, giop_header_tvb, 4, 2,
3673 header.GIOP_version.major,
3674 header.GIOP_version.minor);
3675 switch (minor_version)
3679 proto_tree_add_text (clnp_tree, giop_header_tvb, 6, 1,
3680 "Flags: 0x%02x (%s %s)",
3682 (stream_is_big_endian) ? "big-endian" : "little-endian",
3683 (header.flags & 0x02) ? " fragment" : "");
3686 proto_tree_add_text (clnp_tree, giop_header_tvb, 6, 1,
3687 "Byte ordering: %s-endian",
3688 (stream_is_big_endian) ? "big" : "little");
3692 } /* minor_version */
3694 proto_tree_add_uint_format (clnp_tree,
3695 hf_giop_message_type,
3696 giop_header_tvb, 7, 1,
3697 header.message_type,
3698 "Message type: %s", match_strval(header.message_type, giop_message_types));
3700 proto_tree_add_uint (clnp_tree,
3701 hf_giop_message_size,
3702 giop_header_tvb, 8, 4, message_size);
3707 if (check_col (pinfo->fd, COL_INFO))
3709 col_add_fstr (pinfo->fd, COL_INFO, "GIOP %u.%u %s",
3710 header.GIOP_version.major, header.GIOP_version.minor,
3711 match_strval(header.message_type, giop_message_types));
3715 switch (header.message_type)
3719 if(header.GIOP_version.minor < 2)
3721 dissect_giop_request_1_1 (payload_tvb, pinfo, tree, clnp_tree,
3722 &header, stream_is_big_endian);
3726 dissect_giop_request_1_2 (payload_tvb, pinfo, tree, clnp_tree,
3727 &header, stream_is_big_endian);
3734 if(header.GIOP_version.minor < 2)
3736 dissect_giop_reply (payload_tvb, pinfo, tree, clnp_tree, &header,
3737 stream_is_big_endian);
3741 dissect_giop_reply_1_2 (payload_tvb, pinfo, tree, clnp_tree,
3742 &header, stream_is_big_endian);
3746 dissect_giop_cancel_request(payload_tvb, pinfo, tree, clnp_tree,
3747 &header, stream_is_big_endian);
3750 dissect_giop_locate_request(payload_tvb, pinfo, tree, &header,
3751 stream_is_big_endian);
3754 dissect_giop_locate_reply(payload_tvb, pinfo, tree, &header,
3755 stream_is_big_endian);
3758 dissect_giop_fragment(payload_tvb, pinfo, tree, &header,
3759 stream_is_big_endian);
3764 } /* switch message_type */
3773 proto_register_giop (void)
3775 static hf_register_info hf[] = {
3776 { &hf_giop_message_type,
3777 { "Message type", "giop.type",
3778 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }
3781 { &hf_giop_message_size,
3782 { "Message size", "giop.len",
3783 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
3787 { "Repository ID", "giop.repoid",
3788 FT_STRING, BASE_DEC, NULL, 0x0, "", HFILL }
3791 { &hf_giop_string_length,
3792 { "String Length", "giop.strlen",
3793 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
3796 { &hf_giop_sequence_length,
3797 { "Sequence Length", "giop.seqlen",
3798 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
3801 { &hf_giop_profile_id,
3802 { "Profile ID", "giop.profid",
3803 FT_UINT32, BASE_DEC, VALS(profile_id_vals), 0x0, "", HFILL }
3808 { "IOR::type_id", "giop.typeid",
3809 FT_STRING, BASE_DEC, NULL, 0x0, "", HFILL }
3812 { &hf_giop_iiop_v_maj,
3813 { "IIOP Major Version", "giop.iiop_vmaj",
3814 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }
3817 { &hf_giop_iiop_v_min,
3818 { "IIOP Minor Version", "giop.iiop_vmin",
3819 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }
3822 { &hf_giop_endianess,
3823 { "Endianess", "giop.endianess",
3824 FT_UINT8, BASE_DEC, VALS(giop_endianess_vals), 0x0, "", HFILL }
3827 { &hf_giop_IIOP_tag,
3828 { "IIOP Component TAG", "giop.iioptag",
3829 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
3833 { "IOR Profile TAG", "giop.iortag",
3834 FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }
3838 { "TypeCode enum", "giop.TCKind",
3839 FT_UINT32, BASE_DEC, VALS(tckind_vals), 0x0, "", HFILL }
3842 { &hf_giop_typecode_count,
3843 { "TypeCode count", "giop.tccount",
3844 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
3847 { &hf_giop_typecode_default_used,
3848 { "default_used", "giop.tcdefault_used",
3849 FT_INT32, BASE_DEC, NULL, 0x0, "", HFILL }
3852 { &hf_giop_typecode_digits,
3853 { "Digits", "giop.tcdigits",
3854 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
3858 { &hf_giop_typecode_length,
3859 { "Length", "giop.tclength",
3860 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
3863 { &hf_giop_typecode_max_length,
3864 { "Maximum length", "giop.tcmaxlen",
3865 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
3868 { &hf_giop_typecode_member_name,
3869 { "TypeCode member name", "giop.tcmemname",
3870 FT_STRING, BASE_DEC, NULL, 0x0, "", HFILL }
3873 { &hf_giop_typecode_name,
3874 { "TypeCode name", "giop.tcname",
3875 FT_STRING, BASE_DEC, NULL, 0x0, "", HFILL }
3878 { &hf_giop_typecode_scale,
3879 { "Scale", "giop.tcscale",
3880 FT_INT16, BASE_DEC, NULL, 0x0, "", HFILL }
3883 { &hf_giop_typecode_ValueModifier,
3884 { "ValueModifier", "giop.tcValueModifier",
3885 FT_INT16, BASE_DEC, NULL, 0x0, "", HFILL }
3888 { &hf_giop_typecode_Visibility,
3889 { "Visibility", "giop.tcVisibility",
3890 FT_INT16, BASE_DEC, NULL, 0x0, "", HFILL }
3895 { &hf_giop_type_boolean,
3896 { "TypeCode boolean data", "giop.tcboolean",
3897 FT_BOOLEAN, BASE_DEC, NULL, 0x0, "" }
3900 { &hf_giop_type_char,
3901 { "TypeCode char data", "giop.tcchar",
3902 FT_UINT8, BASE_DEC, NULL, 0x0, "" }
3905 { &hf_giop_type_double,
3906 { "TypeCode double data", "giop.tcdouble",
3907 FT_DOUBLE, BASE_DEC, NULL, 0x0, "" }
3910 { &hf_giop_type_enum,
3911 { "TypeCode enum data", "giop.tcenumdata",
3912 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
3916 * float as double ?? -- FIX
3919 { &hf_giop_type_float,
3920 { "TypeCode float data", "giop.tcfloat",
3921 FT_DOUBLE, BASE_DEC, NULL, 0x0, "" }
3924 { &hf_giop_type_long,
3925 { "TypeCode long data", "giop.tclongdata",
3926 FT_INT32, BASE_DEC, NULL, 0x0, "", HFILL }
3929 { &hf_giop_type_octet,
3930 { "TypeCode octet data", "giop.tcoctet",
3931 FT_UINT8, BASE_DEC, NULL, 0x0, "" }
3934 { &hf_giop_type_short,
3935 { "TypeCode short data", "giop.tcshortdata",
3936 FT_INT16, BASE_DEC, NULL, 0x0, "", HFILL }
3939 { &hf_giop_type_string,
3940 { "TypeCode string data", "giop.tcstring",
3941 FT_STRING, BASE_DEC, NULL, 0x0, "" }
3944 { &hf_giop_type_ulong,
3945 { "TypeCode ulong data", "giop.tculongdata",
3946 FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }
3949 { &hf_giop_type_ushort,
3950 { "TypeCode ushort data", "giop.tcushortdata",
3951 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
3955 * IIOP Module - Chapter 15.10.2
3958 { &hf_giop_iiop_host,
3959 { "IIOP::Profile_host", "giop.iiop.host",
3960 FT_STRING, BASE_DEC, NULL, 0x0, "", HFILL }
3964 { &hf_giop_iiop_port,
3965 { "IIOP::Profile_port", "giop.iiop.port",
3966 FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
3971 * IIOP ServiceContext
3974 { &hf_giop_iop_vscid,
3975 { "VSCID", "giop.iiop.vscid",
3976 FT_UINT32, BASE_HEX, NULL, 0xfffff000, "", HFILL }
3980 { &hf_giop_iop_scid,
3981 { "SCID", "giop.iiop.scid",
3982 FT_UINT32, BASE_HEX, NULL, 0x00000fff, "", HFILL }
3989 static gint *ett[] = {
3993 &ett_giop_cancel_request,
3994 &ett_giop_locate_request,
3995 &ett_giop_locate_reply,
3998 proto_giop = proto_register_protocol("General Inter-ORB Protocol", "GIOP",
4000 proto_register_field_array (proto_giop, hf, array_length (hf));
4001 proto_register_subtree_array (ett, array_length (ett));
4004 /* register init routine */
4006 register_init_routine( &giop_init); /* any init stuff */
4009 * Init the giop user module hash tables here, as giop users
4010 * will populate it via register_giop_user_module BEFORE my
4011 * own giop_init() is called.
4014 giop_module_hash = g_hash_table_new(giop_hash_module_hash, giop_hash_module_equal);
4016 giop_module_keys = g_mem_chunk_new("giop_module_keys",
4017 sizeof(struct giop_module_key),
4018 giop_module_init_count * sizeof(struct giop_module_key),
4021 giop_module_vals = g_mem_chunk_new("giop_module_vals",
4022 sizeof(struct giop_module_val),
4023 giop_module_init_count * sizeof(struct giop_module_val),
4030 void proto_reg_handoff_giop (void) {
4031 heur_dissector_add("tcp", dissect_giop, proto_giop);
4040 * Ref Corba v2.4.2 Chapter 13
4048 typedef unsigned long ProfileId;
4050 const ProfileId TAG_INTERNET_IOP = 0;
4051 const ProfileId TAG_MULTIPLE_COMPONENTS = 1;
4053 struct TaggedProfile {
4055 sequence <octet> profile_data;
4060 sequence <TaggedProfile> profiles;
4063 typedef unsigned long ComponentId;
4065 struct TaggedComponent {
4067 sequence <octet> component_data;
4070 typedef sequence <TaggedComponent> MultipleComponentProfile;
4076 void decode_IOR(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset,
4077 guint32 boundary, gboolean stream_is_big_endian) {
4080 guint32 seqlen_p; /* sequence length of profiles */
4083 gchar *repobuf = NULL; /* for repository ID */
4087 /* Get type_id == Repository ID */
4089 u_octet4 = get_CDR_string(tvb,&repobuf,offset,stream_is_big_endian,boundary);
4092 proto_tree_add_uint(tree,hf_giop_string_length,tvb,
4093 *offset-u_octet4-sizeof(u_octet4),4,u_octet4);
4095 proto_tree_add_string(tree,hf_giop_type_id,tvb,
4096 *offset-u_octet4,u_octet4,repobuf);
4101 /* g_free(repobuf); */ /* dont free yet, as must wait until I have */
4102 /* the object key before I can add both to hash */
4103 /* this is done later */
4105 /* Now get a sequence of profiles */
4106 /* Get sequence length (number of elements) */
4108 seqlen_p = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary);
4110 proto_tree_add_uint(tree,hf_giop_sequence_length,tvb,
4111 *offset-sizeof(seqlen_p),4,seqlen_p);
4115 /* fetch all TaggedProfiles in this sequence */
4117 for (i=0; i< seqlen_p; i++) { /* for every TaggedProfile */
4118 decode_TaggedProfile(tvb, pinfo, tree, offset, boundary, stream_is_big_endian, repobuf);
4123 static void decode_TaggedProfile(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset,
4124 guint32 boundary, gboolean stream_is_big_endian, gchar *repobuf) {
4126 guint32 seqlen_pd; /* sequence length of profile data */
4128 guint32 pidtag; /* profile ID TAG */
4130 gchar *profile_data = NULL; /* profile_data pointer */
4131 gchar *p_profile_data = NULL; /* printable profile_data pointer */
4133 guint32 new_boundary; /* for encapsulations encountered */
4134 gboolean new_big_endianess; /* for encapsulations encountered */
4136 /* Get ProfileId tag */
4138 pidtag = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary);
4141 proto_tree_add_uint(tree,hf_giop_profile_id,tvb,
4142 *offset-sizeof(pidtag),4,pidtag);
4145 /* get sequence length, new endianness and boundary for encapsulation */
4147 seqlen_pd = get_CDR_encap_info(tvb, tree, offset,
4148 stream_is_big_endian, boundary,
4149 &new_big_endianess, &new_boundary);
4151 /* return if zero length sequence */
4158 * Lets see what kind of TAG it is. If TAG_INTERNET_IOP then
4159 * decode it, otherwise just dump the octet sequence
4161 * also, store IOR in our objectkey hash
4163 * TODO - handle other TAGS
4167 case IOP_TAG_INTERNET_IOP:
4169 decode_IIOP_IOR_profile(tvb, pinfo, tree, offset, new_boundary, new_big_endianess, repobuf, TRUE);
4174 /* fetch all octets in this sequence */
4176 get_CDR_octet_seq(tvb, &profile_data, offset, seqlen_pd);
4178 /* Make a printable string */
4180 p_profile_data = make_printable_string( profile_data, seqlen_pd );
4183 proto_tree_add_text (tree, tvb, *offset -seqlen_pd, seqlen_pd,
4184 "Profile Data: %s", p_profile_data);
4190 g_free(profile_data);
4191 g_free(p_profile_data);
4198 * Decode IIOP IOR Profile
4199 * Ref Chap 15.7.2 in Corba Spec
4203 static void decode_IIOP_IOR_profile(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset,
4204 guint32 boundary, gboolean stream_is_big_endian, gchar *repo_id_buf,
4205 gboolean store_flag) {
4207 int i; /* loop index */
4209 guint8 v_major,v_minor; /* IIOP sersion */
4211 guint32 u_octet4; /* u long */
4212 guint16 u_octet2; /* u short */
4213 guint32 seqlen; /* generic sequence length */
4214 guint32 seqlen1; /* generic sequence length */
4215 gchar *objkey = NULL; /* object key pointer */
4216 gchar *p_chars = NULL; /* printable characters pointer */
4219 /* Get major/minor version */
4221 v_major = get_CDR_octet(tvb,offset);
4222 v_minor = get_CDR_octet(tvb,offset);
4226 proto_tree_add_uint(tree,hf_giop_iiop_v_maj,tvb,
4227 *offset-sizeof(v_minor)-sizeof(v_major),1,v_major );
4228 proto_tree_add_uint(tree,hf_giop_iiop_v_min,tvb,
4229 *offset-sizeof(v_minor),1,v_minor );
4235 u_octet4 = get_CDR_string(tvb,&buf,offset,stream_is_big_endian,boundary);
4238 proto_tree_add_uint(tree,hf_giop_string_length,tvb,
4239 *offset-u_octet4-sizeof(u_octet4),4,u_octet4);
4241 proto_tree_add_string(tree,hf_giop_iiop_host,tvb,
4242 *offset-u_octet4,u_octet4,buf);
4246 g_free(buf); /* dont forget */
4250 u_octet2 = get_CDR_ushort(tvb,offset,stream_is_big_endian,boundary);
4253 proto_tree_add_uint(tree,hf_giop_iiop_port,tvb,
4254 *offset-sizeof(u_octet2),2,u_octet2);
4258 /* Object Key - sequence<octet> object_key */
4260 seqlen = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary);
4263 proto_tree_add_uint(tree,hf_giop_sequence_length,tvb,
4264 *offset-sizeof(seqlen),4,seqlen);
4268 /* fetch all octets in this sequence */
4269 get_CDR_octet_seq(tvb, &objkey, offset, seqlen);
4272 * Now we may have the Repository ID from earlier, as well
4273 * as the object key sequence and lengh. So lets store them in
4274 * our objectkey hash and free buffers.
4276 * But only insert if user is not clicking and repo id not NULL.
4282 if(!pinfo->fd->flags.visited)
4283 insert_in_objkey_hash(giop_objkey_hash,objkey,seqlen,repo_id_buf,req_res);
4288 * No pinfo, but store anyway if flag set. eg: IOR read from file
4292 insert_in_objkey_hash(giop_objkey_hash,objkey,seqlen,repo_id_buf,file);
4296 /* Make a printable string */
4298 p_chars = make_printable_string( objkey, seqlen );
4301 proto_tree_add_text (tree, tvb, *offset -seqlen, seqlen,
4302 "Object Key: %s", p_chars);
4306 g_free(repo_id_buf);
4309 p_chars = NULL; /* reuse later */
4312 * Now see if if its v1.1 or 1.2, as they can contain
4313 * extra sequence of IOP::TaggedComponents
4326 /* sequence of IOP::TaggedComponents */
4327 /* Ref Chap 13 in Corba Spec */
4329 /* get sequence length */
4330 seqlen = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary);
4333 proto_tree_add_uint(tree,hf_giop_sequence_length,tvb,
4334 *offset-sizeof(seqlen),4,seqlen);
4337 for (i=0; i< seqlen; i++) {
4339 u_octet4 = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary);
4341 proto_tree_add_uint(tree,hf_giop_IIOP_tag,tvb,
4342 *offset-sizeof(u_octet4),4,u_octet4);
4345 /* get component_data */
4346 seqlen1 = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary);
4348 proto_tree_add_uint(tree,hf_giop_sequence_length,tvb,
4349 *offset-sizeof(seqlen1),4,seqlen1);
4353 get_CDR_octet_seq(tvb, &buf, offset, seqlen1);
4356 /* Make a printable string of data */
4358 p_chars = make_printable_string(buf, seqlen1);
4360 proto_tree_add_text (tree, tvb, *offset -seqlen1, seqlen1,
4361 "component_data: %s", p_chars);
4368 buf = NULL; /* reuse later */
4369 p_chars = NULL; /* reuse later */
4377 g_warning("giop:Invalid v_minor value = %u ", v_minor);
4385 * Service Contexts Begin
4393 void dissect_SID_BI_DIR_IIOP(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset,
4394 MessageHeader *header, gchar *operation, guint32 boundary) {
4404 * Service Contexts End
4416 * typedef unsigned long ServiceID;
4418 * struct ServiceContext {
4419 * ServiceID context_id;
4420 * sequence <octet> context_data;
4422 * typedef sequence <ServiceContext> ServiceContextList;
4425 * Note: Spec says context_data is an encapsulation.
4432 void decode_ServiceContextList(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset,
4433 gboolean stream_is_be, guint32 boundary) {
4435 guint32 seqlen; /* sequence length */
4436 guint32 seqlen_cd; /* sequence length, context_data */
4439 gchar *context_data = NULL;
4440 gchar *p_context_data = NULL;
4443 guint32 vscid; /* Vendor Service context id */
4447 /* Get sequence length (number of elements) */
4449 seqlen = get_CDR_ulong(tvb,offset,stream_is_be,boundary);
4451 proto_tree_add_uint(tree,hf_giop_sequence_length,tvb,
4452 *offset-sizeof(seqlen),4,seqlen);
4455 /* return if zero length sequence */
4460 /* Loop for all ServiceContext's */
4462 for (i=0; i<seqlen; i++) {
4464 context_id = get_CDR_ulong(tvb,offset,stream_is_be,boundary);
4466 proto_tree_add_uint(tree,hf_giop_iop_vscid,tvb,
4467 *offset-sizeof(context_id),4,context_id);
4469 proto_tree_add_uint(tree,hf_giop_iop_scid,tvb,
4470 *offset-sizeof(context_id),4,context_id);
4474 vscid = context_id && 0xfffff000; /* vendor info, top 20 bits */
4475 scid = context_id && 0x00000fff; /* standard service info, lower 12 bits */
4478 #if CONTEXT_DATA_IS_ENCAPSULATED
4480 /* get sequence length, new endianness and boundary for encapsulation */
4482 seqlen_cd = get_CDR_encap_info(tvb, tree, offset,
4483 stream_is_be, boundary,
4484 &new_big_endianess, &new_boundary);
4488 /* get sequence length, and NO encapsulation */
4490 seqlen_cd = get_CDR_ulong(tvb, offset, stream_is_be,boundary);
4494 /* return if zero length sequence */
4500 * Now decode sequence according to vendor ServiceId, but I dont
4501 * have that yet, so just dump it as data.
4504 /* fetch all octets in this sequence */
4506 get_CDR_octet_seq(tvb, &context_data, offset, seqlen_cd);
4508 /* Make a printable string */
4510 p_context_data = make_printable_string( context_data, seqlen_cd );
4513 proto_tree_add_text (tree, tvb, *offset - seqlen_cd , seqlen_cd,
4514 "context_data: %s", p_context_data);
4517 g_free(context_data);
4518 g_free(p_context_data);
4523 return; /* for now, fix later */
4528 /* Decode SystemExceptionReplyBody as defined in the CORBA spec chapter 15.
4531 static void decode_SystemExceptionReplyBody (tvbuff_t *tvb, proto_tree *tree, gint *offset,
4532 gboolean stream_is_big_endian,
4535 guint32 length; /* string length */
4536 guint32 minor_code_value;
4537 guint32 completion_status;
4539 gchar *buf = NULL; /* pointer to string buffer */
4541 length = get_CDR_string(tvb, &buf, offset, stream_is_big_endian, boundary);
4544 proto_tree_add_text(tree, tvb, *offset-4, 4,
4545 "Exception length: %u", length);
4547 proto_tree_add_text(tree, tvb, *offset - length, length,
4548 "Exception id: %s", buf );
4552 minor_code_value = get_CDR_ulong(tvb, offset, stream_is_big_endian, boundary);
4553 completion_status = get_CDR_ulong(tvb, offset, stream_is_big_endian, boundary);
4556 proto_tree_add_text(tree, tvb, *offset-8, 4,
4557 "Minor code value: %u", minor_code_value);
4558 proto_tree_add_text(tree, tvb, *offset-4, 4,
4559 "Completion Status: %u", completion_status);
4565 * Helper functions for dissecting TypeCodes
4567 * These functions decode the complex parameter lists
4568 * of TypeCodes as defined in the CORBA spec chapter 15.
4571 static void dissect_tk_objref_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
4572 gboolean stream_is_big_endian, guint32 boundary,
4573 MessageHeader * header) {
4575 guint32 new_boundary; /* new boundary for encapsulation */
4576 gboolean new_stream_is_big_endian; /* new endianness for encapsulation */
4578 guint32 seqlen; /* sequence length */
4580 /* get sequence length, new endianness and boundary for encapsulation */
4581 seqlen = get_CDR_encap_info(tvb, tree, offset,
4582 stream_is_big_endian, boundary,
4583 &new_stream_is_big_endian, &new_boundary);
4585 /* get repository ID */
4586 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4590 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4591 hf_giop_typecode_name);
4596 static void dissect_tk_struct_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
4597 gboolean stream_is_big_endian, guint32 boundary,
4598 MessageHeader * header ) {
4600 guint32 new_boundary; /* new boundary for encapsulation */
4601 gboolean new_stream_is_big_endian; /* new endianness for encapsulation */
4603 guint32 count; /* parameter count (of tuples) */
4604 guint32 seqlen; /* sequence length */
4605 int i; /* loop index */
4607 /* get sequence lengt,h new endianness and boundary for encapsulation */
4608 seqlen = get_CDR_encap_info(tvb, tree, offset,
4609 stream_is_big_endian, boundary,
4610 &new_stream_is_big_endian, &new_boundary);
4612 /* get repository ID */
4613 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4617 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4618 hf_giop_typecode_name);
4620 /* get count of tuples */
4621 count = get_CDR_ulong(tvb,offset,new_stream_is_big_endian,new_boundary);
4623 proto_tree_add_uint(tree,hf_giop_typecode_count,tvb,
4624 *offset-sizeof(count),4,count);
4627 /* get all tuples */
4628 for (i=0; i< count; i++) {
4629 /* get member name */
4630 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4631 hf_giop_typecode_member_name);
4633 /* get member type */
4634 get_CDR_typeCode(tvb,tree,offset,new_stream_is_big_endian,new_boundary,header);
4640 static void dissect_tk_union_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
4641 gboolean stream_is_big_endian, guint32 boundary,
4642 MessageHeader * header) {
4644 guint32 new_boundary; /* new boundary for encapsulation */
4645 gboolean new_stream_is_big_endian; /* new endianness for encapsulation */
4647 guint32 TCKind; /* TypeCode */
4648 gint32 s_octet4; /* signed int32 */
4650 guint32 count; /* parameter count (of tuples) */
4651 guint32 seqlen; /* sequence length */
4652 int i; /* loop index */
4654 /* get sequence legnth, new endianness and boundary for encapsulation */
4655 seqlen = get_CDR_encap_info(tvb, tree, offset,
4656 stream_is_big_endian, boundary,
4657 &new_stream_is_big_endian, &new_boundary);
4659 /* get repository ID */
4660 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4664 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4665 hf_giop_typecode_name);
4667 /* get discriminant type */
4668 TCKind = get_CDR_typeCode(tvb,tree,offset,new_stream_is_big_endian,new_boundary,header);
4670 /* get default used */
4671 s_octet4 = get_CDR_long(tvb,offset,new_stream_is_big_endian,new_boundary);
4673 proto_tree_add_int(tree,hf_giop_typecode_default_used,tvb,
4674 *offset-sizeof(s_octet4),4,s_octet4);
4676 /* get count of tuples */
4677 count = get_CDR_ulong(tvb,offset,new_stream_is_big_endian,new_boundary);
4679 proto_tree_add_uint(tree,hf_giop_typecode_count,tvb,
4680 *offset-sizeof(count),4,count);
4683 /* get all tuples */
4684 for (i=0; i< count; i++) {
4685 /* get label value, based on TCKind above */
4686 dissect_data_for_typecode(tvb, tree, offset, new_stream_is_big_endian, new_boundary, header, TCKind );
4688 /* get member name */
4689 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4690 hf_giop_typecode_member_name);
4692 /* get member type */
4693 get_CDR_typeCode(tvb,tree,offset,new_stream_is_big_endian,new_boundary,header);
4699 static void dissect_tk_enum_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
4700 gboolean stream_is_big_endian, guint32 boundary,
4701 MessageHeader * header) {
4703 guint32 new_boundary; /* new boundary for encapsulation */
4704 gboolean new_stream_is_big_endian; /* new endianness for encapsulation */
4706 guint32 count; /* parameter count (of tuples) */
4707 guint32 seqlen; /* sequence length */
4708 int i; /* loop index */
4710 /* get sequence length, new endianness and boundary for encapsulation */
4711 seqlen = get_CDR_encap_info(tvb, tree, offset,
4712 stream_is_big_endian, boundary,
4713 &new_stream_is_big_endian, &new_boundary);
4715 /* get repository ID */
4716 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4720 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4721 hf_giop_typecode_name);
4723 /* get count of tuples */
4724 count = get_CDR_ulong(tvb,offset,new_stream_is_big_endian,new_boundary);
4726 proto_tree_add_uint(tree,hf_giop_typecode_count,tvb,
4727 *offset-sizeof(count),4,count);
4730 /* get all tuples */
4731 for (i=0; i< count; i++) {
4732 /* get member name */
4733 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4734 hf_giop_typecode_member_name);
4740 static void dissect_tk_sequence_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
4741 gboolean stream_is_big_endian, guint32 boundary,
4742 MessageHeader * header) {
4744 guint32 new_boundary; /* new boundary for encapsulation */
4745 gboolean new_stream_is_big_endian; /* new endianness for encapsulation */
4747 guint32 u_octet4; /* unsigned int32 */
4749 guint32 seqlen; /* sequence length */
4751 /* get sequence length, new endianness and boundary for encapsulation */
4752 seqlen = get_CDR_encap_info(tvb, tree, offset,
4753 stream_is_big_endian, boundary,
4754 &new_stream_is_big_endian, &new_boundary);
4756 /* get element type */
4757 get_CDR_typeCode(tvb,tree,offset,new_stream_is_big_endian,new_boundary,header);
4759 /* get max length */
4760 u_octet4 = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary);
4762 proto_tree_add_uint(tree,hf_giop_typecode_max_length,tvb,
4763 *offset-sizeof(u_octet4),4,u_octet4);
4768 static void dissect_tk_array_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
4769 gboolean stream_is_big_endian, guint32 boundary,
4770 MessageHeader * header) {
4772 guint32 new_boundary; /* new boundary for encapsulation */
4773 gboolean new_stream_is_big_endian; /* new endianness for encapsulation */
4775 guint32 u_octet4; /* unsigned int32 */
4777 guint32 seqlen; /* sequence length */
4779 /* get sequence length, new endianness and boundary for encapsulation */
4780 seqlen = get_CDR_encap_info(tvb, tree, offset,
4781 stream_is_big_endian, boundary,
4782 &new_stream_is_big_endian, &new_boundary);
4784 /* get element type */
4785 get_CDR_typeCode(tvb,tree,offset,new_stream_is_big_endian,new_boundary,header);
4788 u_octet4 = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary);
4790 proto_tree_add_uint(tree,hf_giop_typecode_length,tvb,
4791 *offset-sizeof(u_octet4),4,u_octet4);
4796 static void dissect_tk_alias_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
4797 gboolean stream_is_big_endian, guint32 boundary,
4798 MessageHeader * header) {
4800 guint32 new_boundary; /* new boundary for encapsulation */
4801 gboolean new_stream_is_big_endian; /* new endianness for encapsulation */
4803 guint32 seqlen; /* sequence length */
4805 /* get sequence legnth, new endianness and boundary for encapsulation */
4806 seqlen = get_CDR_encap_info(tvb, tree, offset,
4807 stream_is_big_endian, boundary,
4808 &new_stream_is_big_endian, &new_boundary);
4810 /* get repository ID */
4811 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4815 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4816 hf_giop_typecode_name);
4818 /* get ??? (noname) TypeCode */
4819 get_CDR_typeCode(tvb,tree,offset,new_stream_is_big_endian,new_boundary,header);
4824 static void dissect_tk_except_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
4825 gboolean stream_is_big_endian, guint32 boundary,
4826 MessageHeader * header) {
4828 guint32 new_boundary; /* new boundary for encapsulation */
4829 gboolean new_stream_is_big_endian; /* new endianness for encapsulation */
4831 guint32 count; /* parameter count (of tuples) */
4832 guint32 seqlen; /* sequence length */
4833 int i; /* loop index */
4835 /* get sequence length, new endianness and boundary for encapsulation */
4836 seqlen = get_CDR_encap_info(tvb, tree, offset,
4837 stream_is_big_endian, boundary,
4838 &new_stream_is_big_endian, &new_boundary);
4840 /* get repository ID */
4841 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4845 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4846 hf_giop_typecode_name);
4848 /* get count of tuples */
4849 count = get_CDR_ulong(tvb,offset,new_stream_is_big_endian,new_boundary);
4851 proto_tree_add_uint(tree,hf_giop_typecode_count,tvb,
4852 *offset-sizeof(count),4,count);
4855 /* get all tuples */
4856 for (i=0; i< count; i++) {
4857 /* get member name */
4858 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4859 hf_giop_typecode_member_name);
4861 /* get member type */
4862 get_CDR_typeCode(tvb,tree,offset,new_stream_is_big_endian,new_boundary,header);
4868 static void dissect_tk_value_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
4869 gboolean stream_is_big_endian, guint32 boundary,
4870 MessageHeader * header) {
4872 guint32 new_boundary; /* new boundary for encapsulation */
4873 gboolean new_stream_is_big_endian; /* new endianness for encapsulation */
4875 gint16 s_octet2; /* signed int16 */
4877 guint32 count; /* parameter count (of tuples) */
4878 guint32 seqlen; /* sequence length */
4879 int i; /* loop index */
4881 /* get sequence length, new endianness and boundary for encapsulation */
4882 seqlen = get_CDR_encap_info(tvb, tree, offset,
4883 stream_is_big_endian, boundary,
4884 &new_stream_is_big_endian, &new_boundary);
4886 /* get repository ID */
4887 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4891 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4892 hf_giop_typecode_name);
4894 /* get ValueModifier */
4895 s_octet2 = get_CDR_short(tvb,offset,stream_is_big_endian,boundary);
4897 proto_tree_add_int(tree,hf_giop_typecode_ValueModifier,tvb,
4898 *offset-sizeof(s_octet2),2,s_octet2);
4901 /* get conrete base */
4902 get_CDR_typeCode(tvb,tree,offset,new_stream_is_big_endian,new_boundary,header);
4904 /* get count of tuples */
4905 count = get_CDR_ulong(tvb,offset,new_stream_is_big_endian,new_boundary);
4907 proto_tree_add_uint(tree,hf_giop_typecode_count,tvb,
4908 *offset-sizeof(count),4,count);
4911 /* get all tuples */
4912 for (i=0; i< count; i++) {
4913 /* get member name */
4914 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4915 hf_giop_typecode_member_name);
4917 /* get member type */
4918 get_CDR_typeCode(tvb,tree,offset,new_stream_is_big_endian,new_boundary,header);
4920 /* get Visibility */
4921 s_octet2 = get_CDR_short(tvb,offset,stream_is_big_endian,boundary);
4923 proto_tree_add_int(tree,hf_giop_typecode_Visibility,tvb,
4924 *offset-sizeof(s_octet2),2,s_octet2);
4931 static void dissect_tk_value_box_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
4932 gboolean stream_is_big_endian, guint32 boundary,
4933 MessageHeader * header) {
4935 guint32 new_boundary; /* new boundary for encapsulation */
4936 gboolean new_stream_is_big_endian; /* new endianness for encapsulation */
4938 guint32 seqlen; /* sequence length */
4940 /* get sequence length, new endianness and boundary for encapsulation */
4941 seqlen = get_CDR_encap_info(tvb, tree, offset,
4942 stream_is_big_endian, boundary,
4943 &new_stream_is_big_endian, &new_boundary);
4945 /* get repository ID */
4946 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4950 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4951 hf_giop_typecode_name);
4953 /* get ??? (noname) TypeCode */
4954 get_CDR_typeCode(tvb,tree,offset,new_stream_is_big_endian,new_boundary,header);
4958 static void dissect_tk_native_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
4959 gboolean stream_is_big_endian, guint32 boundary,
4960 MessageHeader * header) {
4962 guint32 new_boundary; /* new boundary for encapsulation */
4963 gboolean new_stream_is_big_endian; /* new endianness for encapsulation */
4965 guint32 seqlen; /* sequence length */
4967 /* get sequence length, new endianness and boundary for encapsulation */
4968 seqlen = get_CDR_encap_info(tvb, tree, offset,
4969 stream_is_big_endian, boundary,
4970 &new_stream_is_big_endian, &new_boundary);
4972 /* get repository ID */
4973 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4977 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
4978 hf_giop_typecode_name);
4983 static void dissect_tk_abstract_interface_params(tvbuff_t *tvb, proto_tree *tree, gint *offset,
4984 gboolean stream_is_big_endian, guint32 boundary,
4985 MessageHeader * header) {
4987 guint32 new_boundary; /* new boundary for encapsulation */
4988 gboolean new_stream_is_big_endian; /* new endianness for encapsulation */
4990 guint32 seqlen; /* sequence length */
4992 /* get sequence length, new endianness and boundary for encapsulation */
4993 seqlen = get_CDR_encap_info(tvb, tree, offset,
4994 stream_is_big_endian, boundary,
4995 &new_stream_is_big_endian, &new_boundary);
4997 /* get repository ID */
4998 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
5002 dissect_typecode_string_param(tvb, tree, offset, new_stream_is_big_endian, new_boundary,
5003 hf_giop_typecode_name);
5007 /* Typecode parameter lists are encoded as encapsulations and
5008 * this function gets the encapsulation information; see
5009 * CORBA spec chapter 15
5012 * Renamed to get_CDR_encap_info() for any encapsulation
5013 * we come across, useful helper function
5015 * Also, should return immediately if seqlen == 0.
5016 * ie: Forget about trying to grab endianess for
5017 * zero length sequence.
5019 * Caller must always check seqlen == 0, and not assume its value
5022 * Note: there seemed to be considerable confusion in corba
5023 * circles as to the correct interpretation of encapsulations,
5024 * and zero length sequences etc, but this is our best bet at the
5031 guint32 get_CDR_encap_info(tvbuff_t *tvb, proto_tree *tree, gint *offset,
5032 gboolean old_stream_is_big_endian, guint32 old_boundary,
5033 gboolean *new_stream_is_big_endian_ptr, guint32 *new_boundary_ptr ) {
5035 guint32 seqlen; /* sequence length */
5036 guint8 giop_endianess;
5038 /* Get sequence length of parameter list */
5039 seqlen = get_CDR_ulong(tvb,offset,old_stream_is_big_endian,old_boundary);
5041 proto_tree_add_uint(tree,hf_giop_sequence_length,tvb,
5042 *offset-sizeof(seqlen),4,seqlen);
5048 * seqlen == 0, implies no endianess and no data
5049 * so just return. Populate new_boundary_ptr and
5050 * new_stream_is_big_endian_ptr with current (old)
5051 * values, just to keep everyone happy. -- FS
5057 *new_boundary_ptr = old_boundary;
5058 *new_stream_is_big_endian_ptr = old_stream_is_big_endian;
5064 /* Start of encapsulation of parameter list */
5065 *new_boundary_ptr = *offset; /* remember */
5066 giop_endianess = get_CDR_octet(tvb,offset);
5068 *new_stream_is_big_endian_ptr = ! giop_endianess;
5071 * Glib: typedef gint gboolean;
5072 * ie: It is not a guint8, so cannot use sizeof to correctly
5078 proto_tree_add_uint(tree,hf_giop_endianess,tvb,
5079 *offset-1,1,giop_endianess);
5089 * gets a TypeCode complex string parameter and
5090 * displays it in the relevant tree.
5093 static void dissect_typecode_string_param(tvbuff_t *tvb, proto_tree *tree, gint *offset,
5094 gboolean new_stream_is_big_endian, guint32 new_boundary, int hf_id ) {
5096 guint32 u_octet4; /* unsigned int32 */
5097 gchar *buf = NULL; /* ptr to string buffer */
5100 u_octet4 = get_CDR_string(tvb,&buf,offset,new_stream_is_big_endian,new_boundary);
5103 proto_tree_add_uint(tree,hf_giop_string_length,tvb,
5104 *offset-u_octet4-sizeof(u_octet4),4,u_octet4);
5106 proto_tree_add_string(tree,hf_id,tvb,*offset-u_octet4,u_octet4,buf);
5110 g_free(buf); /* dont forget */
5115 * For a given data type, given by a TypeCode gets the associated data
5116 * and displays it in the relevant tree.
5119 static void dissect_data_for_typecode(tvbuff_t *tvb, proto_tree *tree, gint *offset,
5120 gboolean stream_is_big_endian, guint32 boundary,
5121 MessageHeader * header, guint32 data_type ) {
5123 gboolean my_boolean; /* boolean */
5125 gint8 s_octet1; /* signed int8 */
5126 guint8 u_octet1; /* unsigned int8 */
5128 gint16 s_octet2; /* signed int16 */
5129 guint16 u_octet2; /* unsigned int16 */
5131 gint32 s_octet4; /* signed int32 */
5132 guint32 u_octet4; /* unsigned int32 */
5134 gdouble my_double; /* double */
5135 gfloat my_float; /* float */
5137 gchar *buf = NULL; /* ptr to string buffer */
5139 /* Grab the data according to data type */
5141 switch (data_type) {
5143 /* nothing to decode */
5146 /* nothing to decode */
5149 s_octet2 = get_CDR_short(tvb,offset,stream_is_big_endian,boundary);
5151 proto_tree_add_int(tree,hf_giop_type_short,tvb,
5152 *offset-sizeof(s_octet2),2,s_octet2);
5156 s_octet4 = get_CDR_long(tvb,offset,stream_is_big_endian,boundary);
5158 proto_tree_add_int(tree,hf_giop_type_long,tvb,
5159 *offset-sizeof(s_octet4),4,s_octet4);
5163 u_octet2 = get_CDR_ushort(tvb,offset,stream_is_big_endian,boundary);
5165 proto_tree_add_uint(tree,hf_giop_type_ushort,tvb,
5166 *offset-sizeof(u_octet2),2,u_octet2);
5170 u_octet4 = get_CDR_ulong(tvb,offset,stream_is_big_endian,boundary);
5172 proto_tree_add_uint(tree,hf_giop_type_ulong,tvb,
5173 *offset-sizeof(u_octet4),4,u_octet4);
5177 my_float = get_CDR_float(tvb,offset,stream_is_big_endian,boundary);
5179 proto_tree_add_double(tree,hf_giop_type_float,tvb,
5180 *offset-sizeof(my_float),4,my_float);
5184 my_double = get_CDR_double(tvb,offset,stream_is_big_endian,boundary);
5186 proto_tree_add_double(tree,hf_giop_type_double,tvb,
5187 *offset-sizeof(my_double),8,my_double);
5191 my_boolean = get_CDR_boolean(tvb,offset);
5193 proto_tree_add_boolean(tree,hf_giop_type_boolean,tvb,
5194 *offset-1,1,my_boolean);
5198 u_octet1 = get_CDR_char(tvb,offset);
5200 proto_tree_add_uint(tree,hf_giop_type_char,tvb,
5201 *offset-sizeof(u_octet1),1,u_octet1);
5205 u_octet1 = get_CDR_octet(tvb,offset);
5207 proto_tree_add_uint(tree,hf_giop_type_octet,tvb,
5208 *offset-sizeof(u_octet1),1,u_octet1);
5212 get_CDR_any(tvb,tree,offset,stream_is_big_endian,boundary,header);
5215 get_CDR_typeCode(tvb,tree,offset,stream_is_big_endian,boundary,header);
5226 u_octet4 = get_CDR_enum(tvb,offset,stream_is_big_endian,boundary);
5228 proto_tree_add_uint(tree,hf_giop_type_enum,tvb,
5229 *offset-sizeof(u_octet4),4,u_octet4);
5233 u_octet4 = get_CDR_string(tvb,&buf,offset,stream_is_big_endian,boundary);
5235 proto_tree_add_uint(tree,hf_giop_string_length,tvb,
5236 *offset-u_octet4-sizeof(u_octet4),4,u_octet4);
5238 proto_tree_add_string(tree,hf_giop_type_string,tvb,
5239 *offset-u_octet4,u_octet4,buf);
5243 g_free(buf); /* dont forget */
5260 s_octet1 = get_CDR_wchar(tvb,&buf,offset,header);
5262 if (s_octet1 < 0) { /* no size to add to tree */
5263 proto_tree_add_string(tree,hf_giop_type_string,tvb,
5264 *offset+s_octet1,(-s_octet1),buf);
5266 proto_tree_add_uint(tree,hf_giop_string_length,tvb,
5267 *offset-s_octet1-sizeof(s_octet1),1,s_octet1);
5268 proto_tree_add_string(tree,hf_giop_type_string,tvb,
5269 *offset-s_octet1,s_octet1,buf);
5273 g_free(buf); /* dont forget */
5276 u_octet4 = get_CDR_wstring(tvb,&buf,offset,stream_is_big_endian,boundary,header);
5278 proto_tree_add_uint(tree,hf_giop_string_length,tvb,
5279 *offset-u_octet4-sizeof(u_octet4),4,u_octet4);
5280 proto_tree_add_string(tree,hf_giop_type_string,tvb,
5281 *offset-u_octet4,u_octet4,buf);
5284 g_free(buf); /* dont forget */
5294 case tk_abstract_interface:
5297 g_warning("giop: Unknown typecode data type %u \n", data_type);