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 * https://www.omg.org/spec/ZIOP/1.0/Beta1/PDF
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * SPDX-License-Identifier: GPL-2.0-or-later
20 #include <epan/packet.h>
21 #include <epan/expert.h>
23 #include "packet-ziop.h"
24 #include "packet-giop.h"
25 #include "packet-tcp.h"
28 * Set to 1 for DEBUG output - TODO make this a runtime option
33 void proto_reg_handoff_ziop(void);
34 void proto_register_ziop(void);
37 * ------------------------------------------------------------------------------------------+
38 * Data/Variables/Structs
39 * ------------------------------------------------------------------------------------------+
42 static int proto_ziop
;
48 static int hf_ziop_magic
;
49 static int hf_ziop_giop_version_major
;
50 static int hf_ziop_giop_version_minor
;
51 static int hf_ziop_flags
;
52 static int hf_ziop_message_type
;
53 static int hf_ziop_message_size
;
54 static int hf_ziop_compressor_id
;
55 static int hf_ziop_original_length
;
59 static expert_field ei_ziop_version
;
61 static dissector_handle_t ziop_tcp_handle
;
64 static const value_string ziop_compressor_ids
[] = {
79 static const value_string giop_message_types
[] = {
82 { 0x2, "CancelRequest"},
83 { 0x3, "LocateRequest"},
84 { 0x4, "LocateReply"},
85 { 0x5, "CloseConnection"},
86 { 0x6, "MessageError"},
92 static bool ziop_desegment
= true;
95 /* Main entry point */
97 dissect_ziop (tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data _U_
) {
99 uint8_t giop_version_major
, giop_version_minor
, message_type
;
101 proto_tree
*ziop_tree
= NULL
;
105 const char *label
= "none";
107 if (tvb_reported_length(tvb
) < 7)
110 col_set_str (pinfo
->cinfo
, COL_PROTOCOL
, ZIOP_MAGIC
);
112 /* Clear out stuff in the info column */
113 col_clear(pinfo
->cinfo
, COL_INFO
);
115 ti
= proto_tree_add_item (tree
, proto_ziop
, tvb
, 0, -1, ENC_NA
);
116 ziop_tree
= proto_item_add_subtree (ti
, ett_ziop
);
118 proto_tree_add_item(ziop_tree
, hf_ziop_magic
, tvb
, offset
, 4, ENC_ASCII
);
120 proto_tree_add_item(ziop_tree
, hf_ziop_giop_version_major
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
121 giop_version_major
= tvb_get_uint8(tvb
, offset
);
123 proto_tree_add_item(ziop_tree
, hf_ziop_giop_version_minor
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
124 giop_version_minor
= tvb_get_uint8(tvb
, offset
);
127 if ( (giop_version_major
< 1) ||
128 (giop_version_minor
< 2) ) /* earlier than GIOP 1.2 */
130 col_add_fstr (pinfo
->cinfo
, COL_INFO
, "Version %u.%u",
131 giop_version_major
, giop_version_minor
);
133 expert_add_info_format(pinfo
, ti
, &ei_ziop_version
,
134 "Version %u.%u not supported",
138 call_data_dissector(tvb
, pinfo
, tree
);
139 return tvb_reported_length(tvb
);
142 flags
= tvb_get_uint8(tvb
, offset
);
143 byte_order
= (flags
& 0x01) ? ENC_LITTLE_ENDIAN
: ENC_BIG_ENDIAN
;
146 label
= "little-endian";
148 proto_tree_add_uint_format_value(ziop_tree
, hf_ziop_flags
, tvb
, offset
, 1,
149 flags
, "0x%02x (%s)", flags
, label
);
152 proto_tree_add_item(ziop_tree
, hf_ziop_message_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
153 message_type
= tvb_get_uint8(tvb
, offset
);
156 col_add_fstr (pinfo
->cinfo
, COL_INFO
, "ZIOP %u.%u %s",
159 val_to_str(message_type
, giop_message_types
,
160 "Unknown message type (0x%02x)")
163 proto_tree_add_item(ziop_tree
, hf_ziop_message_size
, tvb
, offset
, 4, byte_order
);
165 proto_tree_add_item(ziop_tree
, hf_ziop_compressor_id
, tvb
, offset
, 2, byte_order
);
167 proto_tree_add_item(ziop_tree
, hf_ziop_original_length
, tvb
, offset
, 4, byte_order
);
169 return tvb_reported_length(tvb
);
173 get_ziop_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
, void *data _U_
)
176 unsigned message_size
;
177 bool stream_is_big_endian
;
179 if ( tvb_memeql(tvb
, 0, (const uint8_t *)ZIOP_MAGIC
, 4) != 0)
182 flags
= tvb_get_uint8(tvb
, offset
+ 6);
184 stream_is_big_endian
= ((flags
& 0x1) == 0);
186 if (stream_is_big_endian
)
187 message_size
= tvb_get_ntohl(tvb
, offset
+ 8);
189 message_size
= tvb_get_letohl(tvb
, offset
+ 8);
191 return message_size
+ ZIOP_HEADER_SIZE
;
195 dissect_ziop_tcp (tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data
)
197 if ( tvb_memeql(tvb
, 0, (const uint8_t *)ZIOP_MAGIC
, 4) != 0)
199 if (tvb_get_ntohl(tvb
, 0) == GIOP_MAGIC_NUMBER
)
201 dissect_giop(tvb
, pinfo
, tree
);
202 return tvb_captured_length(tvb
);
207 tcp_dissect_pdus(tvb
, pinfo
, tree
, ziop_desegment
, ZIOP_HEADER_SIZE
,
208 get_ziop_pdu_len
, dissect_ziop
, data
);
209 return tvb_captured_length(tvb
);
214 dissect_ziop_heur (tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data
)
218 conversation_t
*conversation
;
219 /* check magic number and version */
221 tot_len
= tvb_captured_length(tvb
);
223 if (tot_len
< ZIOP_HEADER_SIZE
) /* tot_len < 12 */
225 /* Not enough data captured to hold the ZIOP header; don't try
226 to interpret it as GIOP. */
229 if ( tvb_memeql(tvb
, 0, (const uint8_t *)ZIOP_MAGIC
, 4) != 0)
234 if ( pinfo
->ptype
== PT_TCP
)
237 * Make the ZIOP dissector the dissector for this conversation.
239 * If this isn't the first time this packet has been processed,
240 * we've already done this work, so we don't need to do it
243 if (!pinfo
->fd
->visited
)
245 conversation
= find_or_create_conversation(pinfo
);
248 conversation_set_dissector(conversation
, ziop_tcp_handle
);
250 dissect_ziop_tcp (tvb
, pinfo
, tree
, data
);
254 dissect_ziop (tvb
, pinfo
, tree
, data
);
260 proto_register_ziop (void)
262 /* A header field is something you can search/filter on.
264 * We create a structure to register our fields. It consists of an
265 * array of hf_register_info structures, each of which are of the format
266 * {&(field id), {name, abbrev, type, display, strings, bitmask, blurb, HFILL}}.
268 static hf_register_info hf
[] = {
270 { "Header magic", "ziop.magic", FT_STRING
, BASE_NONE
, NULL
, 0x0,
271 "ZIOPHeader magic", HFILL
}},
272 { &hf_ziop_giop_version_major
,
273 { "Header major version", "ziop.giop_version_major", FT_UINT8
, BASE_OCT
, NULL
, 0x0,
274 "ZIOPHeader giop_major_version", HFILL
}},
275 { &hf_ziop_giop_version_minor
,
276 { "Header minor version", "ziop.giop_version_minor", FT_UINT8
, BASE_OCT
, NULL
, 0x0,
277 "ZIOPHeader giop_minor_version", HFILL
}},
279 { "Header flags", "ziop.flags", FT_UINT8
, BASE_OCT
, NULL
, 0x0,
280 "ZIOPHeader flags", HFILL
}},
281 { &hf_ziop_message_type
,
282 { "Header type", "ziop.message_type", FT_UINT8
, BASE_OCT
, VALS(giop_message_types
), 0x0,
283 "ZIOPHeader message_type", HFILL
}},
284 { &hf_ziop_message_size
,
285 { "Header size", "ziop.message_size", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
286 "ZIOPHeader message_size", HFILL
}},
287 { &hf_ziop_compressor_id
,
288 { "Header compressor id", "ziop.compressor_id", FT_UINT16
, BASE_DEC
, VALS(ziop_compressor_ids
), 0x0,
289 "ZIOPHeader compressor_id", HFILL
}},
290 { &hf_ziop_original_length
,
291 { "Header original length", "ziop.original_length", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
292 "ZIOP original_length", HFILL
}}
295 static int *ett
[] = {
299 static ei_register_info ei
[] = {
300 { &ei_ziop_version
, { "ziop.version_not_supported", PI_PROTOCOL
, PI_WARN
, "Version not supported", EXPFILL
}},
303 expert_module_t
* expert_ziop
;
305 proto_ziop
= proto_register_protocol("Zipped Inter-ORB Protocol", "ZIOP", "ziop");
306 proto_register_field_array (proto_ziop
, hf
, array_length (hf
));
307 proto_register_subtree_array (ett
, array_length (ett
));
308 expert_ziop
= expert_register_protocol(proto_ziop
);
309 expert_register_field_array(expert_ziop
, ei
, array_length(ei
));
311 register_dissector("ziop", dissect_ziop
, proto_ziop
);
312 ziop_tcp_handle
= register_dissector("ziop.tcp", dissect_ziop_tcp
, proto_ziop
);
317 proto_reg_handoff_ziop (void)
319 dissector_add_for_decode_as_with_preference("udp.port", ziop_tcp_handle
);
321 heur_dissector_add("tcp", dissect_ziop_heur
, "ZIOP over TCP", "ziop_tcp", proto_ziop
, HEURISTIC_ENABLE
);
325 * Editor modelines - https://www.wireshark.org/tools/modelines.html
330 * indent-tabs-mode: nil
333 * vi: set shiftwidth=2 tabstop=8 expandtab:
334 * :indentSize=2:tabSize=8:noTabs=true: