2 * Routines for CORBA ZIOP packet disassembly
3 * Significantly based on packet-giop.c
4 * Copyright 2009 Alvaro Vega Garcia <avega at tid dot es>
6 * According with GIOP Compression RFP revised submission
8 * http://www.omg.org/docs/ptc/09-01-03.pdf
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
36 #include <epan/packet.h>
37 #include <epan/conversation.h>
39 #include "packet-ziop.h"
40 #include "packet-giop.h"
41 #include "packet-tcp.h"
44 * Set to 1 for DEBUG output - TODO make this a runtime option
50 * ------------------------------------------------------------------------------------------+
51 * Data/Variables/Structs
52 * ------------------------------------------------------------------------------------------+
55 static int proto_ziop
= -1;
61 static gint hf_ziop_magic
= -1;
62 static gint hf_ziop_giop_version_major
= -1;
63 static gint hf_ziop_giop_version_minor
= -1;
64 static gint hf_ziop_flags
= -1;
65 static gint hf_ziop_message_type
= -1;
66 static gint hf_ziop_message_size
= -1;
67 static gint hf_ziop_compressor_id
= -1;
68 static gint hf_ziop_original_length
= -1;
70 static gint ett_ziop
= -1;
73 static dissector_handle_t data_handle
;
74 static dissector_handle_t ziop_tcp_handle
;
77 static const value_string ziop_compressor_ids
[] = {
92 static const value_string giop_message_types
[] = {
95 { 0x2, "CancelRequest"},
96 { 0x3, "LocateRequest"},
97 { 0x4, "LocateReply"},
98 { 0x5, "CloseConnection"},
99 { 0x6, "MessageError"},
105 static gboolean ziop_desegment
= TRUE
;
108 /* Main entry point */
110 dissect_ziop (tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data _U_
) {
112 guint8 giop_version_major
, giop_version_minor
, message_type
;
114 proto_tree
*ziop_tree
= NULL
;
117 col_set_str (pinfo
->cinfo
, COL_PROTOCOL
, ZIOP_MAGIC
);
119 /* Clear out stuff in the info column */
120 col_clear(pinfo
->cinfo
, COL_INFO
);
122 giop_version_major
= tvb_get_guint8(tvb
, 4);
123 giop_version_minor
= tvb_get_guint8(tvb
, 5);
124 message_type
= tvb_get_guint8(tvb
, 7);
126 if ( (giop_version_major
< 1) ||
127 (giop_version_minor
< 2) ) /* earlier than GIOP 1.2 */
129 col_add_fstr (pinfo
->cinfo
, COL_INFO
, "Version %u.%u",
130 giop_version_major
, giop_version_minor
);
133 ti
= proto_tree_add_item (tree
, proto_ziop
, tvb
, 0, -1, ENC_NA
);
134 ziop_tree
= proto_item_add_subtree (ti
, ett_ziop
);
135 proto_tree_add_text (ziop_tree
, tvb
, 4, 2,
136 "Version %u.%u not supported",
140 call_dissector(data_handle
, tvb
, pinfo
, tree
);
141 return tvb_length(tvb
);
144 col_add_fstr (pinfo
->cinfo
, COL_INFO
, "ZIOP %u.%u %s",
147 val_to_str(message_type
, giop_message_types
,
148 "Unknown message type (0x%02x)")
155 const char *label
= "none";
157 ti
= proto_tree_add_item (tree
, proto_ziop
, tvb
, 0, -1, ENC_NA
);
158 ziop_tree
= proto_item_add_subtree (ti
, ett_ziop
);
160 proto_tree_add_item(ziop_tree
, hf_ziop_magic
, tvb
, offset
, 4, ENC_ASCII
|ENC_NA
);
162 proto_tree_add_item(ziop_tree
, hf_ziop_giop_version_major
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
164 proto_tree_add_item(ziop_tree
, hf_ziop_giop_version_minor
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
167 flags
= tvb_get_guint8(tvb
, offset
);
168 byte_order
= (flags
& 0x01) ? ENC_LITTLE_ENDIAN
: ENC_BIG_ENDIAN
;
171 label
= "little-endian";
173 proto_tree_add_uint_format_value(ziop_tree
, hf_ziop_flags
, tvb
, offset
, 1,
174 flags
, "0x%02x (%s)", flags
, label
);
177 proto_tree_add_item(ziop_tree
, hf_ziop_message_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
180 proto_tree_add_item(ziop_tree
, hf_ziop_message_size
, tvb
, offset
, 4, byte_order
);
182 proto_tree_add_item(ziop_tree
, hf_ziop_compressor_id
, tvb
, offset
, 2, byte_order
);
184 proto_tree_add_item(ziop_tree
, hf_ziop_original_length
, tvb
, offset
, 4, byte_order
);
187 return tvb_length(tvb
);
191 get_ziop_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
)
195 gboolean stream_is_big_endian
;
197 if ( tvb_memeql(tvb
, 0, ZIOP_MAGIC
, 4) != 0)
200 flags
= tvb_get_guint8(tvb
, offset
+ 6);
202 stream_is_big_endian
= ((flags
& 0x1) == 0);
204 if (stream_is_big_endian
)
205 message_size
= tvb_get_ntohl(tvb
, offset
+ 8);
207 message_size
= tvb_get_letohl(tvb
, offset
+ 8);
209 return message_size
+ ZIOP_HEADER_SIZE
;
213 dissect_ziop_tcp (tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data
) {
215 if ( tvb_memeql(tvb
, 0, ZIOP_MAGIC
,4) != 0) {
217 if (tvb_get_ntohl(tvb
, 0) == GIOP_MAGIC_NUMBER
) {
218 dissect_giop(tvb
, pinfo
, tree
);
219 return tvb_length(tvb
);
224 tcp_dissect_pdus(tvb
, pinfo
, tree
, ziop_desegment
, ZIOP_HEADER_SIZE
,
225 get_ziop_pdu_len
, dissect_ziop
, data
);
226 return tvb_length(tvb
);
231 dissect_ziop_heur (tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data
) {
235 conversation_t
*conversation
;
236 /* check magic number and version */
239 tot_len
= tvb_length(tvb
);
242 if (tot_len
< ZIOP_HEADER_SIZE
) /* tot_len < 12 */
244 /* Not enough data captured to hold the ZIOP header; don't try
245 to interpret it as GIOP. */
248 if ( tvb_memeql(tvb
, 0, ZIOP_MAGIC
, 4) != 0) {
252 if ( pinfo
->ptype
== PT_TCP
)
255 * Make the ZIOP dissector the dissector for this conversation.
257 * If this isn't the first time this packet has been processed,
258 * we've already done this work, so we don't need to do it
261 if (!pinfo
->fd
->flags
.visited
)
263 conversation
= find_or_create_conversation(pinfo
);
266 conversation_set_dissector(conversation
, ziop_tcp_handle
);
268 dissect_ziop_tcp (tvb
, pinfo
, tree
, data
);
272 dissect_ziop (tvb
, pinfo
, tree
, data
);
278 void proto_register_ziop (void) {
281 /* A header field is something you can search/filter on.
283 * We create a structure to register our fields. It consists of an
284 * array of hf_register_info structures, each of which are of the format
285 * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
287 static hf_register_info hf
[] = {
289 { "Header magic", "ziop.magic", FT_STRING
, BASE_NONE
, NULL
, 0x0,
290 "ZIOPHeader magic", HFILL
}},
291 { &hf_ziop_giop_version_major
,
292 { "Header major version", "ziop.giop_version_major", FT_UINT8
, BASE_OCT
, NULL
, 0x0,
293 "ZIOPHeader giop_major_version", HFILL
}},
294 { &hf_ziop_giop_version_minor
,
295 { "Header minor version", "ziop.giop_version_minor", FT_UINT8
, BASE_OCT
, NULL
, 0x0,
296 "ZIOPHeader giop_minor_version", HFILL
}},
298 { "Header flags", "ziop.flags", FT_UINT8
, BASE_OCT
, NULL
, 0x0,
299 "ZIOPHeader flags", HFILL
}},
300 { &hf_ziop_message_type
,
301 { "Header type", "ziop.message_type", FT_UINT8
, BASE_OCT
, VALS(giop_message_types
), 0x0,
302 "ZIOPHeader message_type", HFILL
}},
303 { &hf_ziop_message_size
,
304 { "Header size", "ziop.message_size", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
305 "ZIOPHeader message_size", HFILL
}},
306 { &hf_ziop_compressor_id
,
307 { "Header compressor id", "ziop.compressor_id", FT_UINT16
, BASE_DEC
, VALS(ziop_compressor_ids
), 0x0,
308 "ZIOPHeader compressor_id", HFILL
}},
309 { &hf_ziop_original_length
,
310 { "Header original length", "ziop.original_length", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
311 "ZIOP original_length", HFILL
}},
315 static gint
*ett
[] = {
319 proto_ziop
= proto_register_protocol("Zipped Inter-ORB Protocol", "ZIOP",
321 proto_register_field_array (proto_ziop
, hf
, array_length (hf
));
322 proto_register_subtree_array (ett
, array_length (ett
));
324 new_register_dissector("ziop", dissect_ziop
, proto_ziop
);
329 void proto_reg_handoff_ziop (void) {
331 ziop_tcp_handle
= new_create_dissector_handle(dissect_ziop_tcp
, proto_ziop
);
332 dissector_add_handle("udp.port", ziop_tcp_handle
); /* For 'Decode As' */
334 heur_dissector_add("tcp", dissect_ziop_heur
, proto_ziop
);
336 data_handle
= find_dissector("data");
340 * Editor modelines - http://www.wireshark.org/tools/modelines.html
345 * indent-tabs-mode: nil
348 * vi: set shiftwidth=2 tabstop=8 expandtab:
349 * :indentSize=2:tabSize=8:noTabs=true: