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