* Routines for java rmiregistry dissection
* Copyright 2002, Michael Stiller <ms@2scale.net>
*
- * $Id: packet-rmi.c,v 1.2 2002/07/17 00:42:42 guy Exp $
+ * $Id: packet-rmi.c,v 1.9 2003/05/26 21:44:28 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-
#include <glib.h>
#include <epan/packet.h>
#include "packet-rmi.h"
+static void
+dissect_ser(tvbuff_t *tvb, proto_tree *tree);
+
+static rmi_type
+get_rmi_type(const guchar *data, int datalen);
+
/* Initialize the protocol and registered fields */
static int proto_rmi = -1;
static int proto_ser = -1;
static gint ett_rmi = -1;
static gint ett_rmi_magic = -1;
static gint ett_rmi_version = -1;
-static gint ett_rmi_protocol = -1;
static gint ett_rmi_inputmessage = -1;
static gint ett_rmi_outputmessage = -1;
static gint ett_rmi_epid_length = -1;
static gint ett_rmi_epid_port = -1;
static gint ett_ser = -1;
-static gint ett_ser_magic = -1;
-static gint ett_ser_version = -1;
+
+/*
+ * See
+ *
+ * http://java.sun.com/products/jdk/1.2/docs/guide/rmi/spec/rmi-protocol.doc1.html
+ *
+ * for RMI, and
+ *
+ * http://java.sun.com/products/jdk/1.2/docs/guide/serialization/spec/protocol.doc.html
+ *
+ * for the serialization protocol.
+ */
#define TCP_PORT_RMI 1099
+static const value_string rmi_protocol_str[] = {
+ {RMI_OUTPUTSTREAM_PROTOCOL_STREAM, "StreamProtocol"},
+ {RMI_OUTPUTSTREAM_PROTOCOL_SINGLEOP, "SingleOpProtocol"},
+ {RMI_OUTPUTSTREAM_PROTOCOL_MULTIPLEX, "MultiPlexProtocol"},
+ {0, NULL}
+};
+
+static const value_string rmi_output_message_str[] = {
+ {RMI_OUTPUTSTREAM_MESSAGE_CALL, "Call"},
+ {RMI_OUTPUTSTREAM_MESSAGE_PING, "Ping"},
+ {RMI_OUTPUTSTREAM_MESSAGE_DGCACK, "DgcAck"},
+ {0, NULL}
+};
+
+static const value_string rmi_input_message_str[] = {
+ {RMI_INPUTSTREAM_MESSAGE_ACK, "ProtocolAck"},
+ {RMI_INPUTSTREAM_MESSAGE_NOTSUPPORTED, "ProtocolNotSupported"},
+ {RMI_INPUTSTREAM_MESSAGE_RETURNDATA, "ReturnData"},
+ {RMI_INPUTSTREAM_MESSAGE_PINGACK, "PingAck"},
+ {0, NULL}
+};
+
static void
dissect_rmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
gint offset;
gint next_offset;
int datalen;
- const u_char *data;
+ const guchar *data;
guint16 version, len, port;
guint8 message, proto;
rmitype = 0;
/* Make entries in Protocol column and Info column on summary display */
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "RMI");
- datalen = tvb_find_line_end(tvb, offset, -1, &next_offset);
+ datalen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
data = tvb_get_ptr(tvb, offset, datalen);
-
+
rmitype = get_rmi_type(data, datalen);
-
+
if (check_col(pinfo->cinfo, COL_INFO)) {
switch(rmitype) {
case RMI_OUTPUTSTREAM:
"JRMI, Version: %d, ", version);
proto = tvb_get_guint8(tvb, 6);
- col_append_str(pinfo->cinfo, COL_INFO,
+ col_append_str(pinfo->cinfo, COL_INFO,
val_to_str(proto, rmi_protocol_str,
"Unknown protocol"));
break;
rmi_tree = proto_item_add_subtree(ti, ett_rmi);
switch(rmitype) {
case RMI_OUTPUTSTREAM:
+ /* XXX - uint, or string? */
proto_tree_add_uint(rmi_tree, hf_rmi_magic,
tvb, offset, 4, tvb_get_ntohl(tvb,0));
- proto_tree_add_uint(rmi_tree, hf_rmi_version,
- tvb, offset + 4, 2, tvb_get_ntohs(tvb,4));
- proto_tree_add_string(rmi_tree, hf_rmi_protocol,
- tvb, offset + 6, 1,
- val_to_str(tvb_get_guint8(tvb, 6),
- rmi_protocol_str,
- "Unknown Protocol"));
+ proto_tree_add_item(rmi_tree, hf_rmi_version,
+ tvb, offset + 4, 2, FALSE);
+ proto_tree_add_item(rmi_tree, hf_rmi_protocol,
+ tvb, offset + 6, 1, FALSE);
break;
case RMI_INPUTSTREAM:
message = tvb_get_guint8(tvb, 0);
- proto_tree_add_string(rmi_tree, hf_rmi_inputmessage,
- tvb, offset, 1,
- val_to_str(message,
- rmi_input_message_str,
- "Unknown Message"));
+ proto_tree_add_uint(rmi_tree, hf_rmi_inputmessage,
+ tvb, offset, 1, message);
if(message == RMI_INPUTSTREAM_MESSAGE_ACK) {
proto_tree_add_text(rmi_tree, tvb, offset + 1, -1,
"EndPointIdentifier");
strncpy(epid_hostname,
"<string too long>", sizeof(epid_hostname));
}
+ epid_hostname[sizeof(epid_hostname)-1] = '\0';
proto_tree_add_string(rmi_tree, hf_rmi_epid_hostname,
tvb, offset + 3, strlen(epid_hostname),
epid_hostname);
port = tvb_get_ntohs(tvb, offset + len + 5);
- proto_tree_add_uint(rmi_tree, hf_rmi_epid_port,
+ proto_tree_add_uint(rmi_tree, hf_rmi_epid_port,
tvb, offset + len + 5, 2, port);
}
if(message == RMI_INPUTSTREAM_MESSAGE_RETURNDATA) {
proto_tree_add_text(rmi_tree, tvb, offset + 1, -1,
"Serialization Data");
next_tvb = tvb_new_subset(tvb, offset + 1, -1, -1);
- dissect_ser(next_tvb, pinfo, tree);
+ dissect_ser(next_tvb, tree);
}
break;
case RMI_OUTPUTMESSAGE:
message = tvb_get_guint8(tvb, 0);
- proto_tree_add_string(rmi_tree, hf_rmi_outputmessage,
- tvb, offset, 1,
- val_to_str(message,
- rmi_output_message_str,
- "Unknown Message"));
+ proto_tree_add_uint(rmi_tree, hf_rmi_outputmessage,
+ tvb, offset, 1, message);
if(message == RMI_OUTPUTSTREAM_MESSAGE_CALL) {
proto_tree_add_text(rmi_tree, tvb, offset + 1, -1,
"Serialization Data");
/* XXX */
next_tvb = tvb_new_subset(tvb, offset + 1, -1, -1);
- dissect_ser(next_tvb, pinfo, tree);
+ dissect_ser(next_tvb, tree);
}
if(message == RMI_OUTPUTSTREAM_MESSAGE_DGCACK) {
proto_tree_add_text(rmi_tree, tvb, offset + 1, -1,
}
break;
case SERIALIZATION_DATA:
- dissect_ser(tvb, pinfo, tree);
+ dissect_ser(tvb, tree);
break;
default:
break;
}
static void
-dissect_ser(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+dissect_ser(tvbuff_t *tvb, proto_tree *tree)
{
proto_item *ti;
proto_tree *ser_tree;
gint offset;
offset = 0;
-
+
if(tree) {
ti = proto_tree_add_item(tree, proto_ser, tvb, 0, -1, FALSE);
ser_tree = proto_item_add_subtree(ti, ett_ser);
- proto_tree_add_uint(ser_tree, hf_ser_magic,
- tvb, offset, 2, tvb_get_ntohs(tvb,0));
- proto_tree_add_uint(ser_tree, hf_ser_version,
- tvb, offset + 2, 2, tvb_get_ntohs(tvb,2));
+ proto_tree_add_item(ser_tree, hf_ser_magic,
+ tvb, offset, 2, FALSE);
+ proto_tree_add_item(ser_tree, hf_ser_version,
+ tvb, offset + 2, 2, FALSE);
}
}
static rmi_type
-get_rmi_type(const u_char *data, int datalen)
+get_rmi_type(const guchar *data, int datalen)
{
guint16 ser_magic;
-
+
if (datalen >= 2) {
ser_magic = data[0] << 8 | data[1];
if (ser_magic == SER_STREAM_MAGIC) {
}
}
if (datalen >= 4) {
- if(strncmp(data, "JRMI", 4) == 0) {
+ if(strncmp(data, RMI_MAGIC, 4) == 0) {
return RMI_OUTPUTSTREAM;
}
}
void
proto_register_rmi(void)
{
-
+
static hf_register_info hf[] = {
{ &hf_rmi_magic,
{ "Magic", "rmi.magic",
"RMI Header Magic", HFILL }},
{ &hf_rmi_version,
{ "Version", "rmi.version",
- FT_UINT16, BASE_DEC, NULL, 0x0,
+ FT_UINT16, BASE_DEC, NULL, 0x0,
"RMI Protocol Version", HFILL }},
{ &hf_rmi_protocol,
{ "Protocol","rmi.protocol",
- FT_STRING, BASE_HEX, NULL, 0x0,
+ FT_UINT8, BASE_HEX, VALS(rmi_protocol_str), 0x0,
"RMI Protocol Type", HFILL }},
{ &hf_rmi_inputmessage,
{ "Input Stream Message", "rmi.inputstream.message",
- FT_STRING, BASE_HEX, NULL, 0x0,
+ FT_UINT8, BASE_HEX, VALS(rmi_input_message_str), 0x0,
"RMI Inputstream Message Token", HFILL }},
{ &hf_rmi_outputmessage,
{ "Output Stream Message", "rmi.outputstream.message",
- FT_STRING, BASE_HEX, NULL, 0x0,
+ FT_UINT8, BASE_HEX, VALS(rmi_output_message_str), 0x0,
"RMI Outputstream Message token", HFILL }},
{ &hf_rmi_epid_length,
{ "Length", "rmi.endpoint_id.length",
- FT_UINT16, BASE_DEC, NULL, 0x0,
+ FT_UINT16, BASE_DEC, NULL, 0x0,
"RMI Endpointidentifier Length", HFILL }},
{ &hf_rmi_epid_hostname,
{ "Hostname", "rmi.endpoint_id.hostname",
"Java Serialization Magic", HFILL }},
{ &hf_ser_version,
{ "Version", "rmi.ser.version",
- FT_UINT16, BASE_DEC, NULL, 0x0,
+ FT_UINT16, BASE_DEC, NULL, 0x0,
"Java Serialization Version", HFILL }},
};
-
+
static gint *ett[] = {
&ett_rmi,
&ett_rmi_magic,
&ett_rmi_epid_port,
&ett_ser,
};
-
+
proto_rmi = proto_register_protocol("Java RMI", "RMI", "rmi");
proto_ser = proto_register_protocol("Java Serialization", "Serialization",
"serialization");