2 * Routines for java rmiregistry dissection
3 * Copyright 2002, Michael Stiller <ms@2scale.net>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include <epan/packet.h>
17 #include "packet-rmi.h"
19 void proto_register_rmi(void);
20 void proto_reg_handoff_rmi(void);
22 static dissector_handle_t rmi_handle
;
25 dissect_ser(tvbuff_t
*tvb
, proto_tree
*tree
);
28 get_rmi_type(tvbuff_t
*tvb
, int offset
, int datalen
);
30 /* Initialize the protocol and registered fields */
33 static int hf_rmi_magic
;
34 static int hf_rmi_version
;
35 static int hf_rmi_protocol
;
36 static int hf_rmi_inputmessage
;
37 static int hf_rmi_outputmessage
;
38 static int hf_rmi_epid_length
;
39 static int hf_rmi_epid_hostname
;
40 static int hf_rmi_epid_port
;
41 static int hf_rmi_serialization_data
;
42 static int hf_rmi_unique_identifier
;
44 static int hf_ser_magic
;
45 static int hf_ser_version
;
47 /* Initialize the subtree pointers */
49 static int ett_rmi_magic
;
50 static int ett_rmi_version
;
51 static int ett_rmi_inputmessage
;
52 static int ett_rmi_outputmessage
;
53 static int ett_rmi_epid_length
;
54 static int ett_rmi_epid_hostname
;
55 static int ett_rmi_epid_port
;
56 static int ett_rmi_endpoint_identifier
;
63 * http://java.sun.com/products/jdk/1.2/docs/guide/rmi/spec/rmi-protocol.doc1.html
67 * http://java.sun.com/products/jdk/1.2/docs/guide/serialization/spec/protocol.doc.html
69 * for the serialization protocol.
72 #define TCP_PORT_RMI 1099
74 static const value_string rmi_protocol_str
[] = {
75 {RMI_OUTPUTSTREAM_PROTOCOL_STREAM
, "StreamProtocol"},
76 {RMI_OUTPUTSTREAM_PROTOCOL_SINGLEOP
, "SingleOpProtocol"},
77 {RMI_OUTPUTSTREAM_PROTOCOL_MULTIPLEX
, "MultiPlexProtocol"},
81 static const value_string rmi_output_message_str
[] = {
82 {RMI_OUTPUTSTREAM_MESSAGE_CALL
, "Call"},
83 {RMI_OUTPUTSTREAM_MESSAGE_PING
, "Ping"},
84 {RMI_OUTPUTSTREAM_MESSAGE_DGCACK
, "DgcAck"},
88 static const value_string rmi_input_message_str
[] = {
89 {RMI_INPUTSTREAM_MESSAGE_ACK
, "ProtocolAck"},
90 {RMI_INPUTSTREAM_MESSAGE_NOTSUPPORTED
, "ProtocolNotSupported"},
91 {RMI_INPUTSTREAM_MESSAGE_RETURNDATA
, "ReturnData"},
92 {RMI_INPUTSTREAM_MESSAGE_PINGACK
, "PingAck"},
97 dissect_rmi(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
100 proto_tree
*rmi_tree
;
108 uint16_t version
, len
, port
;
109 uint8_t message
, proto
;
113 /* Make entries in Protocol column and Info column on summary display */
114 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RMI");
116 datalen
= tvb_find_line_end(tvb
, offset
, -1, &next_offset
, false);
118 rmitype
= get_rmi_type(tvb
, offset
, datalen
);
121 case RMI_OUTPUTSTREAM
:
122 version
= tvb_get_ntohs(tvb
,4);
123 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
124 "JRMI, Version: %d, ", version
);
126 proto
= tvb_get_uint8(tvb
, 6);
127 col_append_str(pinfo
->cinfo
, COL_INFO
,
128 val_to_str_const(proto
, rmi_protocol_str
,
129 "Unknown protocol"));
131 case RMI_OUTPUTMESSAGE
:
132 message
= tvb_get_uint8(tvb
,0);
133 col_set_str(pinfo
->cinfo
, COL_INFO
,
135 col_append_str(pinfo
->cinfo
, COL_INFO
,
136 val_to_str_const(message
, rmi_output_message_str
,
139 case RMI_INPUTSTREAM
:
140 message
= tvb_get_uint8(tvb
,0);
141 col_set_str(pinfo
->cinfo
, COL_INFO
,
143 col_append_str(pinfo
->cinfo
, COL_INFO
,
144 val_to_str_const(message
, rmi_input_message_str
,
147 case SERIALIZATION_DATA
:
148 version
= tvb_get_ntohs(tvb
,2);
149 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
150 "Serialization data, Version: %d", version
);
153 col_set_str(pinfo
->cinfo
, COL_INFO
, "Continuation");
158 ti
= proto_tree_add_item(tree
, proto_rmi
, tvb
, 0, -1, ENC_NA
);
159 rmi_tree
= proto_item_add_subtree(ti
, ett_rmi
);
161 case RMI_OUTPUTSTREAM
:
162 /* XXX - uint, or string? */
163 proto_tree_add_item(rmi_tree
, hf_rmi_magic
,
164 tvb
, offset
, 4, ENC_BIG_ENDIAN
);
165 proto_tree_add_item(rmi_tree
, hf_rmi_version
,
166 tvb
, offset
+ 4, 2, ENC_BIG_ENDIAN
);
167 proto_tree_add_item(rmi_tree
, hf_rmi_protocol
,
168 tvb
, offset
+ 6, 1, ENC_BIG_ENDIAN
);
170 case RMI_INPUTSTREAM
:
171 message
= tvb_get_uint8(tvb
, 0);
172 proto_tree_add_uint(rmi_tree
, hf_rmi_inputmessage
,
173 tvb
, offset
, 1, message
);
174 if(message
== RMI_INPUTSTREAM_MESSAGE_ACK
) {
175 proto_tree
* endpoint_tree
= proto_tree_add_subtree(rmi_tree
, tvb
, offset
+ 1, -1,
176 ett_rmi_endpoint_identifier
, NULL
, "EndPointIdentifier");
177 /* MESSAGE_ACK should include EndpointIdentifier */
178 len
= tvb_get_ntohs(tvb
, 1);
179 proto_tree_add_uint(endpoint_tree
, hf_rmi_epid_length
,
180 tvb
, offset
+ 1, 2, len
);
182 proto_tree_add_item(endpoint_tree
, hf_rmi_epid_hostname
,
183 tvb
, offset
+ 3, len
, ENC_ASCII
);
185 proto_tree_add_string(endpoint_tree
, hf_rmi_epid_hostname
,
186 tvb
, offset
+ 3, len
, "[Empty]");
189 port
= tvb_get_ntohs(tvb
, offset
+ len
+ 5);
190 proto_tree_add_uint(endpoint_tree
, hf_rmi_epid_port
,
191 tvb
, offset
+ len
+ 5, 2, port
);
193 if(message
== RMI_INPUTSTREAM_MESSAGE_RETURNDATA
) {
194 proto_tree_add_bytes_format(rmi_tree
, hf_rmi_serialization_data
, tvb
, offset
+ 1, -1,
195 NULL
, "Serialization Data");
196 next_tvb
= tvb_new_subset_remaining(tvb
, offset
+ 1);
197 dissect_ser(next_tvb
, tree
);
200 case RMI_OUTPUTMESSAGE
:
201 message
= tvb_get_uint8(tvb
, 0);
202 proto_tree_add_uint(rmi_tree
, hf_rmi_outputmessage
,
203 tvb
, offset
, 1, message
);
204 if(message
== RMI_OUTPUTSTREAM_MESSAGE_CALL
) {
205 proto_tree_add_bytes_format(rmi_tree
, hf_rmi_serialization_data
, tvb
, offset
+ 1, -1,
206 NULL
, "Serialization Data");
208 next_tvb
= tvb_new_subset_remaining(tvb
, offset
+ 1);
209 dissect_ser(next_tvb
, tree
);
211 if(message
== RMI_OUTPUTSTREAM_MESSAGE_DGCACK
) {
212 proto_tree_add_item(rmi_tree
, hf_rmi_unique_identifier
, tvb
, offset
+ 1, -1, ENC_NA
);
215 case SERIALIZATION_DATA
:
216 dissect_ser(tvb
, tree
);
222 return tvb_captured_length(tvb
);
226 dissect_ser(tvbuff_t
*tvb
, proto_tree
*tree
)
229 proto_tree
*ser_tree
;
236 ti
= proto_tree_add_item(tree
, proto_ser
, tvb
, 0, -1, ENC_NA
);
237 ser_tree
= proto_item_add_subtree(ti
, ett_ser
);
238 proto_tree_add_item(ser_tree
, hf_ser_magic
,
239 tvb
, offset
, 2, ENC_BIG_ENDIAN
);
240 proto_tree_add_item(ser_tree
, hf_ser_version
,
241 tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
247 get_rmi_type(tvbuff_t
*tvb
, int offset
, int datalen
)
250 unsigned char data
[4];
252 tvb_memcpy(tvb
, data
, offset
, (datalen
> 4) ? 4 : datalen
);
255 ser_magic
= data
[0] << 8 | data
[1];
256 if (ser_magic
== SER_STREAM_MAGIC
) {
257 return SERIALIZATION_DATA
;
261 if(strncmp(data
, RMI_MAGIC
, 4) == 0) {
262 return RMI_OUTPUTSTREAM
;
266 if (data
[0] == RMI_INPUTSTREAM_MESSAGE_ACK
||
267 data
[0] == RMI_INPUTSTREAM_MESSAGE_NOTSUPPORTED
||
268 data
[0] == RMI_INPUTSTREAM_MESSAGE_RETURNDATA
||
269 data
[0] == RMI_INPUTSTREAM_MESSAGE_PINGACK
) {
270 return RMI_INPUTSTREAM
;
274 if (data
[0] == RMI_OUTPUTSTREAM_MESSAGE_CALL
||
275 data
[0] == RMI_OUTPUTSTREAM_MESSAGE_PING
||
276 data
[0] == RMI_OUTPUTSTREAM_MESSAGE_DGCACK
) {
277 return RMI_OUTPUTMESSAGE
;
284 proto_register_rmi(void)
287 static hf_register_info hf
[] = {
289 { "Magic", "rmi.magic",
290 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
291 "RMI Header Magic", HFILL
}},
293 { "Version", "rmi.version",
294 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
295 "RMI Protocol Version", HFILL
}},
297 { "Protocol","rmi.protocol",
298 FT_UINT8
, BASE_HEX
, VALS(rmi_protocol_str
), 0x0,
299 "RMI Protocol Type", HFILL
}},
300 { &hf_rmi_inputmessage
,
301 { "Input Stream Message", "rmi.inputstream.message",
302 FT_UINT8
, BASE_HEX
, VALS(rmi_input_message_str
), 0x0,
303 "RMI Inputstream Message Token", HFILL
}},
304 { &hf_rmi_outputmessage
,
305 { "Output Stream Message", "rmi.outputstream.message",
306 FT_UINT8
, BASE_HEX
, VALS(rmi_output_message_str
), 0x0,
307 "RMI Outputstream Message token", HFILL
}},
308 { &hf_rmi_epid_length
,
309 { "Length", "rmi.endpoint_id.length",
310 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
311 "RMI Endpointidentifier Length", HFILL
}},
312 { &hf_rmi_epid_hostname
,
313 { "Hostname", "rmi.endpoint_id.hostname",
314 FT_STRING
, BASE_NONE
, NULL
, 0x0,
315 "RMI Endpointidentifier Hostname", HFILL
}},
317 { "Port", "rmi.endpoint_id.port",
318 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
319 "RMI Endpointidentifier Port", HFILL
}},
320 { &hf_rmi_serialization_data
,
321 { "Serialization Data", "rmi.serialization_data",
322 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
324 { &hf_rmi_unique_identifier
,
325 { "UniqueIdentifier", "rmi.unique_identifier",
326 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
330 { "Magic", "rmi.ser.magic",
331 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
332 "Java Serialization Magic", HFILL
}},
334 { "Version", "rmi.ser.version",
335 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
336 "Java Serialization Version", HFILL
}},
339 static int *ett
[] = {
343 &ett_rmi_inputmessage
,
344 &ett_rmi_outputmessage
,
345 &ett_rmi_epid_length
,
346 &ett_rmi_epid_hostname
,
349 &ett_rmi_endpoint_identifier
,
352 proto_rmi
= proto_register_protocol("Java RMI", "RMI", "rmi");
353 proto_ser
= proto_register_protocol_in_name_only("Java Serialization", "Serialization",
354 "serialization", proto_rmi
, FT_PROTOCOL
);
355 proto_register_field_array(proto_rmi
, hf
, array_length(hf
));
356 proto_register_subtree_array(ett
, array_length(ett
));
358 rmi_handle
= register_dissector("rmi", dissect_rmi
, proto_rmi
);
362 proto_reg_handoff_rmi(void)
364 dissector_add_uint_with_preference("tcp.port", TCP_PORT_RMI
, rmi_handle
);
368 * Editor modelines - https://www.wireshark.org/tools/modelines.html
373 * indent-tabs-mode: nil
376 * vi: set shiftwidth=4 tabstop=8 expandtab:
377 * :indentSize=4:tabSize=8:noTabs=true: