aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2003-04-23 00:24:38 +0000
committerGuy Harris <guy@alum.mit.edu>2003-04-23 00:24:38 +0000
commit733b96657b9c461e802a6d12c8ba0e09a53dce6d (patch)
treef125c2b34f26275baa5095ddeed2dc07bd7cab6e
parentcf110883402711dcb5c697109a30fac125c1cd6b (diff)
downloadwireshark-733b96657b9c461e802a6d12c8ba0e09a53dce6d.tar.gz
wireshark-733b96657b9c461e802a6d12c8ba0e09a53dce6d.tar.bz2
wireshark-733b96657b9c461e802a6d12c8ba0e09a53dce6d.zip
From Duncan Laurie: IPMI-over-LAN support.
svn path=/trunk/; revision=7538
-rw-r--r--AUTHORS4
-rw-r--r--Makefile.am5
-rw-r--r--Makefile.nmake5
-rw-r--r--doc/ethereal.pod.template1
-rw-r--r--packet-asf.c147
-rw-r--r--packet-ipmi.c647
-rw-r--r--packet-rmcp.c189
7 files changed, 996 insertions, 2 deletions
diff --git a/AUTHORS b/AUTHORS
index eeec8a48a6..6ec6b2ae5f 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1674,6 +1674,10 @@ Erwin Rol <erwin [AT] muffin.org> {
ArtNET support
}
+Duncan Laurie <duncan [AT] sun.com> {
+ IPMI-over-LAN support (IPMI, RMCP, partial ASF)
+}
+
And assorted fixes and enhancements by the people listed above and by:
Pavel Roskin <proski [AT] gnu.org>
diff --git a/Makefile.am b/Makefile.am
index 38601d0536..17cd47e87b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
-# $Id: Makefile.am,v 1.575 2003/04/21 21:28:31 guy Exp $
+# $Id: Makefile.am,v 1.576 2003/04/23 00:24:36 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@ethereal.com>
@@ -96,6 +96,7 @@ DISSECTOR_SRC = \
packet-arp.c \
packet-asap.c \
packet-ascend.c\
+ packet-asf.c \
packet-atalk.c \
packet-atm.c \
packet-auto_rp.c \
@@ -228,6 +229,7 @@ DISSECTOR_SRC = \
packet-imap.c \
packet-ip.c \
packet-ipfc.c \
+ packet-ipmi.c \
packet-ipp.c \
packet-ipsec.c \
packet-ipv6.c \
@@ -322,6 +324,7 @@ DISSECTOR_SRC = \
packet-rip.c \
packet-ripng.c \
packet-rlogin.c \
+ packet-rmcp.c \
packet-rmi.c \
packet-rmp.c \
packet-rpc.c \
diff --git a/Makefile.nmake b/Makefile.nmake
index a8cc2fb973..503bdf4499 100644
--- a/Makefile.nmake
+++ b/Makefile.nmake
@@ -1,7 +1,7 @@
## Makefile for building ethereal.exe with Microsoft C and nmake
## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake
#
-# $Id: Makefile.nmake,v 1.293 2003/04/16 07:24:03 guy Exp $
+# $Id: Makefile.nmake,v 1.294 2003/04/23 00:24:36 guy Exp $
include config.nmake
include <win32.mak>
@@ -38,6 +38,7 @@ DISSECTOR_SRC = \
packet-arp.c \
packet-asap.c \
packet-ascend.c\
+ packet-asf.c \
packet-atalk.c \
packet-atm.c \
packet-auto_rp.c \
@@ -170,6 +171,7 @@ DISSECTOR_SRC = \
packet-imap.c \
packet-ip.c \
packet-ipfc.c \
+ packet-ipmi.c \
packet-ipp.c \
packet-ipsec.c \
packet-ipv6.c \
@@ -264,6 +266,7 @@ DISSECTOR_SRC = \
packet-rip.c \
packet-ripng.c \
packet-rlogin.c \
+ packet-rmcp.c \
packet-rmi.c \
packet-rmp.c \
packet-rpc.c \
diff --git a/doc/ethereal.pod.template b/doc/ethereal.pod.template
index ee982ce30f..5ed6fc17a6 100644
--- a/doc/ethereal.pod.template
+++ b/doc/ethereal.pod.template
@@ -1728,6 +1728,7 @@ B<http://www.ethereal.com>.
emre <emre [AT] flash.net>
Stephen Shelley <steve.shelley [AT] attbi.com>
Erwin Rol <erwin [AT] muffin.org>
+ Duncan Laurie <duncan [AT] sun.com>
Pavel Roskin <proski [AT] gnu.org>
Georgi Guninski <guninski [AT] guninski.com>
Jason Copenhaver <jcopenha [AT] typedef.org>
diff --git a/packet-asf.c b/packet-asf.c
new file mode 100644
index 0000000000..a379a418f6
--- /dev/null
+++ b/packet-asf.c
@@ -0,0 +1,147 @@
+/* packet-asf.c
+ * Routines for ASF packet dissection
+ *
+ * Duncan Laurie <duncan@sun.com>
+ *
+ * $Id: packet-asf.c,v 1.1 2003/04/23 00:24:36 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * Copied from packet-rmcp.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <epan/packet.h>
+
+/*
+ * See
+ *
+ * http://www.dmtf.org/standards/standard_alert.php
+ */
+
+#define RMCP_CLASS_ASF 0x06
+
+static int proto_asf = -1;
+static int hf_asf_iana = -1;
+static int hf_asf_type = -1;
+static int hf_asf_tag = -1;
+static int hf_asf_len = -1;
+
+static dissector_handle_t data_handle;
+static gint ett_asf = -1;
+
+static const value_string asf_type_vals[] = {
+ { 0x10, "Reset" },
+ { 0x11, "Power-up" },
+ { 0x12, "Unconditional Power-down" },
+ { 0x13, "Power Cycle" },
+ { 0x40, "Presence Pong" },
+ { 0x41, "Capabilities Response" },
+ { 0x42, "System State Response" },
+ { 0x80, "Presence Ping" },
+ { 0x81, "Capabilities Request" },
+ { 0x82, "System State Request" },
+ { 0x00, NULL }
+};
+
+static void
+dissect_asf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_tree *asf_tree = NULL;
+ proto_item *ti;
+ guint8 type;
+ guint8 len;
+ tvbuff_t *next_tvb;
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "ASF");
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ type = tvb_get_guint8(tvb, 4);
+ len = tvb_get_guint8(tvb, 7);
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
+ val_to_str(type, asf_type_vals, "Unknown (0x%02x)"));
+
+ if (tree) {
+ ti = proto_tree_add_item(tree, proto_asf, tvb, 0, 8, TRUE);
+ asf_tree = proto_item_add_subtree(ti, ett_asf);
+ proto_tree_add_item(asf_tree, hf_asf_iana, tvb, 0, 4, TRUE);
+ proto_tree_add_item(asf_tree, hf_asf_type, tvb, 4, 1, TRUE);
+ proto_tree_add_item(asf_tree, hf_asf_tag, tvb, 5, 1, TRUE);
+ proto_tree_add_item(asf_tree, hf_asf_len, tvb, 7, 1, TRUE);
+ }
+
+ if (len) {
+ next_tvb = tvb_new_subset(tvb, 8, -1, len);
+ call_dissector(data_handle, next_tvb, pinfo, tree);
+ }
+}
+
+void
+proto_register_asf(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_asf_iana, {
+ "IANA Enterprise Number", "asf.iana",
+ FT_UINT32, BASE_HEX, NULL, 0,
+ "ASF IANA Enterprise Number", HFILL }},
+ { &hf_asf_type, {
+ "Message Type", "asf.type",
+ FT_UINT8, BASE_HEX, VALS(asf_type_vals), 0,
+ "ASF Message Type", HFILL }},
+ { &hf_asf_tag, {
+ "Message Tag", "asf.tag",
+ FT_UINT8, BASE_HEX, NULL, 0,
+ "ASF Message Tag", HFILL }},
+ { &hf_asf_len, {
+ "Data Length", "asf.len",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ "ASF Data Length", HFILL }},
+ };
+ static gint *ett[] = {
+ &ett_asf,
+ };
+
+ proto_asf = proto_register_protocol(
+ "Alert Standard Forum", "ASF", "asf");
+
+ proto_register_field_array(proto_asf, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ register_dissector("asf", dissect_asf, proto_asf);
+}
+
+void
+proto_reg_handoff_asf(void)
+{
+ dissector_handle_t asf_handle;
+ asf_handle = create_dissector_handle(dissect_asf, proto_asf);
+ dissector_add("rmcp.class", RMCP_CLASS_ASF, asf_handle);
+
+ data_handle = find_dissector("data");
+}
diff --git a/packet-ipmi.c b/packet-ipmi.c
new file mode 100644
index 0000000000..066cc68e8f
--- /dev/null
+++ b/packet-ipmi.c
@@ -0,0 +1,647 @@
+/* packet-ipmi.c
+ * Routines for IPMI-over-LAN packet dissection
+ *
+ * Duncan Laurie <duncan@sun.com>
+ *
+ * $Id: packet-ipmi.c,v 1.1 2003/04/23 00:24:36 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * Copied from packet-rmcp.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * 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.
+ *
+ *
+ * See the IPMI spec at
+ *
+ * http://www.intel.com/design/servers/ipmi/
+ *
+ * IPMI LAN Message Request
+ * ipmi.session.authtype
+ * ipmi.session.sequence
+ * ipmi.session.id
+ * [ipmi.session.authcode]
+ * ipmi.msg.len
+ * ipmi.msg.rsaddr
+ * ipmi.msg.netfn << 2 | ipmi.msg.rslun
+ * ipmi.msg.csum1
+ * ipmi.msg.rqaddr
+ * ipmi.msg.seq << 2 | ipmi.msg.rqlun
+ * ipmi.msg.cmd
+ * ipmi.msg.DATA
+ * ipmi.msg.csum2
+ *
+ * IPMI LAN Message Response
+ * ipmi.session.authtype
+ * ipmi.session.sequence
+ * ipmi.session.id
+ * [ipmi.session.authcode]
+ * ipmi.msg.len
+ * ipmi.msg.rqaddr
+ * ipmi.msg.netfn << 2 | ipmi.msg.rqlun
+ * ipmi.msg.csum1
+ * ipmi.msg.rsaddr
+ * ipmi.msg.seq << 2 | ipmi.msg.rslun
+ * ipmi.msg.cmd
+ * ipmi.msg.ccode
+ * ipmi.msg.DATA
+ * ipmi.msg.csum2
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <epan/packet.h>
+
+#define RMCP_CLASS_IPMI 0x07
+
+static dissector_handle_t data_handle;
+static int proto_ipmi = -1;
+
+static gint ett_ipmi = -1;
+static gint ett_ipmi_session = -1;
+static gint ett_ipmi_msg_nlfield = -1;
+static gint ett_ipmi_msg_slfield = -1;
+
+/* IPMI session header */
+static int hf_ipmi_session_id = -1;
+static int hf_ipmi_session_authtype = -1;
+static int hf_ipmi_session_sequence = -1;
+static int hf_ipmi_session_authcode = -1;
+
+/* IPMI message header */
+static int hf_ipmi_msg_len = -1;
+static int hf_ipmi_msg_rsaddr = -1;
+static int hf_ipmi_msg_nlfield = -1;
+static int hf_ipmi_msg_netfn = -1;
+static int hf_ipmi_msg_rqlun = -1;
+static int hf_ipmi_msg_csum1 = -1;
+static int hf_ipmi_msg_rqaddr = -1;
+static int hf_ipmi_msg_slfield = -1;
+static int hf_ipmi_msg_seq = -1;
+static int hf_ipmi_msg_rslun = -1;
+static int hf_ipmi_msg_cmd = -1;
+static int hf_ipmi_msg_ccode = -1;
+static int hf_ipmi_msg_csum2 = -1;
+
+static const value_string ipmi_netfn_vals[] = {
+ { 0x00, "Chassis Request" },
+ { 0x01, "Chassis Response" },
+ { 0x02, "Bridge Request" },
+ { 0x03, "Bridge Response" },
+ { 0x04, "Sensor/Event Request" },
+ { 0x05, "Sensor/Event Response" },
+ { 0x06, "Application Request" },
+ { 0x07, "Application Response" },
+ { 0x08, "Firmware Request" },
+ { 0x09, "Frimware Response" },
+ { 0x0a, "Storage Request" },
+ { 0x0b, "Storage Response" },
+ { 0x0c, "Transport Request" },
+ { 0x0d, "Transport Response" },
+ { 0x2c, "Group Extension Request" },
+ { 0x2d, "Group Extension Response" },
+ { 0x30, "OEM Request" },
+ { 0x31, "OEM Response" },
+ { 0x00, NULL },
+};
+
+static const value_string ipmi_authtype_vals[] = {
+ { 0x00, "NONE" },
+ { 0x01, "MD2" },
+ { 0x02, "MD5" },
+ { 0x04, "PASSWORD" },
+ { 0x05, "OEM" },
+ { 0x00, NULL }
+};
+
+static const value_string ipmi_ccode_vals[] = {
+ { 0x00, "Command completed normally" },
+ { 0xc0, "Node busy" },
+ { 0xc1, "Unrecognized or unsupported command" },
+ { 0xc2, "Command invalid for given LUN" },
+ { 0xc3, "Timeout while processing command" },
+ { 0xc4, "Out of space" },
+ { 0xc5, "Reservation cancelled or invalid reservation ID" },
+ { 0xc6, "Request data truncated" },
+ { 0xc7, "Request data length invalid" },
+ { 0xc8, "Request data field length limit exceeded" },
+ { 0xc9, "Parameter out of range" },
+ { 0xca, "Cannot return number of requested data bytes" },
+ { 0xcb, "Requested sensor, data, or record not present" },
+ { 0xcc, "Invalid data field in request" },
+ { 0xcd, "Command illegal for specified sensor or record type" },
+ { 0xce, "Command response could not be provided" },
+ { 0xcf, "Cannot execute duplicated request" },
+ { 0xd0, "SDR repository in update mode" },
+ { 0xd1, "Device in firmware update mode" },
+ { 0xd2, "BMC initialization or initialization agent running" },
+ { 0xd3, "Destination unavailable" },
+ { 0xd4, "Insufficient privilege level" },
+ { 0xd5, "Command or param not supported in present state" },
+ { 0xff, "Unspecified error" },
+ { 0x00, NULL },
+};
+
+static const value_string ipmi_addr_vals[] = {
+ { 0x20, "BMC Slave Address" },
+ { 0x81, "Remote Console Software ID" },
+ { 0x00, NULL },
+};
+
+static const value_string ipmi_chassis_cmd_vals[] = {
+ /* Chassis Device Commands */
+ { 0x00, "Get Chassis Capabilities" },
+ { 0x01, "Get Chassis Status" },
+ { 0x02, "Chassis Control" },
+ { 0x03, "Chassis Reset" },
+ { 0x04, "Chassis Identify" },
+ { 0x05, "Set Chassis Capabilities" },
+ { 0x06, "Set Power Restore Policy" },
+ { 0x07, "Get System Restart Cause" },
+ { 0x08, "Set System Boot Options" },
+ { 0x09, "Get System Boot Options" },
+ { 0x0f, "Get POH Counter" },
+ { 0x00, NULL },
+};
+
+static const value_string ipmi_bridge_cmd_vals[] = {
+ /* ICMB Bridge Management Commands */
+ { 0x00, "Get Bridge State" },
+ { 0x01, "Set Bridge State" },
+ { 0x02, "Get ICMB Address" },
+ { 0x03, "Set ICMB Address" },
+ { 0x04, "Set Bridge ProxyAddress" },
+ { 0x05, "Get Bridge Statistics" },
+ { 0x06, "Get ICMB Capabilities" },
+ { 0x08, "Clear Bridge Statistics" },
+ { 0x09, "Get Bridge Proxy Address" },
+ { 0x0a, "Get ICMB Connector Info" },
+ { 0x0b, "Get ICMB Connection ID" },
+ { 0x0c, "Send ICMB Connection ID" },
+ /* ICMB Discovery Commands */
+ { 0x10, "Prepare For Discovery" },
+ { 0x11, "Get Addresses" },
+ { 0x12, "Set Discovered" },
+ { 0x13, "Get Chassis Device ID" },
+ { 0x14, "Set Chassis Device ID" },
+ /* ICMB Bridging Commands */
+ { 0x20, "Bridge Request" },
+ { 0x21, "Bridge Message" },
+ /* ICMB Event Commands */
+ { 0x30, "Get Event Count" },
+ { 0x31, "Set Event Destination" },
+ { 0x32, "Set Event Reception State" },
+ { 0x33, "Send ICMB Event Message" },
+ { 0x34, "Get Event Destination" },
+ { 0x35, "Get Event Recption State" },
+ { 0x00, NULL },
+};
+
+static const value_string ipmi_se_cmd_vals[] = {
+ /* Event Commands */
+ { 0x00, "Set Event Receiver" },
+ { 0x01, "Get Event Receiver" },
+ { 0x02, "Platform Event Message" },
+ /* PEF and Alerting Commands */
+ { 0x10, "Get PEF Capabilities" },
+ { 0x11, "Arm PEF Postpone Timer" },
+ { 0x12, "Set PEF Config Params" },
+ { 0x13, "Get PEF Config Params" },
+ { 0x14, "Set Last Processed Event ID" },
+ { 0x15, "Get Last Processed Event ID" },
+ { 0x16, "Alert Immediate" },
+ { 0x17, "PET Acknowledge" },
+ /* Sensor Device Commands */
+ { 0x20, "Get Device SDR Info" },
+ { 0x21, "Get Device SDR" },
+ { 0x22, "Reserve Device SDR Repository" },
+ { 0x23, "Get Sensor Reading Factors" },
+ { 0x24, "Set Sensor Hysteresis" },
+ { 0x25, "Get Sensor Hysteresis" },
+ { 0x26, "Set Sensor Threshold" },
+ { 0x27, "Get Sensor Threshold" },
+ { 0x28, "Set Sensor Event Enable" },
+ { 0x29, "Get Sensor Event Enable" },
+ { 0x2a, "Re-arm Sensor Events" },
+ { 0x2b, "Get Sensor Event Status" },
+ { 0x2d, "Get Sensor Reading" },
+ { 0x2e, "Set Sensor Type" },
+ { 0x2f, "Get Sensor Type" },
+ { 0x00, NULL },
+};
+
+static const value_string ipmi_storage_cmd_vals[] = {
+ /* FRU Device Commands */
+ { 0x10, "Get FRU Inventory Area Info" },
+ { 0x11, "Read FRU Data" },
+ { 0x12, "Write FRU Data" },
+ /* SDR Device Commands */
+ { 0x20, "Get SDR Repository Info" },
+ { 0x21, "Get SDR Repository Allocation Info" },
+ { 0x22, "Reserve SDR Repository" },
+ { 0x23, "Get SDR" },
+ { 0x24, "Add SDR" },
+ { 0x25, "Partial Add SDR" },
+ { 0x26, "Delete SDR" },
+ { 0x27, "Clear SDR Repository" },
+ { 0x28, "Get SDR Repository Time" },
+ { 0x29, "Set SDR Repository Time" },
+ { 0x2a, "Enter SDR Repository Update Mode" },
+ { 0x2b, "Exit SDR Repository Update Mode" },
+ { 0x2c, "Run Initialization Agent" },
+ /* SEL Device Commands */
+ { 0x40, "Get SEL Info" },
+ { 0x41, "Get SEL Allocation Info" },
+ { 0x42, "Reserve SEL" },
+ { 0x43, "Get SEL Entry" },
+ { 0x44, "Add SEL Entry" },
+ { 0x45, "Partial Add SEL Entry" },
+ { 0x46, "Delete SEL Entry" },
+ { 0x47, "Clear SEL" },
+ { 0x48, "Get SEL Time" },
+ { 0x49, "Set SEL Time" },
+ { 0x5a, "Get Auxillary Log Status" },
+ { 0x5b, "Set Auxillary Log Status" },
+ { 0x00, NULL },
+};
+
+static const value_string ipmi_transport_cmd_vals[] = {
+ /* LAN Device Commands */
+ { 0x01, "Set LAN Config Param" },
+ { 0x02, "Get LAN Config Param" },
+ { 0x03, "Suspend BMC ARPs" },
+ { 0x04, "Get IP/UDP/RMCP Statistics" },
+ /* Serial/Modem Device Commands */
+ { 0x10, "Set Serial/Modem Config" },
+ { 0x11, "Get Serial/Modem Config" },
+ { 0x12, "Get Serial/Modem Mux" },
+ { 0x13, "Get TAP Response Codes" },
+ { 0x14, "Set PPP UDP Proxy Transmit Data" },
+ { 0x15, "Get PPP UDP Proxy Transmit Data" },
+ { 0x16, "Send PPP UDP Proxy Packet" },
+ { 0x17, "Get PPP UDP Proxy Data" },
+ { 0x18, "Serial/Modem Connection Active" },
+ { 0x19, "Callback" },
+ { 0x1a, "Set User Callback Options" },
+ { 0x1b, "Get User Callback Options" },
+ { 0x00, NULL },
+};
+
+static const value_string ipmi_app_cmd_vals[] = {
+ /* Device "Global" Commands */
+ { 0x01, "Get Device ID" },
+ { 0x02, "Cold Reset" },
+ { 0x03, "Warm Reset" },
+ { 0x04, "Get Self Test Results" },
+ { 0x05, "Manufacturing Test On" },
+ { 0x06, "Set ACPI Power State" },
+ { 0x07, "Get ACPI Power State" },
+ { 0x08, "Get Device GUID" },
+ /* BMC Watchdog Timer Commands */
+ { 0x22, "Reset Watchdog Timer" },
+ { 0x24, "Set Watchdog Timer" },
+ { 0x25, "Get Watchdog Timer" },
+ /* BMC Device and Messaging Commands */
+ { 0x2e, "Set BMC Global Enables" },
+ { 0x2f, "Get BMC Global Enables" },
+ { 0x30, "Clear Message Flags" },
+ { 0x31, "Get Message Flags" },
+ { 0x32, "Enable Message Channel Receive" },
+ { 0x33, "Get Message" },
+ { 0x34, "Send Message" },
+ { 0x35, "Read Event Message Buffer" },
+ { 0x36, "Get BT Interface Capabilities" },
+ { 0x37, "Get System GUID" },
+ { 0x38, "Get Channel Auth Capabilities" },
+ { 0x39, "Get Session Challenge" },
+ { 0x3a, "Activate Session" },
+ { 0x3b, "Set Session Privilege Level" },
+ { 0x3c, "Close Session" },
+ { 0x3d, "Get Session Info" },
+ { 0x3e, "unassigned" },
+ { 0x3f, "Get AuthCode" },
+ { 0x40, "Set Channel Access" },
+ { 0x41, "Get Channel Access" },
+ { 0x42, "Get Channel Info" },
+ { 0x43, "Set User Access" },
+ { 0x44, "Get User Access" },
+ { 0x45, "Set User Name" },
+ { 0x46, "Get User Name" },
+ { 0x47, "Set User Password" },
+ { 0x52, "Master Write-Read" },
+ { 0x00, NULL },
+};
+
+static const char *
+get_netfn_cmd_text(guint8 netfn, guint8 cmd)
+{
+ switch (netfn) {
+ case 0x00:
+ case 0x01:
+ return val_to_str(cmd, ipmi_chassis_cmd_vals, "Unknown (0x%02x)");
+ case 0x02:
+ case 0x03:
+ return val_to_str(cmd, ipmi_bridge_cmd_vals, "Unknown (0x%02x)");
+ case 0x04:
+ case 0x05:
+ return val_to_str(cmd, ipmi_se_cmd_vals, "Unknown (0x%02x)");
+ case 0x06:
+ case 0x07:
+ return val_to_str(cmd, ipmi_app_cmd_vals, "Unknown (0x%02x)");
+ case 0x0a:
+ case 0x0b:
+ return val_to_str(cmd, ipmi_storage_cmd_vals, "Unknown (0x%02x)");
+ case 0x0c:
+ case 0x0d:
+ return val_to_str(cmd, ipmi_transport_cmd_vals, "Unknown (0x%02x)");
+ default:
+ return (netfn & 1) ? "Unknown Response" : "Unknown Request";
+ }
+}
+
+static void
+dissect_ipmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_tree *ipmi_tree = NULL, *field_tree = NULL;
+ proto_item *ti = NULL, *tf;
+ gint offset = 0;
+ tvbuff_t *next_tvb;
+ guint32 session_id;
+ guint8 authtype, netfn, cmd, ccode, len;
+ gint response;
+
+ /* session authtype, 0=no authcode present */
+ authtype = tvb_get_guint8(tvb, 0);
+
+ /* session ID */
+ session_id = tvb_get_letohl(tvb, 5);
+
+ /* network function code */
+ netfn = tvb_get_guint8(tvb, authtype ? 27 : 11) >> 2;
+
+ /* bit 0 of netfn: even=request odd=response */
+ response = netfn & 1;
+
+ /* command */
+ cmd = tvb_get_guint8(tvb, authtype ? 31 : 15);
+
+ /* completion code */
+ ccode = response ? tvb_get_guint8(tvb, authtype ? 32 : 16) : 0;
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPMI");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ if (ccode)
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s, %s: %s",
+ get_netfn_cmd_text(netfn, cmd),
+ val_to_str(netfn, ipmi_netfn_vals, "Unknown (0x%02x)"),
+ val_to_str(ccode, ipmi_ccode_vals, "Unknown (0x%02x)"));
+ else
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s, %s",
+ get_netfn_cmd_text(netfn, cmd),
+ val_to_str(netfn, ipmi_netfn_vals, "Unknown (0x%02x)"));
+ }
+
+ if (tree) {
+ ti = proto_tree_add_protocol_format(tree, proto_ipmi,
+ tvb, offset, authtype ? 32 : 16,
+ "Intelligent Platform Management Interface, "
+ "NetFn: %s (0x%02x), Cmd: %s (0x%02x)",
+ val_to_str(netfn, ipmi_netfn_vals, "Unknown (0x%02x)"),
+ netfn, get_netfn_cmd_text(netfn, cmd), cmd);
+ ipmi_tree = proto_item_add_subtree(ti, ett_ipmi);
+ }
+
+ /* ipmi session field */
+ if (tree) {
+ tf = proto_tree_add_text(ipmi_tree, tvb, offset,
+ authtype ? 25 : 9,
+ "Session: ID 0x%08x (%d bytes)",
+ session_id, authtype ? 25 : 9);
+ field_tree = proto_item_add_subtree(tf, ett_ipmi_session);
+ proto_tree_add_item(field_tree, hf_ipmi_session_authtype,
+ tvb, offset++, 1, TRUE);
+ proto_tree_add_item(field_tree, hf_ipmi_session_sequence,
+ tvb, offset, 4, TRUE);
+ offset += 4;
+ proto_tree_add_item(field_tree, hf_ipmi_session_id,
+ tvb, offset, 4, TRUE);
+ offset += 4;
+ if (authtype) {
+ proto_tree_add_item(field_tree, hf_ipmi_session_authcode,
+ tvb, offset, 16, TRUE);
+ offset += 16;
+ }
+ }
+
+ /* message length */
+ if (tree) {
+ proto_tree_add_item(ipmi_tree, hf_ipmi_msg_len,
+ tvb, offset++, 1, TRUE);
+ }
+
+ /* r[sq]addr */
+ if (tree) {
+ proto_tree_add_item(ipmi_tree,
+ response ? hf_ipmi_msg_rqaddr : hf_ipmi_msg_rsaddr,
+ tvb, offset++, 1, TRUE);
+ }
+
+ /* netfn/lun */
+ if (tree) {
+ tf = proto_tree_add_text(ipmi_tree, tvb, offset, 1,
+ "NetFn/LUN: %s", val_to_str(netfn,
+ ipmi_netfn_vals, "Unknown (0x%02x)"));
+
+ field_tree = proto_item_add_subtree(tf, ett_ipmi_msg_nlfield);
+
+ proto_tree_add_item(field_tree, hf_ipmi_msg_netfn,
+ tvb, offset, 1, TRUE);
+ proto_tree_add_item(field_tree,
+ response ? hf_ipmi_msg_rqlun : hf_ipmi_msg_rslun,
+ tvb, offset, 1, TRUE);
+ offset += 1;
+ }
+
+ /* checksum */
+ if (tree) {
+ proto_tree_add_item(ipmi_tree, hf_ipmi_msg_csum1,
+ tvb, offset++, 1, TRUE);
+ }
+
+ /* r[sq]addr */
+ if (tree) {
+ proto_tree_add_item(ipmi_tree,
+ response ? hf_ipmi_msg_rsaddr : hf_ipmi_msg_rqaddr,
+ tvb, offset++, 1, TRUE);
+ }
+
+ /* seq/lun */
+ if (tree) {
+ tf = proto_tree_add_item(ipmi_tree, hf_ipmi_msg_slfield,
+ tvb, offset, 1, TRUE);
+ field_tree = proto_item_add_subtree(tf, ett_ipmi_msg_slfield);
+
+ proto_tree_add_item(field_tree, hf_ipmi_msg_seq,
+ tvb, offset, 1, TRUE);
+ proto_tree_add_item(field_tree,
+ response ? hf_ipmi_msg_rslun : hf_ipmi_msg_rqlun,
+ tvb, offset, 1, TRUE);
+ offset += 1;
+ }
+
+ /* command */
+ if (tree) {
+ proto_tree_add_text(ipmi_tree, tvb, offset++, 1,
+ "Command: %s (0x%02x)",
+ get_netfn_cmd_text(netfn, cmd), cmd);
+ }
+
+ /* completion code */
+ if (tree && response) {
+ proto_tree_add_item(ipmi_tree, hf_ipmi_msg_ccode,
+ tvb, offset++, 1, TRUE);
+ }
+
+ /* determine data length */
+ len = tvb_get_guint8(tvb, authtype ? 25 : 9) - 7 - (response ? 1 : 0);
+
+ /* dissect the data block */
+ next_tvb = tvb_new_subset(tvb, offset, len, len);
+ call_dissector(data_handle, next_tvb, pinfo, tree);
+ offset += len;
+
+ /* checksum 2 */
+ if (tree) {
+ proto_tree_add_item(ipmi_tree, hf_ipmi_msg_csum2,
+ tvb, offset++, 1, TRUE);
+ }
+}
+
+void
+proto_register_ipmi(void)
+{
+ static hf_register_info hf_session[] = {
+ { &hf_ipmi_session_authtype, {
+ "Authentication Type", "ipmi.session.authtype",
+ FT_UINT8, BASE_HEX, VALS(ipmi_authtype_vals), 0,
+ "IPMI Authentication Type", HFILL }},
+ { &hf_ipmi_session_sequence, {
+ "Session Sequence Number", "ipmi.session.sequence",
+ FT_UINT32, BASE_HEX, NULL, 0,
+ "IPMI Session Sequence Number", HFILL }},
+ { &hf_ipmi_session_id, {
+ "Session ID", "ipmi.session.id",
+ FT_UINT32, BASE_HEX, NULL, 0,
+ "IPMI Session ID", HFILL }},
+ { &hf_ipmi_session_authcode, {
+ "Authentication Code", "ipmi.session.authcode",
+ FT_BYTES, BASE_HEX, NULL, 0,
+ "IPMI Message Authentication Code", HFILL }},
+ };
+ static hf_register_info hf_msg[] = {
+ { &hf_ipmi_msg_len, {
+ "Message Length", "ipmi.msg.len",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ "IPMI Message Length", HFILL }},
+ { &hf_ipmi_msg_rsaddr, {
+ "Response Address", "ipmi.msg.rsaddr",
+ FT_UINT8, BASE_HEX, VALS(ipmi_addr_vals), 0,
+ "Responder's Slave Address", HFILL }},
+ { &hf_ipmi_msg_csum1, {
+ "Checksum 1", "ipmi.msg.csum1",
+ FT_UINT8, BASE_HEX, NULL, 0,
+ "2s Complement Checksum", HFILL }},
+ { &hf_ipmi_msg_rqaddr, {
+ "Request Address", "ipmi.msg.rqaddr",
+ FT_UINT8, BASE_HEX, VALS(ipmi_addr_vals), 0,
+ "Requester's Address (SA or SWID)", HFILL }},
+ { &hf_ipmi_msg_cmd, {
+ "Command", "ipmi.msg.cmd",
+ FT_UINT8, BASE_HEX, NULL, 0,
+ "IPMI Command Byte", HFILL }},
+ { &hf_ipmi_msg_ccode, {
+ "Completion Code", "ipmi.msg.ccode",
+ FT_UINT8, BASE_HEX, VALS(ipmi_ccode_vals), 0,
+ "Completion Code for Request", HFILL }},
+ { &hf_ipmi_msg_csum2, {
+ "Checksum 2", "ipmi.msg.csum2",
+ FT_UINT8, BASE_HEX, NULL, 0,
+ "2s Complement Checksum", HFILL }},
+ };
+ static hf_register_info hf_msg_field[] = {
+ { &hf_ipmi_msg_nlfield, {
+ "NetFn/LUN", "ipmi.msg.nlfield",
+ FT_UINT8, BASE_HEX, NULL, 0,
+ "Network Function and LUN field", HFILL }},
+ { &hf_ipmi_msg_netfn, {
+ "NetFn", "ipmi.msg.nlfield.netfn",
+ FT_UINT8, BASE_HEX, VALS(ipmi_netfn_vals), 0xfc,
+ "Network Function Code", HFILL }},
+ { &hf_ipmi_msg_rqlun, {
+ "Request LUN", "ipmi.msg.nlfield.rqlun",
+ FT_UINT8, BASE_HEX, NULL, 0x03,
+ "Requester's Logical Unit Number", HFILL }},
+ { &hf_ipmi_msg_slfield, {
+ "Seq/LUN", "ipmi.msg.slfield",
+ FT_UINT8, BASE_HEX, NULL, 0,
+ "Sequence and LUN field", HFILL }},
+ { &hf_ipmi_msg_seq, {
+ "Sequence", "ipmi.msg.slfield.seq",
+ FT_UINT8, BASE_HEX, NULL, 0xfc,
+ "Sequence Number (requester)", HFILL }},
+ { &hf_ipmi_msg_rslun, {
+ "Response LUN", "ipmi.msg.slfield.rslun",
+ FT_UINT8, BASE_HEX, NULL, 0x03,
+ "Responder's Logical Unit Number", HFILL }},
+ };
+ static gint *ett[] = {
+ &ett_ipmi,
+ &ett_ipmi_session,
+ &ett_ipmi_msg_nlfield,
+ &ett_ipmi_msg_slfield,
+ };
+
+ proto_ipmi = proto_register_protocol(
+ "Intelligent Platform Management Interface", "IPMI", "ipmi");
+
+ proto_register_field_array(proto_ipmi, hf_session,
+ array_length(hf_session));
+ proto_register_field_array(proto_ipmi, hf_msg,
+ array_length(hf_msg));
+ proto_register_field_array(proto_ipmi, hf_msg_field,
+ array_length(hf_msg_field));
+
+ proto_register_subtree_array(ett, array_length(ett));
+
+ register_dissector("ipmi", dissect_ipmi, proto_ipmi);
+}
+
+void
+proto_reg_handoff_ipmi(void)
+{
+ dissector_handle_t ipmi_handle;
+ ipmi_handle = create_dissector_handle(dissect_ipmi, proto_ipmi);
+ dissector_add("rmcp.class", RMCP_CLASS_IPMI, ipmi_handle);
+ data_handle = find_dissector("data");
+}
diff --git a/packet-rmcp.c b/packet-rmcp.c
new file mode 100644
index 0000000000..1f083cf69a
--- /dev/null
+++ b/packet-rmcp.c
@@ -0,0 +1,189 @@
+/* packet-rmcp.c
+ * Routines for RMCP packet dissection
+ *
+ * Duncan Laurie <duncan@sun.com>
+ *
+ * $Id: packet-rmcp.c,v 1.1 2003/04/23 00:24:36 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * Copied from packet-tftp.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib.h>
+#include <epan/packet.h>
+
+/*
+ * See
+ *
+ * http://www.dmtf.org/standards/standard_alert.php
+ *
+ * (the ASF specification includes RMCP)
+ */
+
+static int proto_rmcp = -1;
+static int hf_rmcp_version = -1;
+static int hf_rmcp_sequence = -1;
+static int hf_rmcp_class = -1;
+static int hf_rmcp_type = -1;
+
+static gint ett_rmcp = -1;
+static gint ett_rmcp_typeclass = -1;
+
+static dissector_handle_t asf_handle;
+static dissector_handle_t ipmi_handle;
+static dissector_table_t rmcp_dissector_table;
+
+#define UDP_PORT_RMCP 623
+#define UDP_PORT_RMCP_SECURE 664
+
+#define RMCP_TYPE_MASK 0x80
+#define RMCP_TYPE_NORM 0x00
+#define RMCP_TYPE_ACK 0x01
+
+static const value_string rmcp_type_vals[] = {
+ { RMCP_TYPE_NORM, "Normal RMCP" },
+ { RMCP_TYPE_ACK, "RMCP ACK" },
+ { 0, NULL }
+};
+
+#define RMCP_CLASS_MASK 0x1f
+#define RMCP_CLASS_ASF 0x06
+#define RMCP_CLASS_IPMI 0x07
+#define RMCP_CLASS_OEM 0x08
+
+static const value_string rmcp_class_vals[] = {
+ { RMCP_CLASS_ASF, "ASF" },
+ { RMCP_CLASS_IPMI, "IPMI" },
+ { RMCP_CLASS_OEM, "OEM" },
+ { 0, NULL }
+};
+
+static void
+dissect_rmcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_tree *rmcp_tree = NULL, *field_tree;
+ proto_item *ti, *tf;
+ tvbuff_t *next_tvb;
+ guint8 class;
+ guint8 type;
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "RMCP");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ /* check RMCP class for normal/ack bit */
+ class = tvb_get_guint8(tvb, 3);
+ type = (class & RMCP_TYPE_MASK) >> 7;
+ class &= RMCP_CLASS_MASK;
+
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s, Class: %s",
+ val_to_str(type, rmcp_type_vals, "Unknown (0x%02x)"),
+ val_to_str(class, rmcp_class_vals, "Unknown (0x%02x)"));
+
+ if (tree) {
+ ti = proto_tree_add_protocol_format(tree, proto_rmcp, tvb, 0, 4,
+ "Remote Management Control Protocol, Class: %s",
+ val_to_str(class, rmcp_class_vals, "Unknown (0x%02x)"));
+ rmcp_tree = proto_item_add_subtree(ti, ett_rmcp);
+
+ proto_tree_add_item(rmcp_tree, hf_rmcp_version, tvb, 0, 1, TRUE);
+ proto_tree_add_item(rmcp_tree, hf_rmcp_sequence, tvb, 2, 1, TRUE);
+
+ tf = proto_tree_add_text(rmcp_tree, tvb, 3, 1, "Type: %s, Class: %s",
+ val_to_str(type, rmcp_type_vals, "Unknown (0x%02)"),
+ val_to_str(class, rmcp_class_vals, "Unknown (0x%02)"));
+
+ field_tree = proto_item_add_subtree(tf, ett_rmcp_typeclass);
+
+ proto_tree_add_item(field_tree, hf_rmcp_class, tvb, 3, 1, TRUE);
+ proto_tree_add_item(field_tree, hf_rmcp_type, tvb, 3, 1, TRUE);
+ }
+
+ next_tvb = tvb_new_subset(tvb, 4, -1, -1);
+
+ switch (class) {
+ case RMCP_CLASS_ASF:
+ call_dissector(asf_handle, next_tvb, pinfo, tree);
+ break;
+ case RMCP_CLASS_IPMI:
+ call_dissector(ipmi_handle, next_tvb, pinfo, tree);
+ break;
+ default:
+ break;
+ }
+}
+
+void
+proto_register_rmcp(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_rmcp_version, {
+ "Version", "rmcp.version",
+ FT_UINT8, BASE_HEX, NULL, 0,
+ "RMCP Version", HFILL }},
+ { &hf_rmcp_sequence, {
+ "Sequence", "rmcp.sequence",
+ FT_UINT8, BASE_HEX, NULL, 0,
+ "RMCP Sequence", HFILL }},
+ { &hf_rmcp_class, {
+ "Class", "rmcp.class",
+ FT_UINT8, BASE_HEX,
+ VALS(rmcp_class_vals), RMCP_CLASS_MASK,
+ "RMCP Class", HFILL }},
+ { &hf_rmcp_type, {
+ "Message Type", "rmcp.type",
+ FT_UINT8, BASE_HEX,
+ VALS(rmcp_type_vals), RMCP_TYPE_MASK,
+ "RMCP Message Type", HFILL }},
+ };
+ static gint *ett[] = {
+ &ett_rmcp,
+ &ett_rmcp_typeclass,
+ };
+
+ proto_rmcp = proto_register_protocol(
+ "Remote Management Control Protocol", "RMCP", "rmcp");
+
+ proto_register_field_array(proto_rmcp, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ register_dissector("rmcp", dissect_rmcp, proto_rmcp);
+
+ rmcp_dissector_table = register_dissector_table(
+ "rmcp.class", "RMCP Class", FT_UINT8, BASE_HEX);
+}
+
+void
+proto_reg_handoff_rmcp(void)
+{
+ dissector_handle_t rmcp_handle;
+ rmcp_handle = create_dissector_handle(dissect_rmcp, proto_rmcp);
+ ipmi_handle = find_dissector("ipmi");
+ asf_handle = find_dissector("asf");
+ dissector_add("udp.port", UDP_PORT_RMCP, rmcp_handle);
+ dissector_add("udp.port", UDP_PORT_RMCP_SECURE, rmcp_handle);
+}