summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ipmi.h
blob: 28070aeac548304ed37f5dab7d55e08cc3a1856b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/* packet-ipmi.h
 * Definitions for IPMI dissection
 * Copyright 2002-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com>
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@wireshark.org>
 * Copyright 1998 Gerald Combs
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#ifndef __PACKET_IPMI_H__
#define __PACKET_IPMI_H__

#include <epan/expert.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_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(packet_info *pinfo, 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(packet_info *pinfo, 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(wmem_allocator_t *pool, 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  -  https://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:
 */