From Alexey Neyman :

(Note just checking in the new files not yet added to the build process on purpose
the changes to packet-ipmi.c is also not done yet - Anders).

Generic changes:

- IPMI session wrapper dissection has been separated from the dissection of
  IPMI itself. This will allow for possible dissection of captures directly
  from IPMB (as the IPMB messages lack the IPMI session wrapper).
IPMI changes:

- Implemented request-response matching for IPMI sessions. This makes easy
  serves two purposes: first, it allows for easy location of response to a
  certain request and vice versa. Second, it allows for dissection of
  responses where response format depends on the request data.

- IPMI dissector can now dissect much broader set of commands.

- Command-specific completion codes are now handled.

- The dissector is able to parse IPMI commands embedded into other IPMI
  commands (for now, only Send Message; Get Message and Forward Message
  can be implemented later). Such embedded commands also matched with
  responses to them.

svn path=/trunk/; revision=25948
This commit is contained in:
Anders Broman 2008-08-06 20:51:02 +00:00
parent c77c787122
commit 46a26582ec
11 changed files with 13676 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,149 @@
/* packet-ipmi-bridge.c
* Sub-dissectors for IPMI messages (netFn=Bridge)
* Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <epan/packet.h>
#include "packet-ipmi.h"
/* Bridge commands are not implemented (yet) */
static ipmi_cmd_t cmd_bridge[] = {
/* Bridge management commands (ICMB) */
{ 0x00, IPMI_TBD, NULL, NULL, "[ICMB] Get Bridge State", 0 },
{ 0x01, IPMI_TBD, NULL, NULL, "[ICMB] Set Bridge State", 0 },
{ 0x02, IPMI_TBD, NULL, NULL, "[ICMB] Get ICMB Address", 0 },
{ 0x03, IPMI_TBD, NULL, NULL, "[ICMB] Set ICMB Address", 0 },
{ 0x04, IPMI_TBD, NULL, NULL, "[ICMB] Set Bridge Proxy Address", 0 },
{ 0x05, IPMI_TBD, NULL, NULL, "[ICMB] Get Bridge Statistics", 0 },
{ 0x06, IPMI_TBD, NULL, NULL, "[ICMB] Get ICMB Capabilities", 0 },
{ 0x08, IPMI_TBD, NULL, NULL, "[ICMB] Clear Bridge Statistics", 0 },
{ 0x09, IPMI_TBD, NULL, NULL, "[ICMB] Get Bridge Proxy Address", 0 },
{ 0x0a, IPMI_TBD, NULL, NULL, "[ICMB] Get ICMB Connector Info", 0 },
{ 0x0b, IPMI_TBD, NULL, NULL, "[ICMB] Get ICMB Connection ID", 0 },
{ 0x0c, IPMI_TBD, NULL, NULL, "[ICMB] Send ICMB Connection ID", 0 },
/* Discovery Commands (ICMB) */
{ 0x10, IPMI_TBD, NULL, NULL, "[ICMB] Prepare For Discovery", 0 },
{ 0x11, IPMI_TBD, NULL, NULL, "[ICMB] Get Addresses", 0 },
{ 0x12, IPMI_TBD, NULL, NULL, "[ICMB] Set Discovered", 0 },
{ 0x13, IPMI_TBD, NULL, NULL, "[ICMB] Get Chassis Device ID", 0 },
{ 0x14, IPMI_TBD, NULL, NULL, "[ICMB] Set Chassis Device ID", 0 },
/* Bridging Commands (ICMB) */
{ 0x20, IPMI_TBD, NULL, NULL, "[ICMB] Bridge Request", 0 },
{ 0x21, IPMI_TBD, NULL, NULL, "[ICMB] Bridge Message", 0 },
/* Event Commands (ICMB) */
{ 0x30, IPMI_TBD, NULL, NULL, "[ICMB] Get Event Count", 0 },
{ 0x31, IPMI_TBD, NULL, NULL, "[ICMB] Set Event Destination", 0 },
{ 0x32, IPMI_TBD, NULL, NULL, "[ICMB] Set Event Reception State", 0 },
{ 0x33, IPMI_TBD, NULL, NULL, "[ICMB] Send ICMB Event Message", 0 },
{ 0x34, IPMI_TBD, NULL, NULL, "[ICMB] Get Event Destination", 0 },
{ 0x35, IPMI_TBD, NULL, NULL, "[ICMB] Get Event Reception State", 0 },
/* OEM Commands for Bridge NetFn */
{ 0xc0, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xc1, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xc2, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xc3, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xc4, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xc5, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xc6, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xc7, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xc8, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xc9, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xca, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xcb, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xcc, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xcd, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xce, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xcf, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xd0, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xd1, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xd2, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xd3, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xd4, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xd5, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xd6, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xd7, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xd8, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xd9, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xda, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xdb, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xdc, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xdd, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xde, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xdf, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xe0, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xe1, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xe2, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xe3, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xe4, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xe5, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xe6, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xe7, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xe8, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xe9, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xea, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xeb, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xec, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xed, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xee, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xef, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xf0, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xf1, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xf2, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xf3, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xf4, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xf5, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xf6, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xf7, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xf8, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xf9, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xfa, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xfb, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xfc, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xfd, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
{ 0xfe, IPMI_TBD, NULL, NULL, "[ICMB] OEM Command", 0 },
/* Other Bridge Commands */
{ 0xff, IPMI_TBD, NULL, NULL, "[ICMB] Error Report", 0 },
};
void
ipmi_register_bridge(gint proto_ipmi _U_)
{
ipmi_register_netfn_cmdtab(IPMI_BRIDGE_REQ, IPMI_OEM_NONE, NULL, 0, NULL,
cmd_bridge, array_length(cmd_bridge));
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,104 @@
/* packet-ipmi-pps.c
* Sub-dissectors for IPMI messages (netFn=OEM/Group, defining body = PPS)
* Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <epan/packet.h>
#include "packet-ipmi.h"
static ipmi_cmd_t cmd_pps[] = {
{ 0x00, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Status", 0 },
{ 0x01, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Serial Interface Properties", 0 },
{ 0x02, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Serial Interface Properties", 0 },
{ 0x03, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Debug Level", 0 },
{ 0x04, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Debug Level", 0 },
{ 0x05, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Hardware Address", 0 },
{ 0x06, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Hardware Address", 0 },
{ 0x07, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Handle Switch", 0 },
{ 0x08, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Handle Switch", 0 },
{ 0x09, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Payload Communication Timeout", 0 },
{ 0x0a, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Payload Communication Timeout", 0 },
{ 0x0b, IPMI_TBD, NULL, NULL, "[PPS OEM] Enable Payload Control", 0 },
{ 0x0c, IPMI_TBD, NULL, NULL, "[PPS OEM] Disable Payload Control", 0 },
{ 0x0d, IPMI_TBD, NULL, NULL, "[PPS OEM] Reset IPMC", 0 },
{ 0x0e, IPMI_TBD, NULL, NULL, "[PPS OEM] Hang IPMC", 0 },
{ 0x0f, IPMI_TBD, NULL, NULL, "[PPS OEM] Bused Resource Control", 0 },
{ 0x10, IPMI_TBD, NULL, NULL, "[PPS OEM] Bused Resource Status", 0 },
{ 0x11, IPMI_TBD, NULL, NULL, "[PPS OEM] Graceful Reset", 0 },
{ 0x12, IPMI_TBD, NULL, NULL, "[PPS OEM] Diagnostic Interrupt Results", 0 },
{ 0x13, IPMI_TBD, NULL, NULL, "[PPS OEM] Set/Clear Telco Alarm", 0 },
{ 0x14, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Telco Alarm Sensor Number", 0 },
{ 0x15, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Payload Shutdown Timeout", 0 },
{ 0x16, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Payload Shutdown Timeout", 0 },
{ 0x17, IPMI_TBD, NULL, NULL, "[PPS OEM] Switch over Serial Debug", 0 },
{ 0x18, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Local FRU LED State", 0 },
{ 0x19, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Local FRU LED State", 0 },
{ 0x1a, IPMI_TBD, NULL, NULL, "[PPS OEM] Update Discrete Sensor", 0 },
{ 0x1b, IPMI_TBD, NULL, NULL, "[PPS OEM] Update Threshold Sensor", 0 },
{ 0x1c, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Prepare", 0 },
{ 0x1d, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Write", 0 },
{ 0x1e, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Complete", 0 },
{ 0x1f, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Start", 0 },
{ 0x20, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Stop", 0 },
{ 0x21, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Resume", 0 },
{ 0x22, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Script Cease", 0 },
{ 0x23, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Sensor Set", 0 },
{ 0x24, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Notify", 0 },
{ 0x25, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Get FRU State", 0 },
{ 0x26, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Invalidate Hardware Address", 0 },
{ 0x27, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Module Status", 0 },
{ 0x28, IPMI_TBD, NULL, NULL, "[PPS OEM] Enable AMC Site", 0 },
{ 0x29, IPMI_TBD, NULL, NULL, "[PPS OEM] Disable AMC Site", 0 },
{ 0x2a, IPMI_TBD, NULL, NULL, "[PPS OEM] BTI Wait for Payload Notify", 0 },
{ 0x2b, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Test Flags", 0 },
{ 0x2c, IPMI_TBD, NULL, NULL, "[PPS OEM] Get Geographic Address", 0 },
{ 0x2d, IPMI_TBD, NULL, NULL, "[PPS OEM] Set Geographic Address", 0 },
{ 0x30, IPMI_TBD, NULL, NULL, "[PPS OEM] Set EEPROM Sensor Data", 0 },
{ 0x31, IPMI_TBD, NULL, NULL, "[PPS OEM] Set EEPROM Sensor Hysteresis", 0 },
{ 0x32, IPMI_TBD, NULL, NULL, "[PPS OEM] Set EEPROM Sensor Threshold", 0 },
{ 0x33, IPMI_TBD, NULL, NULL, "[PPS OEM] Reset EEPROM SDR Repository", 0 },
{ 0x34, IPMI_TBD, NULL, NULL, "[PPS OEM] Backend Power Control", 0 },
{ 0x35, IPMI_TBD, NULL, NULL, "[PPS OEM] Read CPLD Register", 0 },
{ 0x36, IPMI_TBD, NULL, NULL, "[PPS OEM] Write CPLD Register", 0 }
};
void
ipmi_register_pps(gint proto_ipmi _U_)
{
static guint8 sig_pps[3] = { 0x0a, 0x40, 0x00 };
static guint8 sig_pps_rev[3] = { 0x00, 0x40, 0x0a };
ipmi_register_netfn_cmdtab(IPMI_OEM_REQ, IPMI_OEM_NONE, sig_pps, 3,
"Pigeon Point Systems", cmd_pps, array_length(cmd_pps));
ipmi_register_netfn_cmdtab(IPMI_OEM_REQ, IPMI_OEM_NONE, sig_pps_rev, 3,
"Pigeon Point Systems (reversed)", cmd_pps, array_length(cmd_pps));
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,333 @@
/* packet-ipmi-session.c
* Routines for dissection of IPMI session wrapper (v1.5 and v2.0)
* Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com>
* Copyright Duncan Laurie <duncan@sun.com>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* Partially copied from packet-ipmi.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <glib.h>
#include <epan/packet.h>
#define RMCP_CLASS_IPMI 0x07
static int proto_ipmi_session = -1;
static gint ett_ipmi_session = -1;
static gint ett_ipmi_session_payloadtype = -1;
/* IPMI session header */
static int hf_ipmi_session_id = -1;
static int hf_ipmi_session_authtype = -1;
static int hf_ipmi_session_payloadtype = -1;
static int hf_ipmi_session_payloadtype_auth = -1;
static int hf_ipmi_session_payloadtype_enc = -1;
static int hf_ipmi_session_oem_iana = -1;
static int hf_ipmi_session_oem_payload_id = -1;
static int hf_ipmi_session_sequence = -1;
static int hf_ipmi_session_authcode = -1;
static int hf_ipmi_session_msg_len_1b = -1;
static int hf_ipmi_session_msg_len_2b = -1;
static int hf_ipmi_session_trailer = -1;
static dissector_handle_t ipmi_handle;
static dissector_handle_t data_handle;
#define IPMI_AUTH_NONE 0x00
#define IPMI_AUTH_MD2 0x01
#define IPMI_AUTH_MD5 0x02
#define IPMI_AUTH_PASSWORD 0x04
#define IPMI_AUTH_OEM 0x05
#define IPMI_AUTH_RMCPP 0x06
static const value_string ipmi_authtype_vals[] = {
{ IPMI_AUTH_NONE, "NONE" },
{ IPMI_AUTH_MD2, "MD2" },
{ IPMI_AUTH_MD5, "MD5" },
{ IPMI_AUTH_PASSWORD, "PASSWORD" },
{ IPMI_AUTH_OEM, "OEM" },
{ IPMI_AUTH_RMCPP, "RMCP+"},
{ 0x00, NULL }
};
#define IPMI_IPMI_MESSAGE 0
#define IPMI_OEM_EXPLICIT 2
static const value_string ipmi_payload_vals[] = {
{ IPMI_IPMI_MESSAGE, "IPMI Message" },
{ 0x01, "SOL (serial over LAN)" },
{ IPMI_OEM_EXPLICIT, "OEM Explicit" },
/* Session Setup Payload Types */
{ 0x10, "RMCP+ Open Session Request" },
{ 0x11, "RMCP+ Open Session Response" },
{ 0x12, "RAKP Message 1" },
{ 0x13, "RAKP Message 2" },
{ 0x14, "RAKP Message 3" },
{ 0x15, "RAKP Message 4" },
/* OEM Payload Type Handles */
{ 0x20, "OEM0 (OEM Payload)" },
{ 0x21, "OEM1 (OEM Payload)" },
{ 0x22, "OEM2 (OEM Payload)" },
{ 0x23, "OEM3 (OEM Payload)" },
{ 0x24, "OEM4 (OEM Payload)" },
{ 0x25, "OEM5 (OEM Payload)" },
{ 0x26, "OEM6 (OEM Payload)" },
{ 0x27, "OEM7 (OEM Payload)" },
{ 0x00, NULL }
};
static const true_false_string ipmi_payload_aut_val = {
"Payload is authenticated",
"Payload is unauthenticated"
};
static const true_false_string ipmi_payload_enc_val = {
"Payload is encrypted",
"Payload is unencrypted"
};
static void
dissect_ipmi_session(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *sess_tree = NULL, *s_tree;
proto_item *ti = NULL;
tvbuff_t *next_tvb;
guint32 session_id;
guint8 authtype, payloadtype = 0;
guint32 msg_start, msg_len, offset = 0;
gboolean payloadtype_auth = 0, payloadtype_enc = 0;
/* session authtype, 0=no authcode present, 6=RMCP+ */
authtype = tvb_get_guint8(tvb, 0);
if (authtype == IPMI_AUTH_RMCPP) {
/* Fetch additional info before trying to interpret
the packet. It may not be IPMI at all! */
payloadtype = tvb_get_guint8(tvb, 1);
payloadtype_auth = (payloadtype >> 6) & 1;
payloadtype_enc = (payloadtype >> 7);
payloadtype &= 0x3f;
/* IPMI v2.0 packets have session ID BEFORE the session
sequence number; just after authentification and payload
types. The OEM Explicit payload type has 6 more bytes
(IANA + Payload ID) before the session ID. */
if (payloadtype == IPMI_OEM_EXPLICIT) {
session_id = tvb_get_letohl(tvb, 8);
msg_start = 18;
msg_len = tvb_get_letohs(tvb, 16);
} else {
session_id = tvb_get_letohl(tvb, 2);
msg_start = 12;
msg_len = tvb_get_letohs(tvb, 10);
}
} else {
/* IPMI v1.5 packets have session ID AFTER the session
sequence number. They also have 1 byte for payload
message length. */
session_id = tvb_get_letohl(tvb, 5);
if (authtype == IPMI_AUTH_NONE) {
msg_start = 10;
msg_len = tvb_get_guint8(tvb, 9);
} else {
msg_start = 26;
msg_len = tvb_get_guint8(tvb, 25);
}
}
/* Later it will be overridden with sub-dissector, if any */
if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
if (authtype == IPMI_AUTH_RMCPP) {
col_set_str(pinfo->cinfo, COL_PROTOCOL, "RMCP+");
} else {
col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPMI");
}
}
if (check_col(pinfo->cinfo, COL_INFO)) {
col_clear(pinfo->cinfo, COL_INFO);
col_add_fstr(pinfo->cinfo, COL_INFO, "Session ID 0x%x", session_id);
if (authtype == IPMI_AUTH_RMCPP) {
col_append_fstr(pinfo->cinfo, COL_INFO, ", payload type: %s",
val_to_str(payloadtype, ipmi_payload_vals, "Unknown"));
}
}
if (tree) {
offset = 0;
ti = proto_tree_add_protocol_format(tree, proto_ipmi_session,
tvb, 0, tvb_length(tvb),
"IPMI v%s Session Wrapper, session ID 0x%x",
authtype == IPMI_AUTH_RMCPP ? "2.0+" : "1.5",
session_id);
sess_tree = proto_item_add_subtree(ti, ett_ipmi_session);
proto_tree_add_item(sess_tree, hf_ipmi_session_authtype, tvb, offset, 1, TRUE);
offset++;
if (authtype == IPMI_AUTH_RMCPP) {
/* IPMI v2.0+ */
ti = proto_tree_add_text(sess_tree, tvb, offset, 1,
"Payload type: %s (0x%02x), %sencrypted, %sauthenticated",
val_to_str(payloadtype, ipmi_payload_vals, "Unknown"),
payloadtype,
payloadtype_enc ? "" : "not ",
payloadtype_auth ? "" : "not ");
s_tree = proto_item_add_subtree(ti, ett_ipmi_session_payloadtype);
proto_tree_add_item(s_tree, hf_ipmi_session_payloadtype_enc, tvb, offset, 1, TRUE);
proto_tree_add_item(s_tree, hf_ipmi_session_payloadtype_auth, tvb, offset, 1, TRUE);
proto_tree_add_item(s_tree, hf_ipmi_session_payloadtype, tvb, offset, 1, TRUE);
offset++;
if (payloadtype == IPMI_OEM_EXPLICIT) {
proto_tree_add_item(sess_tree, hf_ipmi_session_oem_iana, tvb, offset, 4, TRUE);
offset += 4;
proto_tree_add_item(sess_tree, hf_ipmi_session_oem_payload_id, tvb, offset, 2, TRUE);
offset += 2;
}
proto_tree_add_item(sess_tree, hf_ipmi_session_id, tvb, offset, 4, TRUE);
offset += 4;
proto_tree_add_item(sess_tree, hf_ipmi_session_sequence, tvb, offset, 4, TRUE);
offset += 4;
proto_tree_add_item(sess_tree, hf_ipmi_session_msg_len_2b, tvb, offset, 2, TRUE);
offset += 2;
} else {
/* IPMI v1.5 */
proto_tree_add_item(sess_tree, hf_ipmi_session_sequence, tvb, offset, 4, TRUE);
offset += 4;
proto_tree_add_item(sess_tree, hf_ipmi_session_id, tvb, offset, 4, TRUE);
offset += 4;
if (authtype != IPMI_AUTH_NONE) {
proto_tree_add_item(sess_tree, hf_ipmi_session_authcode,
tvb, offset, 16, TRUE);
offset += 16;
}
proto_tree_add_item(sess_tree, hf_ipmi_session_msg_len_1b, tvb, offset, 1, TRUE);
offset++;
}
}
/* If we can parse the embedded message, do so */
next_tvb = tvb_new_subset(tvb, msg_start, msg_len, -1);
if (payloadtype_enc) {
/* This is RMCP+, and payload is encrypted. In this case,
there is a 'confidentiality header/trailer', whose lengths
are unknown to us. These lengths are negotiated during
session open process and are retained over a session.
Since we are stateless (and more, we may have no session
open packet in the capture we parse), we cannot even
decipher where a message starts. Just print them as data.
*/
call_dissector(data_handle, next_tvb, pinfo, tree);
} else if (authtype != IPMI_AUTH_RMCPP || payloadtype == IPMI_IPMI_MESSAGE) {
/* This is an IPMI message, either v1.5 or v2.0+. For now,
we don't need to distinguish these kinds. */
call_dissector(ipmi_handle, next_tvb, pinfo, tree);
} else {
/* All other RMCP+ payload types fall here: session open/close
requests, RAKP messages, SOL. We cannot parse them yet, thus
just output as data. */
call_dissector(data_handle, next_tvb, pinfo, tree);
}
if (tree) {
/* Account for the message we just parsed. */
offset += msg_len;
/* Show the rest of the session wrapper as binary data */
if (offset < tvb_length(tvb)) {
proto_tree_add_item(sess_tree, hf_ipmi_session_trailer,
tvb, offset, tvb_length(tvb) - offset, TRUE);
}
}
}
void
proto_register_ipmi_session(void)
{
static hf_register_info hf[] = {
{ &hf_ipmi_session_authtype, {
"Authentication Type", "ipmi.session.authtype",
FT_UINT8, BASE_HEX, VALS(ipmi_authtype_vals), 0, "", HFILL }},
{ &hf_ipmi_session_payloadtype,{
"Payload Type", "ipmi.session.payloadtype",
FT_UINT8, BASE_HEX, VALS(ipmi_payload_vals), 0x3f, "", HFILL }},
{ &hf_ipmi_session_payloadtype_auth,{
"Authenticated","ipmi.session.payloadtype.auth",
FT_BOOLEAN,8, TFS(&ipmi_payload_aut_val), 0x40, "", HFILL }},
{ &hf_ipmi_session_payloadtype_enc,{
"Encryption","ipmi.session.payloadtype.enc",
FT_BOOLEAN,8, TFS(&ipmi_payload_enc_val), 0x80, "", HFILL }},
{ &hf_ipmi_session_oem_iana, {
"OEM IANA", "ipmi.session.oem.iana",
FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }},
{ &hf_ipmi_session_oem_payload_id, {
"OEM Payload ID", "ipmi.session.oem.payloadid",
FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }},
{ &hf_ipmi_session_sequence, {
"Session Sequence Number", "ipmi.session.sequence",
FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }},
{ &hf_ipmi_session_id, {
"Session ID", "ipmi.session.id",
FT_UINT32, BASE_HEX, NULL, 0, "", HFILL }},
{ &hf_ipmi_session_authcode, {
"Authentication Code", "ipmi.session.authcode",
FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }},
{ &hf_ipmi_session_msg_len_1b, {
"Message Length", "ipmi.msg.len",
FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_ipmi_session_msg_len_2b, {
"Message Length", "ipmi.msg.len",
FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }},
{ &hf_ipmi_session_trailer, {
"IPMI Session Wrapper (trailer)", "ipmi.sess.trailer",
FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }},
};
static gint *ett[] = { &ett_ipmi_session, &ett_ipmi_session_payloadtype };
proto_ipmi_session = proto_register_protocol(
"Intelligent Platform Management Interface (Session Wrapper)", "IPMI Session",
"ipmi-session");
proto_register_field_array(proto_ipmi_session, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_ipmi_session(void)
{
static gboolean inited = FALSE;
if (!inited) {
dissector_handle_t ipmi_session_handle;
ipmi_session_handle = create_dissector_handle(dissect_ipmi_session, proto_ipmi_session);
dissector_add("rmcp.class", RMCP_CLASS_IPMI, ipmi_session_handle);
data_handle = find_dissector("data");
ipmi_handle = find_dissector("ipmi");
inited = TRUE;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
/* packet-ipmi-update.c
* Sub-dissectors for IPMI messages (netFn=Firmware Update, PPS-specific)
* Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <epan/packet.h>
#include "packet-ipmi.h"
static ipmi_cmd_t cmd_update[] = {
{ 0x00, IPMI_TBD, NULL, NULL, "[PPS OEM] Upgrade Status", 0 },
{ 0x01, IPMI_TBD, NULL, NULL, "[PPS OEM] Upgrade Start", 0 },
{ 0x02, IPMI_TBD, NULL, NULL, "[PPS OEM] Upgrade Prepare", 0 },
{ 0x03, IPMI_TBD, NULL, NULL, "[PPS OEM] Upgrade Write", 0 },
{ 0x04, IPMI_TBD, NULL, NULL, "[PPS OEM] Upgrade Complete", 0 },
{ 0x05, IPMI_TBD, NULL, NULL, "[PPS OEM] Restore Backup", 0 },
{ 0x06, IPMI_TBD, NULL, NULL, "[PPS OEM] Query Backup Version", 0 }
};
void
ipmi_register_update(gint proto_ipmi _U_)
{
ipmi_register_netfn_cmdtab(IPMI_UPDATE_REQ, IPMI_OEM_PPS, NULL, 0, NULL,
cmd_update, array_length(cmd_update));
}

View File

@ -0,0 +1,186 @@
/* packet-ipmi.h
* Definitions for IPMI dissection
* Copyright 2002-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __PACKET_IPMI_H__
#define __PACKET_IPMI_H__
/* IPMI definitions */
/* Max 32 netfn codes: 6 bits, of which 1 designates request/response */
#define IPMI_NETFN_MAX 32
/* IPMI Network Function supported values.
*/
#define IPMI_CHASSIS_REQ 0x00 /* Chassis */
#define IPMI_BRIDGE_REQ 0x02 /* Bridge */
#define IPMI_SE_REQ 0x04 /* Sensor/Event */
#define IPMI_APP_REQ 0x06 /* Application */
#define IPMI_UPDATE_REQ 0x08 /* Firmware update */
#define IPMI_STORAGE_REQ 0x0a /* Storage */
#define IPMI_TRANSPORT_REQ 0x0c /* Transport */
#define IPMI_GROUP_REQ 0x2c /* Group */
#define IPMI_OEM_REQ 0x2e /* OEM */
/* Selector for dissecting OEM commands which do not carry OEM signatures.
* IPMI spec says these commands are to be specified by OEM and depend on
* the IANA number reported via Get Device ID. However, Wireshark has no
* means to guess that. Therefore, allow the user to select which OEM commands
* should be used. This applies to the following netFns: 0x08/0x09 (Update),
* 0x30..0x3f. Note that the commands which bear defining body signature
* (netFns 0x2c..0x2f) are registered with IPMI_OEM_NONE, as they can be
* recognized. */
enum ipmi_oem_selector {
IPMI_OEM_NONE = 0,
IPMI_OEM_PPS /* Pigeon Point Systems extensions */
};
/* IPMI header fields */
struct ipmi_header {
guint8 trg_sa;
guint8 trg_lun;
guint8 src_sa;
guint8 src_lun;
guint8 netfn;
guint8 cmd;
guint8 seq;
guint8 ccode;
guint8 data_len;
};
extern struct ipmi_header *ipmi_current_hdr;
/* Sub-parser */
typedef void (*ipmi_cmd_handler_t)(tvbuff_t *, proto_tree *);
/* IPMI command structure. */
typedef struct {
guint32 cmd; /* Command number */
ipmi_cmd_handler_t parse_req; /* Request parser */
ipmi_cmd_handler_t parse_resp; /* Response parser */
const value_string *cs_cc; /* Command-specific completion codes */
const value_string *subfn; /* Subfunction codes */
const char *desc; /* Command description */
int flags; /* Command flags */
} ipmi_cmd_t;
/* Command flags */
#define CMD_MAYBROADCAST 0x01 /* Command can be broadcast over IPMB */
#define CMD_CALLRQ 0x02 /* Call request handler early to cache data */
#define CMD_NEWCONV 0x04 /* This command starts new conversation */
void ipmi_setsaveddata(guint idx, guint32 val);
gboolean ipmi_getsaveddata(guint idx, guint32 *val);
/* Top-level search structure: signatures (if any) + command table */
typedef struct ipmi_netfn_handler {
struct ipmi_netfn_handler *next;
const char *desc;
enum ipmi_oem_selector oem_selector;
const guint8 *sig;
ipmi_cmd_t *cmdtab;
guint32 cmdtablen;
} ipmi_netfn_t;
/* Handy wrapper around decode_bitfield_value() */
char *ipmi_dcd8(guint32 val, guint32 mask);
/* Stub parser. Use this to substitute for not-yet-written subparsers;
NULL in command table means 'no custom data in this request/response' */
void ipmi_notimpl(tvbuff_t *tvb, proto_tree *tree);
#define IPMI_TBD ipmi_notimpl, ipmi_notimpl
/* Add a Type/Length field to tree */
void ipmi_add_typelen(proto_tree *tree, const char *desc, tvbuff_t *tvb,
guint offs, gboolean is_fru);
/* Add Timestamp in IPMI format */
void ipmi_add_timestamp(proto_tree *tree, gint hf, tvbuff_t *tvb, guint offset);
/* GUID, IPMI style (fields reversed, little-endian) */
void ipmi_add_guid(proto_tree *tree, gint hf, tvbuff_t *tvb, guint offset);
/* Common format routines */
void ipmi_fmt_10ms_1based(gchar *, guint32);
void ipmi_fmt_500ms_0based(gchar *, guint32);
void ipmi_fmt_500ms_1based(gchar *, guint32);
void ipmi_fmt_1s_0based(gchar *, guint32);
void ipmi_fmt_1s_1based(gchar *, guint32);
void ipmi_fmt_2s_0based(gchar *, guint32);
void ipmi_fmt_5s_1based(gchar *, guint32);
void ipmi_fmt_version(gchar *, guint32);
void ipmi_fmt_channel(gchar *, guint32);
void ipmi_fmt_udpport(gchar *, guint32);
void ipmi_fmt_percent(gchar *, guint32);
/* Registrar for subparsers */
void ipmi_register_netfn_cmdtab(guint32 netfn, enum ipmi_oem_selector oem_selector,
const guint8 *sig, guint32 siglen, const char *desc,
ipmi_cmd_t *cmdtab, guint32 cmdtablen);
/* Lookup routines */
guint32 ipmi_getsiglen(guint32 netfn);
const char *ipmi_getnetfnname(guint32 netfn, ipmi_netfn_t *nf);
ipmi_netfn_t *ipmi_getnetfn(guint32 netfn, const guint8 *sig);
ipmi_cmd_t *ipmi_getcmd(ipmi_netfn_t *nf, guint32 cmd);
const char *ipmi_get_completion_code(guint8 completion, ipmi_cmd_t *cmd);
/* Sub-registrars (ipmi_*.c) */
void ipmi_register_app(int proto);
void ipmi_register_bridge(int proto);
void ipmi_register_chassis(int proto);
void ipmi_register_picmg(int proto);
void ipmi_register_pps(int proto);
void ipmi_register_se(int proto);
void ipmi_register_storage(int proto);
void ipmi_register_transport(int proto);
void ipmi_register_update(int proto);
/* Main dissection routine */
#define IPMI_D_NONE 0x0001 /* Do not parse at all */
#define IPMI_D_SESSION_HANDLE 0x0002 /* Session handle */
#define IPMI_D_BROADCAST 0x0004 /* Check for broadcast message */
#define IPMI_D_TRG_SA 0x0008 /* Target slave addr is present */
struct ipmi_reqresp;
typedef struct {
guint32 flags;
gchar info[ITEM_LABEL_LENGTH];
void *arg; /* Argument passed to callbacks */
/* Extra methods for requests that contain embedded commands */
struct ipmi_header *(*getmoreheaders)(struct ipmi_header *base, void *arg, guint i);
int (*whichresponse)(struct ipmi_header *hdr, struct ipmi_reqresp *rr);
int (*otheridx)(struct ipmi_header *hdr);
} ipmi_dissect_format_t;
int ipmi_guess_dissect_flags(tvbuff_t *tvb);
void ipmi_do_dissect(tvbuff_t *tvb, proto_tree *tree, ipmi_dissect_format_t *dfmt);
struct ipmi_header *ipmi_sendmsg_getheaders(struct ipmi_header *base, void *arg, guint i);
int ipmi_sendmsg_whichresponse(struct ipmi_header *hdr, struct ipmi_reqresp *rr);
int ipmi_sendmsg_otheridx(struct ipmi_header *hdr);
#endif