MSWSP: add two more Property Sets
[wireshark-wip.git] / epan / dissectors / packet-rmi.c
blob2569bcbfc2c24f4fb66a70b6d49c82d1f2cd7a48
1 /* packet-rmi.c
2 * Routines for java rmiregistry dissection
3 * Copyright 2002, Michael Stiller <ms@2scale.net>
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "config.h"
28 #include <string.h>
30 #include <glib.h>
32 #include <epan/packet.h>
33 #include <epan/strutil.h>
35 #include "packet-rmi.h"
37 static void
38 dissect_ser(tvbuff_t *tvb, proto_tree *tree);
40 static rmi_type
41 get_rmi_type(tvbuff_t *tvb, gint offset, int datalen);
43 /* Initialize the protocol and registered fields */
44 static int proto_rmi = -1;
45 static int proto_ser = -1;
46 static int hf_rmi_magic = -1;
47 static int hf_rmi_version = -1;
48 static int hf_rmi_protocol = -1;
49 static int hf_rmi_inputmessage = -1;
50 static int hf_rmi_outputmessage = -1;
51 static int hf_rmi_epid_length = -1;
52 static int hf_rmi_epid_hostname = -1;
53 static int hf_rmi_epid_port = -1;
55 static int hf_ser_magic = -1;
56 static int hf_ser_version = -1;
58 /* Initialize the subtree pointers */
59 static gint ett_rmi = -1;
60 static gint ett_rmi_magic = -1;
61 static gint ett_rmi_version = -1;
62 static gint ett_rmi_inputmessage = -1;
63 static gint ett_rmi_outputmessage = -1;
64 static gint ett_rmi_epid_length = -1;
65 static gint ett_rmi_epid_hostname = -1;
66 static gint ett_rmi_epid_port = -1;
68 static gint ett_ser = -1;
71 * See
73 * http://java.sun.com/products/jdk/1.2/docs/guide/rmi/spec/rmi-protocol.doc1.html
75 * for RMI, and
77 * http://java.sun.com/products/jdk/1.2/docs/guide/serialization/spec/protocol.doc.html
79 * for the serialization protocol.
82 #define TCP_PORT_RMI 1099
84 static const value_string rmi_protocol_str[] = {
85 {RMI_OUTPUTSTREAM_PROTOCOL_STREAM, "StreamProtocol"},
86 {RMI_OUTPUTSTREAM_PROTOCOL_SINGLEOP, "SingleOpProtocol"},
87 {RMI_OUTPUTSTREAM_PROTOCOL_MULTIPLEX, "MultiPlexProtocol"},
88 {0, NULL}
91 static const value_string rmi_output_message_str[] = {
92 {RMI_OUTPUTSTREAM_MESSAGE_CALL, "Call"},
93 {RMI_OUTPUTSTREAM_MESSAGE_PING, "Ping"},
94 {RMI_OUTPUTSTREAM_MESSAGE_DGCACK, "DgcAck"},
95 {0, NULL}
98 static const value_string rmi_input_message_str[] = {
99 {RMI_INPUTSTREAM_MESSAGE_ACK, "ProtocolAck"},
100 {RMI_INPUTSTREAM_MESSAGE_NOTSUPPORTED, "ProtocolNotSupported"},
101 {RMI_INPUTSTREAM_MESSAGE_RETURNDATA, "ReturnData"},
102 {RMI_INPUTSTREAM_MESSAGE_PINGACK, "PingAck"},
103 {0, NULL}
106 static void
107 dissect_rmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
109 proto_item *ti;
110 proto_tree *rmi_tree;
112 tvbuff_t *next_tvb;
114 gint offset;
115 gint next_offset;
116 int datalen;
118 guint16 version, len, port;
119 guint8 message, proto;
121 rmi_type rmitype;
123 const char *epid_hostname;
124 guint epid_len;
126 offset = 0;
128 /* Make entries in Protocol column and Info column on summary display */
129 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RMI");
131 datalen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
133 rmitype = get_rmi_type(tvb, offset, datalen);
135 switch(rmitype) {
136 case RMI_OUTPUTSTREAM:
137 version = tvb_get_ntohs(tvb,4);
138 col_add_fstr(pinfo->cinfo, COL_INFO,
139 "JRMI, Version: %d, ", version);
141 proto = tvb_get_guint8(tvb, 6);
142 col_append_str(pinfo->cinfo, COL_INFO,
143 val_to_str_const(proto, rmi_protocol_str,
144 "Unknown protocol"));
145 break;
146 case RMI_OUTPUTMESSAGE:
147 message = tvb_get_guint8(tvb,0);
148 col_set_str(pinfo->cinfo, COL_INFO,
149 "JRMI, ");
150 col_append_str(pinfo->cinfo, COL_INFO,
151 val_to_str_const(message, rmi_output_message_str,
152 "Unknown message"));
153 break;
154 case RMI_INPUTSTREAM:
155 message = tvb_get_guint8(tvb,0);
156 col_set_str(pinfo->cinfo, COL_INFO,
157 "JRMI, ");
158 col_append_str(pinfo->cinfo, COL_INFO,
159 val_to_str_const(message, rmi_input_message_str,
160 "Unknown message"));
161 break;
162 case SERIALIZATION_DATA:
163 version = tvb_get_ntohs(tvb,2);
164 col_add_fstr(pinfo->cinfo, COL_INFO,
165 "Serialization data, Version: %d", version);
166 break;
167 default:
168 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
169 break;
172 if (tree) {
173 ti = proto_tree_add_item(tree, proto_rmi, tvb, 0, -1, ENC_NA);
174 rmi_tree = proto_item_add_subtree(ti, ett_rmi);
175 switch(rmitype) {
176 case RMI_OUTPUTSTREAM:
177 /* XXX - uint, or string? */
178 proto_tree_add_uint(rmi_tree, hf_rmi_magic,
179 tvb, offset, 4, tvb_get_ntohl(tvb,0));
180 proto_tree_add_item(rmi_tree, hf_rmi_version,
181 tvb, offset + 4, 2, ENC_BIG_ENDIAN);
182 proto_tree_add_item(rmi_tree, hf_rmi_protocol,
183 tvb, offset + 6, 1, ENC_BIG_ENDIAN);
184 break;
185 case RMI_INPUTSTREAM:
186 message = tvb_get_guint8(tvb, 0);
187 proto_tree_add_uint(rmi_tree, hf_rmi_inputmessage,
188 tvb, offset, 1, message);
189 if(message == RMI_INPUTSTREAM_MESSAGE_ACK) {
190 proto_tree_add_text(rmi_tree, tvb, offset + 1, -1,
191 "EndPointIdentifier");
192 /* MESSAGE_ACK should include EndpointIdentifier */
193 len = tvb_get_ntohs(tvb, 1);
194 proto_tree_add_uint(rmi_tree, hf_rmi_epid_length,
195 tvb, offset + 1, 2, len);
196 epid_len = len < ITEM_LABEL_LENGTH ? len : ITEM_LABEL_LENGTH;
197 if (epid_len > 0) {
198 epid_hostname = tvb_format_text(tvb, offset + 3, epid_len);
199 } else {
200 epid_hostname = "[Empty]";
202 proto_tree_add_string(rmi_tree, hf_rmi_epid_hostname,
203 tvb, offset + 3, len, epid_hostname);
205 port = tvb_get_ntohs(tvb, offset + len + 5);
206 proto_tree_add_uint(rmi_tree, hf_rmi_epid_port,
207 tvb, offset + len + 5, 2, port);
209 if(message == RMI_INPUTSTREAM_MESSAGE_RETURNDATA) {
210 proto_tree_add_text(rmi_tree, tvb, offset + 1, -1,
211 "Serialization Data");
212 next_tvb = tvb_new_subset_remaining(tvb, offset + 1);
213 dissect_ser(next_tvb, tree);
215 break;
216 case RMI_OUTPUTMESSAGE:
217 message = tvb_get_guint8(tvb, 0);
218 proto_tree_add_uint(rmi_tree, hf_rmi_outputmessage,
219 tvb, offset, 1, message);
220 if(message == RMI_OUTPUTSTREAM_MESSAGE_CALL) {
221 proto_tree_add_text(rmi_tree, tvb, offset + 1, -1,
222 "Serialization Data");
223 /* XXX */
224 next_tvb = tvb_new_subset_remaining(tvb, offset + 1);
225 dissect_ser(next_tvb, tree);
227 if(message == RMI_OUTPUTSTREAM_MESSAGE_DGCACK) {
228 proto_tree_add_text(rmi_tree, tvb, offset + 1, -1,
229 "UniqueIdentifier");
231 break;
232 case SERIALIZATION_DATA:
233 dissect_ser(tvb, tree);
234 break;
235 default:
236 break;
241 static void
242 dissect_ser(tvbuff_t *tvb, proto_tree *tree)
244 proto_item *ti;
245 proto_tree *ser_tree;
247 gint offset;
249 offset = 0;
251 if(tree) {
252 ti = proto_tree_add_item(tree, proto_ser, tvb, 0, -1, ENC_NA);
253 ser_tree = proto_item_add_subtree(ti, ett_ser);
254 proto_tree_add_item(ser_tree, hf_ser_magic,
255 tvb, offset, 2, ENC_BIG_ENDIAN);
256 proto_tree_add_item(ser_tree, hf_ser_version,
257 tvb, offset + 2, 2, ENC_BIG_ENDIAN);
262 static rmi_type
263 get_rmi_type(tvbuff_t *tvb, gint offset, int datalen)
265 guint16 ser_magic;
266 guchar data[4];
268 tvb_memcpy(tvb, data, offset, (datalen > 4) ? 4 : datalen);
270 if (datalen >= 2) {
271 ser_magic = data[0] << 8 | data[1];
272 if (ser_magic == SER_STREAM_MAGIC) {
273 return SERIALIZATION_DATA;
276 if (datalen >= 4) {
277 if(strncmp(data, RMI_MAGIC, 4) == 0) {
278 return RMI_OUTPUTSTREAM;
281 if (datalen >= 1) {
282 if (data[0] == RMI_INPUTSTREAM_MESSAGE_ACK ||
283 data[0] == RMI_INPUTSTREAM_MESSAGE_NOTSUPPORTED ||
284 data[0] == RMI_INPUTSTREAM_MESSAGE_RETURNDATA ||
285 data[0] == RMI_INPUTSTREAM_MESSAGE_PINGACK) {
286 return RMI_INPUTSTREAM;
289 if (datalen >= 1) {
290 if (data[0] == RMI_OUTPUTSTREAM_MESSAGE_CALL ||
291 data[0] == RMI_OUTPUTSTREAM_MESSAGE_PING ||
292 data[0] == RMI_OUTPUTSTREAM_MESSAGE_DGCACK) {
293 return RMI_OUTPUTMESSAGE;
296 return CONTINUATION;
299 void
300 proto_register_rmi(void)
303 static hf_register_info hf[] = {
304 { &hf_rmi_magic,
305 { "Magic", "rmi.magic",
306 FT_UINT32, BASE_HEX, NULL, 0x0,
307 "RMI Header Magic", HFILL }},
308 { &hf_rmi_version,
309 { "Version", "rmi.version",
310 FT_UINT16, BASE_DEC, NULL, 0x0,
311 "RMI Protocol Version", HFILL }},
312 { &hf_rmi_protocol,
313 { "Protocol","rmi.protocol",
314 FT_UINT8, BASE_HEX, VALS(rmi_protocol_str), 0x0,
315 "RMI Protocol Type", HFILL }},
316 { &hf_rmi_inputmessage,
317 { "Input Stream Message", "rmi.inputstream.message",
318 FT_UINT8, BASE_HEX, VALS(rmi_input_message_str), 0x0,
319 "RMI Inputstream Message Token", HFILL }},
320 { &hf_rmi_outputmessage,
321 { "Output Stream Message", "rmi.outputstream.message",
322 FT_UINT8, BASE_HEX, VALS(rmi_output_message_str), 0x0,
323 "RMI Outputstream Message token", HFILL }},
324 { &hf_rmi_epid_length,
325 { "Length", "rmi.endpoint_id.length",
326 FT_UINT16, BASE_DEC, NULL, 0x0,
327 "RMI Endpointidentifier Length", HFILL }},
328 { &hf_rmi_epid_hostname,
329 { "Hostname", "rmi.endpoint_id.hostname",
330 FT_STRING, BASE_NONE, NULL, 0x0,
331 "RMI Endpointidentifier Hostname", HFILL }},
332 { &hf_rmi_epid_port,
333 { "Port", "rmi.endpoint_id.port",
334 FT_UINT16, BASE_DEC, NULL, 0x0,
335 "RMI Endpointindentifier Port", HFILL }},
337 { &hf_ser_magic,
338 { "Magic", "rmi.ser.magic",
339 FT_UINT16, BASE_HEX, NULL, 0x0,
340 "Java Serialization Magic", HFILL }},
341 { &hf_ser_version,
342 { "Version", "rmi.ser.version",
343 FT_UINT16, BASE_DEC, NULL, 0x0,
344 "Java Serialization Version", HFILL }},
347 static gint *ett[] = {
348 &ett_rmi,
349 &ett_rmi_magic,
350 &ett_rmi_version,
351 &ett_rmi_inputmessage,
352 &ett_rmi_outputmessage,
353 &ett_rmi_epid_length,
354 &ett_rmi_epid_hostname,
355 &ett_rmi_epid_port,
356 &ett_ser,
359 proto_rmi = proto_register_protocol("Java RMI", "RMI", "rmi");
360 proto_ser = proto_register_protocol("Java Serialization", "Serialization",
361 "serialization");
362 proto_register_field_array(proto_rmi, hf, array_length(hf));
363 proto_register_subtree_array(ett, array_length(ett));
367 void
368 proto_reg_handoff_rmi(void)
370 dissector_handle_t rmi_handle;
372 rmi_handle = create_dissector_handle(dissect_rmi, proto_rmi);
373 dissector_add_uint("tcp.port", TCP_PORT_RMI, rmi_handle);