Update a URL.
[obnox/wireshark/wip.git] / packet-rmi.c
index 9e1f9e3b3775e71353b85c5840b8a942c7d752ec..f1d016bc69cd1c9c73fb147a74a509bea83903e3 100644 (file)
@@ -2,7 +2,7 @@
  * 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;
@@ -65,7 +63,6 @@ static int hf_ser_version        = -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;
@@ -73,11 +70,43 @@ static gint ett_rmi_epid_hostname = -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)
 {
@@ -89,7 +118,7 @@ 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;
@@ -102,14 +131,14 @@ dissect_rmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     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:
@@ -118,7 +147,7 @@ dissect_rmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                         "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;
@@ -154,23 +183,18 @@ dissect_rmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        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");
@@ -186,34 +210,32 @@ dissect_rmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                    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,
@@ -221,7 +243,7 @@ dissect_rmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
            }
            break;
        case SERIALIZATION_DATA:
-           dissect_ser(tvb, pinfo, tree);
+           dissect_ser(tvb, tree);
            break;
        default:
            break;
@@ -230,7 +252,7 @@ dissect_rmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 }
 
 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;
@@ -238,23 +260,23 @@ dissect_ser(tvbuff_t *tvb, packet_info *pinfo, proto_tree *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) {
@@ -262,7 +284,7 @@ get_rmi_type(const u_char *data, int datalen)
        }
     }
     if (datalen >= 4) {
-       if(strncmp(data, "JRMI", 4) == 0) {
+       if(strncmp(data, RMI_MAGIC, 4) == 0) {
            return RMI_OUTPUTSTREAM;
        }
     }
@@ -287,7 +309,7 @@ get_rmi_type(const u_char *data, int datalen)
 void
 proto_register_rmi(void)
 {
-    
+
     static hf_register_info hf[] = {
        { &hf_rmi_magic,
          { "Magic",   "rmi.magic",
@@ -295,23 +317,23 @@ proto_register_rmi(void)
            "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",
@@ -328,10 +350,10 @@ proto_register_rmi(void)
            "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,
@@ -343,7 +365,7 @@ proto_register_rmi(void)
        &ett_rmi_epid_port,
        &ett_ser,
     };
-    
+
     proto_rmi = proto_register_protocol("Java RMI", "RMI", "rmi");
     proto_ser = proto_register_protocol("Java Serialization", "Serialization",
                                        "serialization");