MSWSP: fix dissect_mswsp_smb()
[wireshark-wip.git] / epan / dissectors / packet-ziop.c
bloba3895d7de0b9bb8796a350ba29e221203b61a518
1 /* packet-ziop.c
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
7 * OMG mars/2008-12-20
8 * http://www.omg.org/docs/ptc/09-01-03.pdf
10 * $Id$
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.
32 #include "config.h"
34 #include <glib.h>
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
47 #define DEBUG 0
50 * ------------------------------------------------------------------------------------------+
51 * Data/Variables/Structs
52 * ------------------------------------------------------------------------------------------+
55 static int proto_ziop = -1;
58 * (sub)Tree declares
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[] = {
78 { 0, "None" },
79 { 1, "GZIP"},
80 { 2, "PKZIP"},
81 { 3, "BZIP2"},
82 { 4, "ZLIB"},
83 { 5, "LZMA"},
84 { 6, "LZOP"},
85 { 7, "RZIP"},
86 { 8, "7X"},
87 { 9, "XAR"},
88 { 0, NULL}
92 static const value_string giop_message_types[] = {
93 { 0x0, "Request" },
94 { 0x1, "Reply"},
95 { 0x2, "CancelRequest"},
96 { 0x3, "LocateRequest"},
97 { 0x4, "LocateReply"},
98 { 0x5, "CloseConnection"},
99 { 0x6, "MessageError"},
100 { 0x7, "Fragment"},
101 { 0, NULL}
105 static gboolean ziop_desegment = TRUE;
108 /* Main entry point */
109 static int
110 dissect_ziop (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data _U_) {
111 guint offset = 0;
112 guint8 giop_version_major, giop_version_minor, message_type;
114 proto_tree *ziop_tree = NULL;
115 proto_item *ti;
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);
131 if (tree)
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",
137 giop_version_major,
138 giop_version_minor);
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",
145 giop_version_major,
146 giop_version_minor,
147 val_to_str(message_type, giop_message_types,
148 "Unknown message type (0x%02x)")
151 if (tree)
153 guint8 flags;
154 guint byte_order;
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);
161 offset += 4;
162 proto_tree_add_item(ziop_tree, hf_ziop_giop_version_major, tvb, offset, 1, ENC_BIG_ENDIAN);
163 offset++;
164 proto_tree_add_item(ziop_tree, hf_ziop_giop_version_minor, tvb, offset, 1, ENC_BIG_ENDIAN);
165 offset++;
167 flags = tvb_get_guint8(tvb, offset);
168 byte_order = (flags & 0x01) ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
170 if (flags & 0x01) {
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);
175 offset++;
177 proto_tree_add_item(ziop_tree, hf_ziop_message_type, tvb, offset, 1, ENC_BIG_ENDIAN);
178 offset++;
180 proto_tree_add_item(ziop_tree, hf_ziop_message_size, tvb, offset, 4, byte_order);
181 offset += 4;
182 proto_tree_add_item(ziop_tree, hf_ziop_compressor_id, tvb, offset, 2, byte_order);
183 offset += 4;
184 proto_tree_add_item(ziop_tree, hf_ziop_original_length, tvb, offset, 4, byte_order);
187 return tvb_length(tvb);
190 static guint
191 get_ziop_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
193 guint8 flags;
194 guint message_size;
195 gboolean stream_is_big_endian;
197 if ( tvb_memeql(tvb, 0, ZIOP_MAGIC, 4) != 0)
198 return 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);
206 else
207 message_size = tvb_get_letohl(tvb, offset + 8);
209 return message_size + ZIOP_HEADER_SIZE;
212 static int
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);
221 return 0;
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);
230 gboolean
231 dissect_ziop_heur (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data) {
233 guint tot_len;
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. */
246 return FALSE;
248 if ( tvb_memeql(tvb, 0, ZIOP_MAGIC, 4) != 0) {
249 return FALSE;
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
259 * again.
261 if (!pinfo->fd->flags.visited)
263 conversation = find_or_create_conversation(pinfo);
265 /* Set dissector */
266 conversation_set_dissector(conversation, ziop_tcp_handle);
268 dissect_ziop_tcp (tvb, pinfo, tree, data);
270 else
272 dissect_ziop (tvb, pinfo, tree, data);
274 return TRUE;
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[] = {
288 { &hf_ziop_magic,
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 }},
297 { &hf_ziop_flags,
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[] = {
316 &ett_ziop,
319 proto_ziop = proto_register_protocol("Zipped Inter-ORB Protocol", "ZIOP",
320 "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
342 * Local variables:
343 * c-basic-offset: 2
344 * tab-width: 8
345 * indent-tabs-mode: nil
346 * End:
348 * vi: set shiftwidth=2 tabstop=8 expandtab:
349 * :indentSize=2:tabSize=8:noTabs=true: