1 /* packet-ipmi-chassis.c
2  * Sub-dissectors for IPMI messages (netFn=Chassis)
3  * Copyright 2007-2008, Alexey Neyman, Pigeon Point Systems <avn@pigeonpoint.com>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 #include "config.h"
13 
14 #include <epan/packet.h>
15 
16 #include "packet-ipmi.h"
17 
18 void proto_register_ipmi_chassis(void);
19 
20 /* Local variables.
21  */
22 static gint ett_ipmi_chs_bo00_byte1 = -1;
23 static gint ett_ipmi_chs_bo02_byte1 = -1;
24 static gint ett_ipmi_chs_bo03_byte1 = -1;
25 static gint ett_ipmi_chs_bo04_byte2 = -1;
26 static gint ett_ipmi_chs_bo05_byte1 = -1;
27 static gint ett_ipmi_chs_bo05_byte2 = -1;
28 static gint ett_ipmi_chs_bo05_byte3 = -1;
29 static gint ett_ipmi_chs_bo05_byte4 = -1;
30 static gint ett_ipmi_chs_bo06_byte1 = -1;
31 
32 static gint ett_ipmi_chs_00_capflags = -1;
33 static gint ett_ipmi_chs_01_pwr_state = -1;
34 static gint ett_ipmi_chs_01_last_event = -1;
35 static gint ett_ipmi_chs_01_misc = -1;
36 static gint ett_ipmi_chs_01_fpb = -1;
37 static gint ett_ipmi_chs_02_byte1 = -1;
38 static gint ett_ipmi_chs_04_byte2 = -1;
39 static gint ett_ipmi_chs_05_flags = -1;
40 static gint ett_ipmi_chs_06_byte1 = -1;
41 static gint ett_ipmi_chs_06_policy_support = -1;
dissect_iperf2(tvbuff_t * tvb,proto_tree * iperf2_tree,guint32 offset)42 static gint ett_ipmi_chs_07_byte1 = -1;
43 static gint ett_ipmi_chs_08_byte1 = -1;
44 static gint ett_ipmi_chs_09_rq_byte1 = -1;
45 static gint ett_ipmi_chs_09_rs_byte1 = -1;
46 static gint ett_ipmi_chs_09_rs_byte2 = -1;
47 
48 static gint hf_ipmi_chs_bo00_sip = -1;
49 static gint hf_ipmi_chs_bo01_spsel = -1;
50 static gint hf_ipmi_chs_bo02_request = -1;
51 static gint hf_ipmi_chs_bo02_discovered = -1;
52 static gint hf_ipmi_chs_bo03_pef = -1;
53 static gint hf_ipmi_chs_bo03_cctrl_timeout = -1;
54 static gint hf_ipmi_chs_bo03_wd_timeout = -1;
55 static gint hf_ipmi_chs_bo03_softreset = -1;
56 static gint hf_ipmi_chs_bo03_powerup = -1;
57 static gint hf_ipmi_chs_bo04_write_mask = -1;
58 static gint hf_ipmi_chs_bo04_bootinit_ack_oem = -1;
59 static gint hf_ipmi_chs_bo04_bootinit_ack_sms = -1;
60 static gint hf_ipmi_chs_bo04_bootinit_ack_os = -1;
61 static gint hf_ipmi_chs_bo04_bootinit_ack_osloader = -1;
62 static gint hf_ipmi_chs_bo04_bootinit_ack_bios = -1;
63 static gint hf_ipmi_chs_bo05_bootflags_valid = -1;
dissect_iperf2_tcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)64 static gint hf_ipmi_chs_bo05_permanent = -1;
65 static gint hf_ipmi_chs_bo05_boottype = -1;
66 static gint hf_ipmi_chs_bo05_cmos_clear = -1;
67 static gint hf_ipmi_chs_bo05_lock_kbd = -1;
68 static gint hf_ipmi_chs_bo05_bootdev = -1;
69 static gint hf_ipmi_chs_bo05_screen_blank = -1;
70 static gint hf_ipmi_chs_bo05_lockout_reset = -1;
71 static gint hf_ipmi_chs_bo05_lockout_poweroff = -1;
72 static gint hf_ipmi_chs_bo05_bios_verbosity = -1;
73 static gint hf_ipmi_chs_bo05_progress_traps = -1;
74 static gint hf_ipmi_chs_bo05_pwd_bypass = -1;
75 static gint hf_ipmi_chs_bo05_lock_sleep = -1;
76 static gint hf_ipmi_chs_bo05_console_redirection = -1;
77 static gint hf_ipmi_chs_bo05_bios_shared_override = -1;
78 static gint hf_ipmi_chs_bo05_bios_muxctl_override = -1;
79 static gint hf_ipmi_chs_bo05_byte5 = -1;
80 static gint hf_ipmi_chs_bo06_chan_num = -1;
81 static gint hf_ipmi_chs_bo06_session_id = -1;
82 static gint hf_ipmi_chs_bo06_bootinfo_timestamp = -1;
83 static gint hf_ipmi_chs_bo07_block_selector = -1;
84 static gint hf_ipmi_chs_bo07_block_data = -1;
85 
dissect_iperf2_udp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)86 static gint hf_ipmi_chs_00_capflags_ppi = -1;
87 static gint hf_ipmi_chs_00_capflags_di = -1;
88 static gint hf_ipmi_chs_00_capflags_fpl = -1;
89 static gint hf_ipmi_chs_00_capflags_is = -1;
90 static gint hf_ipmi_chs_00_fru_dev_addr = -1;
91 static gint hf_ipmi_chs_00_sdr_dev_addr = -1;
92 static gint hf_ipmi_chs_00_sel_dev_addr = -1;
93 static gint hf_ipmi_chs_00_sm_dev_addr = -1;
94 static gint hf_ipmi_chs_00_bridge_dev_addr = -1;
95 
96 static gint hf_ipmi_chs_01_pwr_state_policy = -1;
97 static gint hf_ipmi_chs_01_pwr_state_ctl_fault = -1;
98 static gint hf_ipmi_chs_01_pwr_state_fault = -1;
99 static gint hf_ipmi_chs_01_pwr_state_ilock = -1;
100 static gint hf_ipmi_chs_01_pwr_state_overload = -1;
101 static gint hf_ipmi_chs_01_pwr_state_powered = -1;
102 static gint hf_ipmi_chs_01_last_event_via_ipmi = -1;
103 static gint hf_ipmi_chs_01_last_event_down_by_fault = -1;
104 static gint hf_ipmi_chs_01_last_event_interlock = -1;
105 static gint hf_ipmi_chs_01_last_event_overload = -1;
106 static gint hf_ipmi_chs_01_last_event_ac_failed = -1;
107 static gint hf_ipmi_chs_01_misc_identsupp = -1;
108 static gint hf_ipmi_chs_01_misc_identstate = -1;
109 static gint hf_ipmi_chs_01_misc_fan = -1;
110 static gint hf_ipmi_chs_01_misc_drive = -1;
111 static gint hf_ipmi_chs_01_misc_fpl_active = -1;
112 static gint hf_ipmi_chs_01_misc_intrusion = -1;
proto_register_iperf2(void)113 static gint hf_ipmi_chs_01_fpb_standby_allowed = -1;
114 static gint hf_ipmi_chs_01_fpb_diagintr_allowed = -1;
115 static gint hf_ipmi_chs_01_fpb_reset_allowed = -1;
116 static gint hf_ipmi_chs_01_fpb_poweroff_allowed = -1;
117 static gint hf_ipmi_chs_01_fpb_standby_disabled = -1;
118 static gint hf_ipmi_chs_01_fpb_diagintr_disabled = -1;
119 static gint hf_ipmi_chs_01_fpb_reset_disabled = -1;
120 static gint hf_ipmi_chs_01_fpb_poweroff_disabled = -1;
121 
122 static gint hf_ipmi_chs_02_cctrl = -1;
123 
124 static gint hf_ipmi_chs_04_ival = -1;
125 static gint hf_ipmi_chs_04_perm_on = -1;
126 
127 static gint hf_ipmi_chs_05_flags_fpl = -1;
128 static gint hf_ipmi_chs_05_flags_intrusion = -1;
129 static gint hf_ipmi_chs_05_fru_dev_addr = -1;
130 static gint hf_ipmi_chs_05_sdr_dev_addr = -1;
131 static gint hf_ipmi_chs_05_sel_dev_addr = -1;
132 static gint hf_ipmi_chs_05_sm_dev_addr = -1;
133 static gint hf_ipmi_chs_05_bridge_dev_addr = -1;
134 
135 static gint hf_ipmi_chs_06_rq_policy = -1;
136 static gint hf_ipmi_chs_06_rs_policy_support_powerup = -1;
137 static gint hf_ipmi_chs_06_rs_policy_support_restore = -1;
138 static gint hf_ipmi_chs_06_rs_policy_support_poweroff = -1;
139 
140 static gint hf_ipmi_chs_07_cause = -1;
141 static gint hf_ipmi_chs_07_chan = -1;
142 
143 static gint hf_ipmi_chs_08_valid = -1;
144 static gint hf_ipmi_chs_08_selector = -1;
145 static gint hf_ipmi_chs_08_data = -1;
146 
147 static gint hf_ipmi_chs_09_rq_param_select = -1;
148 static gint hf_ipmi_chs_09_rq_set_select = -1;
149 static gint hf_ipmi_chs_09_rq_block_select = -1;
150 static gint hf_ipmi_chs_09_rs_param_version = -1;
151 static gint hf_ipmi_chs_09_rs_valid = -1;
152 static gint hf_ipmi_chs_09_rs_param_select = -1;
153 static gint hf_ipmi_chs_09_rs_param_data = -1;
154 
155 static gint hf_ipmi_chs_0f_minpercnt = -1;
156 static gint hf_ipmi_chs_0f_counter = -1;
157 
158 static const struct true_false_string tfs_00_provided = { "Provided", "Not Provided" };
159 
160 static const value_string vals_01_pwr_policy[] = {
161 	{ 0x00, "chassis stays powered off after AC returns" },
162 	{ 0x01, "after AC returns, power is restored to the state that was in effect when AC was lost" },
163 	{ 0x02, "chassis always powers up after AC returns" },
164 	{ 0x03, "unknown" },
165 	{ 0, NULL }
166 };
167 
168 static const value_string vals_01_identstate[] = {
169 	{ 0x00, "Off" },
170 	{ 0x01, "Temporary (timed) On" },
171 	{ 0x02, "On" },
172 	{ 0, NULL }
proto_reg_handoff_iperf2(void)173 };
174 
175 static const value_string vals_02_cctrl[] = {
176 	{ 0x00, "Power down" },
177 	{ 0x01, "Power up" },
178 	{ 0x02, "Power cycle" },
179 	{ 0x03, "Hard reset" },
180 	{ 0x04, "Pulse Diagnostic Interrupt" },
181 	{ 0x05, "Initiate a soft-shutdown of OS via ACPI by emulating a fatal overtemperature" },
182 	{ 0, NULL }
183 };
184 
185 static const value_string vals_06_policy[] = {
186 	{ 0x00, "Chassis always stays powered off after AC/mains is applied" },
187 	{ 0x01, "After AC/mains is applied or returns, power is restored to the state that was in effect when AC/mains was removed or lost" },
188 	{ 0x02, "Chassis always powers up after AC/mains is applied or returns" },
189 	{ 0x03, "No change (just get policy support)" },
190 	{ 0x04, "Reserved" },
191 	{ 0x05, "Reserved" },
192 	{ 0x06, "Reserved" },
193 	{ 0x07, "Reserved" },
194 	{ 0, NULL }
195 };
196 
197 static const struct true_false_string tfs_06_supported = { "Supported", "Not supported" };
198 
199 static const value_string vals_07_cause[] = {
200 	{ 0x00, "Unknown" },
201 	{ 0x01, "Chassis Control command" },
202 	{ 0x02, "Reset via pushbutton" },
203 	{ 0x03, "Power-up via pushbutton" },
204 	{ 0x04, "Watchdog expiration" },
205 	{ 0x05, "OEM" },
206 	{ 0x06, "Automatic power-up on AC being applied due to 'always restore' power restore policy" },
207 	{ 0x07, "Automatic power-up on AC being applied due to 'restore previous power state' power restore policy" },
208 	{ 0x08, "Reset via PEF" },
209 	{ 0x09, "Power-cycle via PEF" },
210 	{ 0x0a, "Soft reset" },
211 	{ 0x0b, "Power-up via RTC wakeup" },
212 	{ 0x0c, "Reserved" },
213 	{ 0x0d, "Reserved" },
214 	{ 0x0e, "Reserved" },
215 	{ 0x0f, "Reserved" },
216 	{ 0, NULL }
217 };
218 
219 static const value_string bo00_sip_vals[] = {
220 	{ 0x00, "Set complete" },
221 	{ 0x01, "Set in progress" },
222 	{ 0x02, "Commit write" },
223 	{ 0x03, "Reserved" },
224 	{ 0, NULL }
225 };
226 
227 static const struct true_false_string tfs_08_valid = {
228 	"Mark parameter invalid/locked",
229 	"Mark parameter valid/unlocked"
230 };
231 
232 static const struct true_false_string bo03_dontclear_tfs = {
233 	"don't clear",
234 	"clear"
235 };
236 
237 static const struct true_false_string bo04_bootinit_ack_tfs = {
238 	"has handled boot info",
239 	"hasn't handled boot info"
240 };
241 
242 static const struct true_false_string bo05_permanent_tfs = {
243 	"options requested to be persistent for all future boots",
244 	"options apply to next boot only"
245 };
246 
247 static const struct true_false_string bo05_boottype_tfs = {
248 	"Extensible Firmware Interface Boot (EFI)",
249 	"'PC compatible' boot (legacy)"
250 };
251 
252 static const value_string bo05_bootdev_vals[] = {
253 	{ 0x00, "No override" },
254 	{ 0x01, "Force PXE" },
255 	{ 0x02, "Force boot from default Hard-drive" },
256 	{ 0x03, "Force boot from default Hard-drive, request Safe Mode" },
257 	{ 0x04, "Force boot from default Diagnostic Partition" },
258 	{ 0x05, "Force boot from default CD/DVD" },
259 	{ 0x06, "Force boot into BIOS Setup" },
260 	{ 0x07, "Reserved" },
261 	{ 0x08, "Reserved" },
262 	{ 0x09, "Reserved" },
263 	{ 0x0a, "Reserved" },
264 	{ 0x0b, "Reserved" },
265 	{ 0x0c, "Reserved" },
266 	{ 0x0d, "Reserved" },
267 	{ 0x0e, "Reserved" },
268 	{ 0x0f, "Force boot from floppy/primary removable media" },
269 	{ 0, NULL }
270 };
271 
272 static const value_string bo05_bios_verbosity_vals[] = {
273 	{ 0x00, "System default" },
274 	{ 0x01, "Request quiet display" },
275 	{ 0x02, "Request verbose display" },
276 	{ 0x03, "Reserved" },
277 	{ 0, NULL }
278 };
279 
280 static const value_string bo05_console_redir_vals[] = {
281 	{ 0x00, "Console redirection occurs per BIOS configuration setting" },
282 	{ 0x01, "Suppress (skip) console redirection" },
283 	{ 0x02, "Request console redirection be enabled" },
284 	{ 0x03, "Reserved" },
285 	{ 0, NULL }
286 };
287 
288 static const struct true_false_string bo05_bios_shared_tfs = {
289 	"Request BIOS to temporarily set the access mode for the channel specified in parameter #6 to 'Shared'",
290 	"No request to BIOS to change present access mode setting"
291 };
292 
293 static const value_string bo05_bios_muxctl_vals[] = {
294 	{ 0x00, "BIOS uses recommended setting of the mux at the end of POST" },
295 	{ 0x01, "Requests BIOS to force mux to BMC at conclusion of POST/start of OS boot" },
296 	{ 0x02, "Requests BIOS to force mux to system at conclusion of POST/start of OSboot" },
297 	{ 0x03, "Reserved" },
298 	{ 0x04, "Reserved" },
299 	{ 0x05, "Reserved" },
300 	{ 0x06, "Reserved" },
301 	{ 0x07, "Reserved" },
302 	{ 0, NULL }
303 };
304 
305 static const struct true_false_string tfs_09_valid = {
306 	"Parameter marked invalid / locked",
307 	"Parameter marked valid / unlocked"
308 };
309 
310 /* Boot options - common for Get/Set Boot Options commands
311  */
312 static void
313 bootopt_00(packet_info *pinfo _U_, tvbuff_t *tvb, proto_tree *tree)
314 {
315 	static int * const byte1[] = { &hf_ipmi_chs_bo00_sip, NULL };
316 
317 	proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_chs_bo00_byte1, byte1,
318 			ENC_LITTLE_ENDIAN, 0);
319 }
320 
321 static void
322 bootopt_01(packet_info *pinfo _U_, tvbuff_t *tvb, proto_tree *tree)
323 {
324 	proto_tree_add_item(tree, hf_ipmi_chs_bo01_spsel, tvb, 0, 1, ENC_LITTLE_ENDIAN);
325 }
326 
327 static void
328 bootopt_02(packet_info *pinfo _U_, tvbuff_t *tvb, proto_tree *tree)
329 {
330 	static int * const byte1[] = { &hf_ipmi_chs_bo02_request, &hf_ipmi_chs_bo02_discovered, NULL };
331 
332 	proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Service partition scan: ",
333 			"Not discovered", ett_ipmi_chs_bo02_byte1, byte1, ENC_LITTLE_ENDIAN, 0);
334 }
335 
336 static void
337 bootopt_03(packet_info *pinfo _U_, tvbuff_t *tvb, proto_tree *tree)
338 {
339 	static int * const byte1[] = { &hf_ipmi_chs_bo03_pef, &hf_ipmi_chs_bo03_cctrl_timeout,
340 		&hf_ipmi_chs_bo03_wd_timeout, &hf_ipmi_chs_bo03_softreset, &hf_ipmi_chs_bo03_powerup, NULL };
341 
342 	proto_tree_add_bitmask_text(tree, tvb, 0, 1, "BMC boot flag valid, don't clear on: ",
343 			"None", ett_ipmi_chs_bo03_byte1, byte1, ENC_LITTLE_ENDIAN, BMT_NO_TFS);
344 }
345 
346 static void
347 bootopt_04(packet_info *pinfo _U_, tvbuff_t *tvb, proto_tree *tree)
348 {
349 	static int * const byte2[] = { &hf_ipmi_chs_bo04_bootinit_ack_oem, &hf_ipmi_chs_bo04_bootinit_ack_sms,
350 		&hf_ipmi_chs_bo04_bootinit_ack_os, &hf_ipmi_chs_bo04_bootinit_ack_osloader,
351 		&hf_ipmi_chs_bo04_bootinit_ack_bios, NULL };
352 
353 	proto_tree_add_item(tree, hf_ipmi_chs_bo04_write_mask, tvb, 0, 1, ENC_LITTLE_ENDIAN);
354 	proto_tree_add_bitmask_text(tree, tvb, 1, 1, "Boot Initiator Acknowledge data: ",
355 			"None", ett_ipmi_chs_bo04_byte2, byte2, ENC_LITTLE_ENDIAN, BMT_NO_TFS);
356 }
357 
358 static void
359 bootopt_05(packet_info *pinfo _U_, tvbuff_t *tvb, proto_tree *tree)
360 {
361 	static int * const byte1[] = { &hf_ipmi_chs_bo05_bootflags_valid,
362 		&hf_ipmi_chs_bo05_permanent, &hf_ipmi_chs_bo05_boottype, NULL };
363 	static int * const byte2[] = { &hf_ipmi_chs_bo05_cmos_clear, &hf_ipmi_chs_bo05_lock_kbd,
364 		&hf_ipmi_chs_bo05_bootdev, &hf_ipmi_chs_bo05_screen_blank, &hf_ipmi_chs_bo05_lockout_reset, NULL };
365 	static int * const byte3[] = { &hf_ipmi_chs_bo05_lockout_poweroff, &hf_ipmi_chs_bo05_bios_verbosity,
366 		&hf_ipmi_chs_bo05_progress_traps, &hf_ipmi_chs_bo05_pwd_bypass, &hf_ipmi_chs_bo05_lock_sleep,
367 		&hf_ipmi_chs_bo05_console_redirection, NULL };
368 	static int * const byte4[] = { &hf_ipmi_chs_bo05_bios_shared_override,
369 		&hf_ipmi_chs_bo05_bios_muxctl_override, NULL };
370 
371 	proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_chs_bo05_byte1,
372 			byte1, ENC_LITTLE_ENDIAN, 0);
373 	proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_chs_bo05_byte2,
374 			byte2, ENC_LITTLE_ENDIAN, 0);
375 	proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, ett_ipmi_chs_bo05_byte3,
376 			byte3, ENC_LITTLE_ENDIAN, 0);
377 	proto_tree_add_bitmask_text(tree, tvb, 3, 1, NULL, NULL, ett_ipmi_chs_bo05_byte4,
378 			byte4, ENC_LITTLE_ENDIAN, 0);
379 	proto_tree_add_item(tree, hf_ipmi_chs_bo05_byte5, tvb, 4, 1, ENC_LITTLE_ENDIAN);
380 }
381 
382 static void
383 bootopt_06(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree)
384 {
385 	static int * const byte1[] = { &hf_ipmi_chs_bo06_chan_num, NULL };
386 
387 	proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL,
388 			ett_ipmi_chs_bo06_byte1, byte1, ENC_LITTLE_ENDIAN, 0);
389 	proto_tree_add_item(tree, hf_ipmi_chs_bo06_session_id, tvb, 1, 4, ENC_LITTLE_ENDIAN);
390 	ipmi_add_timestamp(pinfo, tree, hf_ipmi_chs_bo06_bootinfo_timestamp, tvb, 5);
391 }
392 
393 static void
394 bootopt_07(packet_info *pinfo _U_, tvbuff_t *tvb, proto_tree *tree)
395 {
396 	proto_tree_add_item(tree, hf_ipmi_chs_bo07_block_selector, tvb, 0, 1, ENC_LITTLE_ENDIAN);
397 	proto_tree_add_item(tree, hf_ipmi_chs_bo07_block_data, tvb, 1, -1, ENC_NA);
398 }
399 
400 
401 static struct {
402 	void (*intrp)(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree);
403 	const char *name;
404 } boot_options[] = {
405 	{ bootopt_00, "Set In Progress" },
406 	{ bootopt_01, "Service Partition Selector" },
407 	{ bootopt_02, "Service Partition Scan" },
408 	{ bootopt_03, "BMC boot flag valid bit clearing" },
409 	{ bootopt_04, "Boot info acknowledge" },
410 	{ bootopt_05, "Boot flags" },
411 	{ bootopt_06, "Boot initiator info" },
412 	{ bootopt_07, "Boot initiator mailbox" }
413 };
414 
415 
416 /* Get Chassis Capabilities (response)
417  */
418 static void
419 rs00(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
420 {
421 	static int * const byte1[] = { &hf_ipmi_chs_00_capflags_ppi, &hf_ipmi_chs_00_capflags_di,
422 		&hf_ipmi_chs_00_capflags_fpl, &hf_ipmi_chs_00_capflags_is, NULL };
423 
424 	proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Capabilities: ", "None",
425 			ett_ipmi_chs_00_capflags, byte1, ENC_LITTLE_ENDIAN, BMT_NO_TFS);
426 	proto_tree_add_item(tree, hf_ipmi_chs_00_fru_dev_addr, tvb, 1, 1, ENC_LITTLE_ENDIAN);
427 	proto_tree_add_item(tree, hf_ipmi_chs_00_sdr_dev_addr, tvb, 2, 1, ENC_LITTLE_ENDIAN);
428 	proto_tree_add_item(tree, hf_ipmi_chs_00_sel_dev_addr, tvb, 3, 1, ENC_LITTLE_ENDIAN);
429 	proto_tree_add_item(tree, hf_ipmi_chs_00_sm_dev_addr, tvb, 4, 1, ENC_LITTLE_ENDIAN);
430 
431 	if (tvb_captured_length(tvb) >= 5) {
432 		proto_tree_add_item(tree, hf_ipmi_chs_00_bridge_dev_addr, tvb, 5, 1, ENC_LITTLE_ENDIAN);
433 	}
434 }
435 
436 /* Get Chassis Status.
437  */
438 static void
439 rs01(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
440 {
441 	static int * const byte1[] = { &hf_ipmi_chs_01_pwr_state_policy,
442 		&hf_ipmi_chs_01_pwr_state_ctl_fault, &hf_ipmi_chs_01_pwr_state_fault,
443 		&hf_ipmi_chs_01_pwr_state_ilock, &hf_ipmi_chs_01_pwr_state_overload,
444 		&hf_ipmi_chs_01_pwr_state_powered, NULL };
445 	static int * const byte2[] = { &hf_ipmi_chs_01_last_event_via_ipmi,
446 		&hf_ipmi_chs_01_last_event_down_by_fault, &hf_ipmi_chs_01_last_event_interlock,
447 		&hf_ipmi_chs_01_last_event_overload, &hf_ipmi_chs_01_last_event_ac_failed, NULL };
448 	static int * const byte3[] = { &hf_ipmi_chs_01_misc_identsupp, &hf_ipmi_chs_01_misc_identstate,
449 		&hf_ipmi_chs_01_misc_fan, &hf_ipmi_chs_01_misc_drive, &hf_ipmi_chs_01_misc_fpl_active,
450 		&hf_ipmi_chs_01_misc_intrusion, NULL };
451 	static int * const byte4[] = { &hf_ipmi_chs_01_fpb_standby_allowed,
452 		&hf_ipmi_chs_01_fpb_diagintr_allowed, &hf_ipmi_chs_01_fpb_reset_allowed,
453 		&hf_ipmi_chs_01_fpb_poweroff_allowed, &hf_ipmi_chs_01_fpb_standby_disabled,
454 		&hf_ipmi_chs_01_fpb_diagintr_disabled, &hf_ipmi_chs_01_fpb_reset_disabled,
455 		&hf_ipmi_chs_01_fpb_poweroff_disabled, NULL };
456 
457 	proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Current Power State: ", NULL,
458 			ett_ipmi_chs_01_pwr_state, byte1, ENC_LITTLE_ENDIAN, 0);
459 	proto_tree_add_bitmask_text(tree, tvb, 1, 1, "Last Power Event: ", NULL,
460 			ett_ipmi_chs_01_last_event, byte2, ENC_LITTLE_ENDIAN, 0);
461 	proto_tree_add_bitmask_text(tree, tvb, 2, 1, "Misc. State: ", NULL,
462 			ett_ipmi_chs_01_misc, byte3, ENC_LITTLE_ENDIAN, 0);
463 	if (tvb_captured_length(tvb) > 3) {
464 		proto_tree_add_bitmask_text(tree, tvb, 3, 1, "Front panel buttons capabilities: ",
465 				NULL, ett_ipmi_chs_01_fpb, byte4, ENC_LITTLE_ENDIAN, BMT_NO_TFS);
466 	};
467 }
468 
469 /* Chassis Control.
470  */
471 static void
472 rq02(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
473 {
474 	static int * const byte1[] = { &hf_ipmi_chs_02_cctrl, NULL };
475 
476 	proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL,
477 			ett_ipmi_chs_02_byte1, byte1, ENC_LITTLE_ENDIAN, 0);
478 }
479 
480 /* Chassis Identify
481  */
482 static void
483 rq04(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
484 {
485 	static int * const byte2[] = { &hf_ipmi_chs_04_perm_on, NULL };
486 
487 	if (tvb_captured_length(tvb) > 0) {
488 		proto_tree_add_item(tree, hf_ipmi_chs_04_ival, tvb, 0, 1, ENC_LITTLE_ENDIAN);
489 	}
490 
491 	if (tvb_captured_length(tvb) > 1) {
492 		proto_tree_add_bitmask_text(tree, tvb, 1, 1, "Flags: ", "None",
493 				ett_ipmi_chs_04_byte2, byte2, ENC_LITTLE_ENDIAN, 0);
494 	}
495 }
496 
497 /* Set Chassis Capabilities.
498  */
499 static void
500 rq05(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
501 {
502 	static int * const byte1[] = { &hf_ipmi_chs_05_flags_fpl, &hf_ipmi_chs_05_flags_intrusion, NULL };
503 
504 	proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Capabilities: ", "None",
505 			ett_ipmi_chs_05_flags, byte1, ENC_LITTLE_ENDIAN, 0);
506 	proto_tree_add_item(tree, hf_ipmi_chs_05_fru_dev_addr, tvb, 1, 1, ENC_LITTLE_ENDIAN);
507 	proto_tree_add_item(tree, hf_ipmi_chs_05_sdr_dev_addr, tvb, 2, 1, ENC_LITTLE_ENDIAN);
508 	proto_tree_add_item(tree, hf_ipmi_chs_05_sel_dev_addr, tvb, 3, 1, ENC_LITTLE_ENDIAN);
509 	proto_tree_add_item(tree, hf_ipmi_chs_05_sm_dev_addr, tvb, 4, 1, ENC_LITTLE_ENDIAN);
510 	if (tvb_captured_length(tvb) > 5) {
511 		/* Bridge device address is optional */
512 		proto_tree_add_item(tree, hf_ipmi_chs_05_bridge_dev_addr, tvb, 5, 1, ENC_LITTLE_ENDIAN);
513 	}
514 }
515 
516 /* Set Power Restore Policy
517  */
518 static void
519 rq06(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
520 {
521 	static int * const byte1[] = { &hf_ipmi_chs_06_rq_policy, NULL };
522 
523 	proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL,
524 			ett_ipmi_chs_06_byte1, byte1, ENC_LITTLE_ENDIAN, 0);
525 }
526 
527 /* Get Power Restore Policy
528  */
529 static void
530 rs06(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
531 {
532 	static int * const byte1[] = { &hf_ipmi_chs_06_rs_policy_support_powerup,
533 		&hf_ipmi_chs_06_rs_policy_support_restore, &hf_ipmi_chs_06_rs_policy_support_poweroff, NULL };
534 
535 	proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Power Restore Policy support: ", "None",
536 			ett_ipmi_chs_06_policy_support, byte1, ENC_LITTLE_ENDIAN, BMT_NO_TFS);
537 }
538 
539 /* Get System Restart Cause
540  */
541 static void
542 rs07(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
543 {
544 	static int * const byte1[] = { &hf_ipmi_chs_07_cause, NULL };
545 
546 	proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL,
547 			ett_ipmi_chs_07_byte1, byte1, ENC_LITTLE_ENDIAN, 0);
548 	proto_tree_add_item(tree, hf_ipmi_chs_07_chan, tvb, 1, 1, ENC_LITTLE_ENDIAN);
549 }
550 
551 /* Set System Boot Options
552  */
553 static void
554 rq08(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
555 {
556 	proto_tree *s_tree;
557 	tvbuff_t *sub;
558 	guint8 pno;
559 	const char *desc;
560 
561 	pno = tvb_get_guint8(tvb, 0) & 0x7f;
562 	if (pno < array_length(boot_options)) {
563 		desc = boot_options[pno].name;
564 	} else if (pno >= 96 && pno <= 127) {
565 		desc = "OEM";
566 	} else {
567 		desc = "Reserved";
568 	}
569 
570 	s_tree = proto_tree_add_subtree_format(tree, tvb, 0, 1,
571 			ett_ipmi_chs_08_byte1, NULL, "Boot option parameter selector: %s (0x%02x)",
572 			desc, pno);
573 	proto_tree_add_item(s_tree, hf_ipmi_chs_08_valid, tvb, 0, 1, ENC_LITTLE_ENDIAN);
574 	proto_tree_add_uint_format_value(s_tree, hf_ipmi_chs_08_selector, tvb, 0, 1,
575 			pno, "Boot option parameter selector: %s (0x%02x)",
576 			desc, pno);
577 
578 	/* Data is optional; no data means 'just set validity' */
579 	if (tvb_captured_length(tvb) > 1) {
580 		if (pno < array_length(boot_options)) {
581 			sub = tvb_new_subset_remaining(tvb, 1);
582 			boot_options[pno].intrp(pinfo, sub, tree);
583 		} else {
584 			proto_tree_add_none_format(tree, hf_ipmi_chs_08_data, tvb, 1,
585 					-1, "Parameter data: %s", desc);
586 		}
587 	}
588 }
589 
590 static const value_string cc08[] = {
591 	{ 0x80, "Parameter not supported" },
592 	{ 0x81, "Attempt to set the 'set in progress' value (in parameter #0) when not in the 'set complete' state" },
593 	{ 0x82, "Attempt to write read-only parameter" },
594 	{ 0, NULL }
595 };
596 
597 /* Get System Boot Options
598  */
599 static void
600 rq09(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
601 {
602 	proto_tree *s_tree;
603 	guint8 pno;
604 	const char *desc;
605 
606 	pno = tvb_get_guint8(tvb, 0) & 0x7f;
607 	if (pno < array_length(boot_options)) {
608 		desc = boot_options[pno].name;
609 	} else if (pno >= 96 && pno <= 127) {
610 		desc = "OEM";
611 	} else {
612 		desc = "Reserved";
613 	}
614 
615 
616 	s_tree = proto_tree_add_subtree_format(tree, tvb, 0, 1,
617 			ett_ipmi_chs_09_rq_byte1, NULL, "Boot option parameter selector: %s (0x%02x)",
618 			desc, pno);
619 	proto_tree_add_uint_format_value(s_tree, hf_ipmi_chs_09_rq_param_select, tvb, 0, 1,
620 			pno, "Boot option parameter selector: %s (0x%02x)",
621 			desc, pno);
622 
623 	proto_tree_add_item(tree, hf_ipmi_chs_09_rq_set_select, tvb, 1, 1, ENC_LITTLE_ENDIAN);
624 	proto_tree_add_item(tree, hf_ipmi_chs_09_rq_block_select, tvb, 2, 1, ENC_LITTLE_ENDIAN);
625 }
626 
627 static void
628 rs09(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
629 {
630 	static int * const byte1[] = { &hf_ipmi_chs_09_rs_param_version, NULL };
631 	proto_tree *s_tree;
632 	tvbuff_t *sub;
633 	guint8 pno;
634 	const char *desc;
635 
636 	pno = tvb_get_guint8(tvb, 1) & 0x7f;
637 	if (pno < array_length(boot_options)) {
638 		desc = boot_options[pno].name;
639 	} else if (pno >= 96 && pno <= 127) {
640 		desc = "OEM";
641 	} else {
642 		desc = "Reserved";
643 	}
644 
645 	proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL,
646 			ett_ipmi_chs_09_rs_byte1, byte1, ENC_LITTLE_ENDIAN, 0);
647 
648 	s_tree = proto_tree_add_subtree_format(tree, tvb, 1, 1,
649 			ett_ipmi_chs_09_rs_byte2, NULL, "Boot option parameter selector: %s (0x%02x)",
650 			desc, pno);
651 	proto_tree_add_item(s_tree, hf_ipmi_chs_09_rs_valid, tvb, 1, 1, ENC_LITTLE_ENDIAN);
652 	proto_tree_add_uint_format_value(s_tree, hf_ipmi_chs_09_rs_param_select, tvb, 1, 1,
653 			pno, "Boot option parameter selector: %s (0x%02x)",
654 			desc, pno);
655 
656 	if (pno < array_length(boot_options)) {
657 		sub = tvb_new_subset_remaining(tvb, 2);
658 		boot_options[pno].intrp(pinfo, sub, tree);
659 	} else {
660 		proto_tree_add_item(tree, hf_ipmi_chs_09_rs_param_data, tvb, 2, -1, ENC_NA);
661 	}
662 }
663 
664 static const value_string cc09[] = {
665 	{ 0x80, "Parameter not supported" },
666 	{ 0, NULL }
667 };
668 
669 /* Get POH Counter
670  */
671 static void
672 rs0f(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
673 {
674 	proto_tree_add_item(tree, hf_ipmi_chs_0f_minpercnt, tvb, 0, 1, ENC_LITTLE_ENDIAN);
675 	proto_tree_add_item(tree, hf_ipmi_chs_0f_counter, tvb, 1, 4, ENC_LITTLE_ENDIAN);
676 }
677 
678 static ipmi_cmd_t cmd_chassis[] = {
679 	/* Chassis commands */
680 	{ 0x00, NULL, rs00, NULL, NULL, "Get Chassis Capabilities", 0 },
681 	{ 0x01, NULL, rs01, NULL, NULL, "Get Chassis Status", 0 },
682 	{ 0x02, rq02, NULL, NULL, NULL, "Chassis Control", 0 },
683 	{ 0x03, NULL, NULL, NULL, NULL, "Chassis Reset", 0 },
684 	{ 0x04, rq04, NULL, NULL, NULL, "Chassis Identify", 0 },
685 	{ 0x05, rq05, NULL, NULL, NULL, "Set Chassis Capabilities", 0 },
686 	{ 0x06, rq06, rs06, NULL, NULL, "Set Power Restore Policy", 0 },
687 	{ 0x07, NULL, rs07, NULL, NULL, "Get System Restart Cause", 0 },
688 	{ 0x08, rq08, NULL, cc08, NULL, "Set System Boot Options", 0 },
689 	{ 0x09, rq09, rs09, cc09, NULL, "Get System Boot Options", 0 },
690 	{ 0x0a, IPMI_TBD,   NULL, NULL, "Set Front Panel Buttons Enables", 0 },
691 	{ 0x0b, IPMI_TBD,   NULL, NULL, "Set Power Cycle Interval", 0 },
692 	{ 0x0f, NULL, rs0f, NULL, NULL, "Get POH Counter", 0 },
693 };
694 
695 void
696 proto_register_ipmi_chassis(void)
697 {
698 	static hf_register_info hf[] = {
699 		{ &hf_ipmi_chs_bo00_sip,
700 			{ "Set In Progress",
701 				"ipmi.bootopt00.sip", FT_UINT8, BASE_HEX, VALS(bo00_sip_vals), 0x03, NULL, HFILL }},
702 		{ &hf_ipmi_chs_bo01_spsel,
703 			{ "Service Partition Selector",
704 				"ipmi.bootopt01.spsel", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
705 		{ &hf_ipmi_chs_bo02_request,
706 			{ "Request BIOS to scan for specified service partition",
707 				"ipmi.bootopt02.spscan.request", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
708 		{ &hf_ipmi_chs_bo02_discovered,
709 			{ "Service Partition discovered",
710 				"ipmi.bootopt02.spscan.discovered", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
711 		{ &hf_ipmi_chs_bo03_pef,
712 			{ "Reset/power cycle caused by PEF",
713 				"ipmi.bootopt03.bmcboot.pef", FT_BOOLEAN, 8, TFS(&bo03_dontclear_tfs), 0x10, NULL, HFILL }},
714 		{ &hf_ipmi_chs_bo03_cctrl_timeout,
715 			{ "Chassis Control command not received within 60s timeout",
716 				"ipmi.bootopt03.bmcboot.cctrl_timeout", FT_BOOLEAN, 8, TFS(&bo03_dontclear_tfs), 0x08, NULL, HFILL }},
717 		{ &hf_ipmi_chs_bo03_wd_timeout,
718 			{ "Reset/power cycle caused by watchdog timeout",
719 				"ipmi.bootopt03.bmcboot.wd_timeout", FT_BOOLEAN, 8, TFS(&bo03_dontclear_tfs), 0x04, NULL, HFILL }},
720 		{ &hf_ipmi_chs_bo03_softreset,
721 			{ "Pushbutton reset / soft reset",
722 				"ipmi.bootopt03.bmcboot.softreset", FT_BOOLEAN, 8, TFS(&bo03_dontclear_tfs), 0x02, NULL, HFILL }},
723 		{ &hf_ipmi_chs_bo03_powerup,
724 			{ "Power up via pushbutton or wake event",
725 				"ipmi.bootopt03.bmcboot.powerup", FT_BOOLEAN, 8, TFS(&bo03_dontclear_tfs), 0x01, NULL, HFILL }},
726 		{ &hf_ipmi_chs_bo04_write_mask,
727 			{ "Write mask",
728 				"ipmi.bootopt04.write_mask", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
729 		{ &hf_ipmi_chs_bo04_bootinit_ack_oem,
730 			{ "OEM",
731 				"ipmi.bootopt04.bootinit_ack.oem", FT_BOOLEAN, 8, TFS(&bo04_bootinit_ack_tfs), 0x10, NULL, HFILL }},
732 		{ &hf_ipmi_chs_bo04_bootinit_ack_sms,
733 			{ "SMS",
734 				"ipmi.bootopt04.bootinit_ack.sms", FT_BOOLEAN, 8, TFS(&bo04_bootinit_ack_tfs), 0x08, NULL, HFILL }},
735 		{ &hf_ipmi_chs_bo04_bootinit_ack_os,
736 			{ "OS / Service Partition",
737 				"ipmi.bootopt04.bootinit_ack.os", FT_BOOLEAN, 8, TFS(&bo04_bootinit_ack_tfs), 0x04, NULL, HFILL }},
738 		{ &hf_ipmi_chs_bo04_bootinit_ack_osloader,
739 			{ "OS Loader",
740 				"ipmi.bootopt04.bootinit_ack.osloader", FT_BOOLEAN, 8, TFS(&bo04_bootinit_ack_tfs), 0x02, NULL, HFILL }},
741 		{ &hf_ipmi_chs_bo04_bootinit_ack_bios,
742 			{ "BIOS/POST",
743 				"ipmi.bootopt04.bootinit_ack.bios", FT_BOOLEAN, 8, TFS(&bo04_bootinit_ack_tfs), 0x01, NULL, HFILL }},
744 		{ &hf_ipmi_chs_bo05_bootflags_valid,
745 			{ "Boot flags valid",
746 				"ipmi.bootopt05.boot_flags_valid", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
747 		{ &hf_ipmi_chs_bo05_permanent,
748 			{ "Permanency",
749 				"ipmi.bootopt05.permanent", FT_BOOLEAN, 8, TFS(&bo05_permanent_tfs), 0x40, NULL, HFILL }},
750 		{ &hf_ipmi_chs_bo05_boottype,
751 			{ "Boot type",
752 				"ipmi.bootopt05.boottype", FT_BOOLEAN, 8, TFS(&bo05_boottype_tfs), 0x20, NULL, HFILL }},
753 		{ &hf_ipmi_chs_bo05_cmos_clear,
754 			{ "CMOS Clear",
755 				"ipmi.bootopt05.cmos_clear", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
756 		{ &hf_ipmi_chs_bo05_lock_kbd,
757 			{ "Lock Keyboard",
758 				"ipmi.bootopt05.lock_kbd", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }},
759 		{ &hf_ipmi_chs_bo05_bootdev,
760 			{ "Boot Device Selector",
761 				"ipmi.bootopt05.bootdev", FT_UINT8, BASE_HEX, VALS(bo05_bootdev_vals), 0x3c, NULL, HFILL }},
762 		{ &hf_ipmi_chs_bo05_screen_blank,
763 			{ "Screen Blank",
764 				"ipmi.bootopt05.screen_blank", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
765 		{ &hf_ipmi_chs_bo05_lockout_reset,
766 			{ "Lock out Reset buttons",
767 				"ipmi.bootopt05.lockout_reset", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
768 		{ &hf_ipmi_chs_bo05_lockout_poweroff,
769 			{ "Lock out (power off / sleep request) via Power Button",
770 				"ipmi.bootopt05.lockout_poweroff", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
771 		{ &hf_ipmi_chs_bo05_bios_verbosity,
772 			{ "BIOS verbosity",
773 				"ipmi.bootopt05.bios_verbosity", FT_UINT8, BASE_HEX, VALS(bo05_bios_verbosity_vals), 0x60, NULL, HFILL }},
774 		{ &hf_ipmi_chs_bo05_progress_traps,
775 			{ "Force Progress Event Traps",
776 				"ipmi.bootopt05.progress_traps", FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }},
777 		{ &hf_ipmi_chs_bo05_pwd_bypass,
778 			{ "User password bypass",
779 				"ipmi.bootopt05.pwd_bypass", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
780 		{ &hf_ipmi_chs_bo05_lock_sleep,
781 			{ "Lock Out Sleep Button",
782 				"ipmi.bootopt05.lock_sleep", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
783 		{ &hf_ipmi_chs_bo05_console_redirection,
784 			{ "Console redirection",
785 				"ipmi.bootopt05.console_redirection", FT_UINT8, BASE_HEX, VALS(bo05_console_redir_vals), 0x03, NULL, HFILL }},
786 		{ &hf_ipmi_chs_bo05_bios_shared_override,
787 			{ "BIOS Shared Mode Override",
788 				"ipmi.bootopt05.bios_shared_override", FT_BOOLEAN, 8, TFS(&bo05_bios_shared_tfs), 0x08, NULL, HFILL }},
789 		{ &hf_ipmi_chs_bo05_bios_muxctl_override,
790 			{ "BIOS Mux Control Override",
791 				"ipmi.bootopt05.bios_muxctl_override", FT_UINT8, BASE_HEX, VALS(bo05_bios_muxctl_vals), 0x07, NULL, HFILL }},
792 		{ &hf_ipmi_chs_bo05_byte5,
793 			{ "Data 5 (reserved)",
794 				"ipmi.bootopt05.byte5", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
795 		{ &hf_ipmi_chs_bo06_chan_num,
796 			{ "Channel",
797 				"ipmi.bootopt06.chan_num", FT_UINT8, BASE_CUSTOM, CF_FUNC(ipmi_fmt_channel), 0x0f, NULL, HFILL }},
798 		{ &hf_ipmi_chs_bo06_session_id,
799 			{ "Session ID",
800 				"ipmi.bootopt06.session_id", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
801 		{ &hf_ipmi_chs_bo06_bootinfo_timestamp,
802 			{ "Boot Info Timestamp",
803 				"impi.bootopt06.bootinfo_timestamp", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
804 		{ &hf_ipmi_chs_bo07_block_selector,
805 			{ "Block selector",
806 				"ipmi.bootopt07.block_selector", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
807 		{ &hf_ipmi_chs_bo07_block_data,
808 			{ "Block data",
809 				"ipmi.bootopt07.block_data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
810 
811 		{ &hf_ipmi_chs_00_capflags_ppi,
812 			{ "Power interlock",
813 				"ipmi.ch00.cap.power_interlock", FT_BOOLEAN, 8, TFS(&tfs_00_provided), 0x08, NULL, HFILL }},
814 		{ &hf_ipmi_chs_00_capflags_di,
815 			{ "Diagnostic Interrupt",
816 				"ipmi.ch00.cap.diag_int", FT_BOOLEAN, 8, TFS(&tfs_00_provided), 0x04, NULL, HFILL }},
817 		{ &hf_ipmi_chs_00_capflags_fpl,
818 			{ "Front Panel Lockout",
819 				"ipmi.ch00.cap.fpl", FT_BOOLEAN, 8, TFS(&tfs_00_provided), 0x02, NULL, HFILL }},
820 		{ &hf_ipmi_chs_00_capflags_is,
821 			{ "Intrusion sensor",
822 				"ipmi.ch00.cap.intrusion", FT_BOOLEAN, 8, TFS(&tfs_00_provided), 0x01, NULL, HFILL }},
823 		{ &hf_ipmi_chs_00_fru_dev_addr,
824 			{ "Chassis FRU Info Device Address",
825 				"ipmi.ch00.fru_info", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
826 		{ &hf_ipmi_chs_00_sdr_dev_addr,
827 			{ "Chassis SDR Device Address",
828 				"ipmi.ch00.sdr", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
829 		{ &hf_ipmi_chs_00_sel_dev_addr,
830 			{ "Chassis SEL Device Address",
831 				"ipmi.ch00.sel", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
832 		{ &hf_ipmi_chs_00_sm_dev_addr,
833 			{ "Chassis System Management Device Address",
834 				"ipmi.ch00.sm", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
835 		{ &hf_ipmi_chs_00_bridge_dev_addr,
836 			{ "Chassis Bridge Device Address",
837 				"ipmi.ch00.bridge", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
838 
839 		{ &hf_ipmi_chs_01_pwr_state_policy,
840 			{ "Power Restore Policy",
841 				"ipmi.ch01.cur_pwr.policy", FT_UINT8, BASE_HEX, VALS(vals_01_pwr_policy), 0x60, NULL, HFILL }},
842 		{ &hf_ipmi_chs_01_pwr_state_ctl_fault,
843 			{ "Power Control Fault",
844 				"ipmi.ch01.cur_pwr.ctl_fault", FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }},
845 		{ &hf_ipmi_chs_01_pwr_state_fault,
846 			{ "Power Fault",
847 				"ipmi.ch01.cur_pwr.fault", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
848 		{ &hf_ipmi_chs_01_pwr_state_ilock,
849 			{ "Interlock",
850 				"ipmi.ch01.cur_pwr.interlock", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
851 		{ &hf_ipmi_chs_01_pwr_state_overload,
852 			{ "Overload",
853 				"ipmi.ch01.cur_pwr.overload", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
854 		{ &hf_ipmi_chs_01_pwr_state_powered,
855 			{ "Power is on",
856 				"ipmi.ch01.cur_pwr.powered", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
857 		{ &hf_ipmi_chs_01_last_event_via_ipmi,
858 			{ "Last `Power is on' state was entered via IPMI command",
859 				"ipmi.ch01.last.on_via_ipmi", FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }},
860 		{ &hf_ipmi_chs_01_last_event_down_by_fault,
861 			{ "Last power down caused by power fault",
862 				"ipmi.ch01.last.down_by_fault", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
863 		{ &hf_ipmi_chs_01_last_event_interlock,
864 			{ "Last power down caused by a power interlock being activated",
865 				"ipmi.ch01.last.interlock", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
866 		{ &hf_ipmi_chs_01_last_event_overload,
867 			{ "Last power down caused by a power overload",
868 				"ipmi.ch01.last.overload", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
869 		{ &hf_ipmi_chs_01_last_event_ac_failed,
870 			{ "AC failed",
871 				"ipmi.ch01.last.ac_failed", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
872 		{ &hf_ipmi_chs_01_misc_identsupp,
873 			{ "Chassis Identify command and state info supported",
874 				"ipmi.ch01.identsupp", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }},
875 		{ &hf_ipmi_chs_01_misc_identstate,
876 			{ "Chassis Identify state (if supported)",
877 				"ipmi.ch01.identstate", FT_UINT8, BASE_HEX, VALS(vals_01_identstate), 0x30, NULL, HFILL }},
878 		{ &hf_ipmi_chs_01_misc_fan,
879 			{ "Cooling/fan fault detected",
880 				"ipmi.ch01.misc.fan", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
881 		{ &hf_ipmi_chs_01_misc_drive,
882 			{ "Drive Fault",
883 				"ipmi.ch01.misc.drive", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
884 		{ &hf_ipmi_chs_01_misc_fpl_active,
885 			{ "Front Panel Lockout active",
886 				"ipmi.ch01.misc.fpl_active", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
887 		{ &hf_ipmi_chs_01_misc_intrusion,
888 			{ "Chassis intrusion active",
889 				"ipmi.ch01.misc.intrusion", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
890 		{ &hf_ipmi_chs_01_fpb_standby_allowed,
891 			{ "Standby disable allowed",
892 				"ipmi.ch01.fpb.standby_allowed", FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL }},
893 		{ &hf_ipmi_chs_01_fpb_diagintr_allowed,
894 			{ "Diagnostic interrupt disable allowed",
895 				"ipmi.ch01.fpb.diagintr_allowed", FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL }},
896 		{ &hf_ipmi_chs_01_fpb_reset_allowed,
897 			{ "Reset disable allowed",
898 				"ipmi.ch01.fpb.reset_allowed", FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL }},
899 		{ &hf_ipmi_chs_01_fpb_poweroff_allowed,
900 			{ "Poweroff disable allowed",
901 				"ipmi.ch01.fpb.poweroff_allowed", FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL }},
902 		{ &hf_ipmi_chs_01_fpb_standby_disabled,
903 			{ "Standby disabled",
904 				"ipmi.ch01.fpb.standby_disabled", FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL }},
905 		{ &hf_ipmi_chs_01_fpb_diagintr_disabled,
906 			{ "Diagnostic interrupt disabled",
907 				"ipmi.ch01.fpb.diagintr_disabled", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
908 		{ &hf_ipmi_chs_01_fpb_reset_disabled,
909 			{ "Reset disabled",
910 				"ipmi.ch01.fpb.reset_disabled", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
911 		{ &hf_ipmi_chs_01_fpb_poweroff_disabled,
912 			{ "Poweroff disabled",
913 				"ipmi.ch01.fpb.poweroff_disabled", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
914 
915 		{ &hf_ipmi_chs_02_cctrl,
916 			{ "Chassis Control",
917 				"ipmi.ch02.chassis_control", FT_UINT8, BASE_HEX, VALS(vals_02_cctrl), 0x0f, NULL, HFILL }},
918 
919 		{ &hf_ipmi_chs_04_ival,
920 			{ "Identify Interval in seconds",
921 				"ipmi.ch04.interval", FT_UINT8, BASE_CUSTOM, CF_FUNC(ipmi_fmt_1s_1based), 0, NULL, HFILL }},
922 		{ &hf_ipmi_chs_04_perm_on,
923 			{ "Turn on Identify indefinitely",
924 				"ipmi.ch04.perm_on", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
925 
926 		{ &hf_ipmi_chs_05_flags_fpl,
927 			{ "Provides Front Panel Lockout",
928 				"ipmi.ch05.flags.fpl", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
929 		{ &hf_ipmi_chs_05_flags_intrusion,
930 			{ "Provides intrusion sensor",
931 				"ipmi.ch05.flags.intrusion", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
932 		{ &hf_ipmi_chs_05_fru_dev_addr,
933 			{ "Chassis FRU Info Device Address",
934 				"ipmi.ch05.fru_info", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
935 		{ &hf_ipmi_chs_05_sdr_dev_addr,
936 			{ "Chassis SDR Device Address",
937 				"ipmi.ch05.sdr", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
938 		{ &hf_ipmi_chs_05_sel_dev_addr,
939 			{ "Chassis SEL Device Address",
940 				"ipmi.ch05.sel", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
941 		{ &hf_ipmi_chs_05_sm_dev_addr,
942 			{ "Chassis System Management Device Address",
943 				"ipmi.ch05.sm", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
944 		{ &hf_ipmi_chs_05_bridge_dev_addr,
945 			{ "Chassis Bridge Device Address",
946 				"ipmi.ch05.bridge", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
947 
948 		{ &hf_ipmi_chs_06_rq_policy,
949 			{ "Power Restore Policy",
950 				"ipmi.ch06.rq_policy", FT_UINT8, BASE_HEX, VALS(vals_06_policy), 0x07, NULL, HFILL }},
951 		{ &hf_ipmi_chs_06_rs_policy_support_powerup,
952 			{ "Always powering up",
953 				"ipmi.ch06.rs_support.powerup", FT_BOOLEAN, 8, TFS(&tfs_06_supported), 0x04, NULL, HFILL }},
954 		{ &hf_ipmi_chs_06_rs_policy_support_restore,
955 			{ "Restoring previous state",
956 				"ipmi.ch06.rs_support.restore", FT_BOOLEAN, 8, TFS(&tfs_06_supported), 0x02, NULL, HFILL }},
957 		{ &hf_ipmi_chs_06_rs_policy_support_poweroff,
958 			{ "Staying powered off",
959 				"ipmi.ch06.rs_support.poweroff", FT_BOOLEAN, 8, TFS(&tfs_06_supported), 0x01, NULL, HFILL }},
960 
961 		{ &hf_ipmi_chs_07_cause,
962 			{ "Restart Cause",
963 				"ipmi.ch07.cause", FT_UINT8, BASE_HEX, VALS(vals_07_cause), 0x0f, NULL, HFILL }},
964 		{ &hf_ipmi_chs_07_chan,
965 			{ "Channel",
966 				"ipmi.ch07.chan", FT_UINT8, BASE_CUSTOM, CF_FUNC(ipmi_fmt_channel), 0, NULL, HFILL }},
967 
968 		{ &hf_ipmi_chs_08_valid,
969 			{ "Validity",
970 				"ipmi.ch08.valid", FT_BOOLEAN, 8, TFS(&tfs_08_valid), 0x80, NULL, HFILL }},
971 		{ &hf_ipmi_chs_08_selector,
972 			{ "Boot option parameter selector",
973 				"ipmi.ch08.selector", FT_UINT8, BASE_HEX, NULL, 0x7f, NULL, HFILL }},
974 		{ &hf_ipmi_chs_08_data,
975 			{ "Boot option parameter data",
976 				"ipmi.ch08.data", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
977 
978 		{ &hf_ipmi_chs_09_rq_param_select,
979 			{ "Parameter selector",
980 				"ipmi.ch09.rq_param_select", FT_UINT8, BASE_HEX, NULL, 0x7f, NULL, HFILL }},
981 		{ &hf_ipmi_chs_09_rq_set_select,
982 			{ "Set Selector",
983 				"ipmi.ch09.rq_set_select", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
984 		{ &hf_ipmi_chs_09_rq_block_select,
985 			{ "Block Selector",
986 				"ipmi.ch09.rq_block_select", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
987 		{ &hf_ipmi_chs_09_rs_param_version,
988 			{ "Parameter Version",
989 				"ipmi.ch09.rs_param_version", FT_UINT8, BASE_HEX, NULL, 0x0f, NULL, HFILL }},
990 		{ &hf_ipmi_chs_09_rs_valid,
991 			{ "Parameter Valid",
992 				"ipmi.ch09.rs_valid", FT_BOOLEAN, 8, TFS(&tfs_09_valid), 0x80, NULL, HFILL }},
993 		{ &hf_ipmi_chs_09_rs_param_select,
994 			{ "Parameter Selector",
995 				"ipmi.ch09.rs_param_select", FT_UINT8, BASE_HEX, NULL, 0x7f, NULL, HFILL }},
996 		{ &hf_ipmi_chs_09_rs_param_data,
997 			{ "Configuration parameter data",
998 				"ipmi.ch09.rs_param_data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
999 
1000 		{ &hf_ipmi_chs_0f_minpercnt,
1001 			{ "Minutes per count",
1002 				"ipmi.ch0f.minpercnt", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
1003 		{ &hf_ipmi_chs_0f_counter,
1004 			{ "Counter reading",
1005 				"ipmi.ch0f.counter", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
1006 	};
1007 
1008 	static gint *ett[] = {
1009 		&ett_ipmi_chs_bo00_byte1,
1010 		&ett_ipmi_chs_bo02_byte1,
1011 		&ett_ipmi_chs_bo03_byte1,
1012 		&ett_ipmi_chs_bo04_byte2,
1013 		&ett_ipmi_chs_bo05_byte1,
1014 		&ett_ipmi_chs_bo05_byte2,
1015 		&ett_ipmi_chs_bo05_byte3,
1016 		&ett_ipmi_chs_bo05_byte4,
1017 		&ett_ipmi_chs_bo06_byte1,
1018 		&ett_ipmi_chs_00_capflags,
1019 		&ett_ipmi_chs_01_pwr_state,
1020 		&ett_ipmi_chs_01_last_event,
1021 		&ett_ipmi_chs_01_misc,
1022 		&ett_ipmi_chs_01_fpb,
1023 		&ett_ipmi_chs_02_byte1,
1024 		&ett_ipmi_chs_04_byte2,
1025 		&ett_ipmi_chs_05_flags,
1026 		&ett_ipmi_chs_06_byte1,
1027 		&ett_ipmi_chs_06_policy_support,
1028 		&ett_ipmi_chs_07_byte1,
1029 		&ett_ipmi_chs_08_byte1,
1030 		&ett_ipmi_chs_09_rq_byte1,
1031 		&ett_ipmi_chs_09_rs_byte1,
1032 		&ett_ipmi_chs_09_rs_byte2,
1033 	};
1034 
1035 	proto_register_field_array(proto_ipmi, hf, array_length(hf));
1036 	proto_register_subtree_array(ett, array_length(ett));
1037 	ipmi_register_netfn_cmdtab(IPMI_CHASSIS_REQ, IPMI_OEM_NONE, NULL, 0, NULL,
1038 			cmd_chassis, array_length(cmd_chassis));
1039 }
1040 
1041 
1042 /*
1043  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1044  *
1045  * Local variables:
1046  * c-basic-offset: 8
1047  * tab-width: 8
1048  * indent-tabs-mode: t
1049  * End:
1050  *
1051  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1052  * :indentSize=8:tabSize=8:noTabs=false:
1053  */
1054