/* packet-ipmi.h * Definitions for IPMI dissection * Copyright 2002-2008, Alexey Neyman, Pigeon Point Systems * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef __PACKET_IPMI_H__ #define __PACKET_IPMI_H__ #include /* 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_NONE = 0, IPMI_OEM_PPS /* Pigeon Point Systems extensions */ }; /* * Command context (environment). */ enum { IPMI_E_NONE, /* no surround environment */ IPMI_E_SENDMSG_RQ, /* encapsulated into Send Message request */ IPMI_E_SENDMSG_RS, /* encapsulated into Send Message response */ IPMI_E_GETMSG /* encapsulated into Get Message response */ }; /* * Cached IPMI message header. */ typedef struct { guint8 context; guint8 channel; guint8 dir; guint8 session; guint8 rs_sa; guint8 rs_lun; guint8 netfn; guint8 rq_sa; guint8 rq_lun; guint8 rq_seq; guint8 cmd; } ipmi_header_t; /* Sub-parser */ typedef void (*ipmi_cmd_handler_t)(tvbuff_t *, packet_info *, 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_CALLRQ 0x02 /* Call request handler early to cache data */ /* Get currently parsed message header */ const ipmi_header_t * ipmi_get_hdr(packet_info * pinfo); /* Get completion code for currently parsed message */ guint8 ipmi_get_ccode(packet_info * pinfo); /* Save request data for later use in response */ void ipmi_set_data(packet_info *pinfo, guint idx, guint32 data); /* Get saved request data */ gboolean ipmi_get_data(packet_info *pinfo, guint idx, guint32 * data); /* Top-level search structure: signatures (if any) + command table */ typedef struct ipmi_netfn_handler { struct ipmi_netfn_handler *next; const char *desc; guint oem_selector; const guint8 *sig; ipmi_cmd_t *cmdtab; guint32 cmdtablen; } ipmi_netfn_t; /* 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, packet_info *pinfo, proto_tree *tree); #define IPMI_TBD ipmi_notimpl, ipmi_notimpl /* Add a Type/Length field to tree */ void ipmi_add_typelen(proto_tree *tree, int hf_string, int hf_type, int hf_length, 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, guint 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); /* Used for sub-registrars (ipmi_*.c) */ extern gint proto_ipmi; /* 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 */ #define IPMI_D_TMODE 0x0010 /* Bridged field instead of Rq LUN */ #define IPMI_D_NO_CKS 0x0020 /* Checksum bytes are not present */ #define IPMI_D_NO_RQ_SA 0x0040 /* RQ SA is not present */ #define IPMI_D_NO_SEQ 0x0080 /* RQ Seq is not present */ /* IPMI dissector argument */ typedef struct { guint8 context; guint8 channel; guint8 flags; } ipmi_dissect_arg_t; int do_dissect_ipmb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint hf_parent_item, gint ett_tree, ipmi_dissect_arg_t * arg); #endif /* __PACKET_IPMI_H__ */ /* * Editor modelines - http://www.wireshark.org/tools/modelines.html * * Local variables: * c-basic-offset: 8 * tab-width: 8 * indent-tabs-mode: t * End: * * vi: set shiftwidth=8 tabstop=8 noexpandtab: * :indentSize=8:tabSize=8:noTabs=false: */