Trivial warning fixes
[obnox/wireshark/wip.git] / epan / dissectors / packet-ipmi-se.c
1 /* packet-ipmi-se.c
2  * Sub-dissectors for IPMI messages (netFn=Sensor/Event)
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 /* Data types for sensor-specific info */
39 struct sensor_info;
40 typedef gboolean (*intrp_t)(proto_tree *, tvbuff_t *, const struct sensor_info *,
41                 guint32, guint32, guint32);
42
43 struct sensor_info {
44         const value_string *offsets;
45         intrp_t intrp2;
46         intrp_t intrp3;
47         const char *desc;
48 };
49
50 struct evtype_info {
51         const value_string *byte2;
52         const value_string *byte3;
53         const value_string *offsets;
54         intrp_t intrp2;
55         intrp_t intrp3;
56         const char *desc;
57 };
58
59 static gint ett_ipmi_se_evt_byte3 = -1;
60 static gint ett_ipmi_se_evt_evd_byte1 = -1;
61 static gint ett_ipmi_se_evt_evd_byte2 = -1;
62 static gint ett_ipmi_se_evt_evd_byte3 = -1;
63
64 static gint ett_ipmi_se_cp06_byte1 = -1;
65 static gint ett_ipmi_se_cp07_byte1 = -1;
66 static gint ett_ipmi_se_cp09_byte1 = -1;
67 static gint ett_ipmi_se_cp10_byte1 = -1;
68 static gint ett_ipmi_se_cp12_byte1 = -1;
69 static gint ett_ipmi_se_cp12_byte2 = -1;
70 static gint ett_ipmi_se_cp12_byte3 = -1;
71 static gint ett_ipmi_se_cp13_byte1 = -1;
72 static gint ett_ipmi_se_cp15_byte1 = -1;
73 static gint ett_ipmi_se_cp15_byte2 = -1;
74 static gint ett_ipmi_se_cp15_member = -1;
75 static gint ett_ipmi_se_cp15_byte11 = -1;
76
77 static gint ett_ipmi_se_00_byte2 = -1;
78 static gint ett_ipmi_se_01_byte2 = -1;
79 static gint ett_ipmi_se_10_action = -1;
80 static gint ett_ipmi_se_12_byte1 = -1;
81 static gint ett_ipmi_se_13_byte1 = -1;
82 static gint ett_ipmi_se_13_rev = -1;
83 static gint ett_ipmi_se_14_byte1 = -1;
84 static gint ett_ipmi_se_16_byte1 = -1;
85 static gint ett_ipmi_se_16_byte2 = -1;
86 static gint ett_ipmi_se_16_byte3 = -1;
87 static gint ett_ipmi_se_20_rq_byte1 = -1;
88 static gint ett_ipmi_se_20_rs_byte2 = -1;
89 static gint ett_ipmi_se_23_readingfactors = -1;
90 static gint ett_ipmi_se_23_byte1 = -1;
91 static gint ett_ipmi_se_23_byte2 = -1;
92 static gint ett_ipmi_se_23_byte3 = -1;
93 static gint ett_ipmi_se_23_byte4 = -1;
94 static gint ett_ipmi_se_23_byte5 = -1;
95 static gint ett_ipmi_se_23_byte6 = -1;
96 static gint ett_ipmi_se_XX_mask = -1;
97 static gint ett_ipmi_se_XX_b1 = -1;
98 static gint ett_ipmi_se_XX_b2 = -1;
99 static gint ett_ipmi_se_XX_b3 = -1;
100 static gint ett_ipmi_se_XX_b4 = -1;
101 static gint ett_ipmi_se_28_byte2 = -1;
102 static gint ett_ipmi_se_29_byte1 = -1;
103 static gint ett_ipmi_se_2a_byte2 = -1;
104 static gint ett_ipmi_se_2b_byte1 = -1;
105 static gint ett_ipmi_se_2d_byte2 = -1;
106 static gint ett_ipmi_se_2d_b1 = -1;
107 static gint ett_ipmi_se_2d_b2 = -1;
108 static gint ett_ipmi_se_2e_evtype = -1;
109 static gint ett_ipmi_se_2f_evtype = -1;
110
111 static gint hf_ipmi_se_evt_rev = -1;
112 static gint hf_ipmi_se_evt_sensor_type = -1;
113 static gint hf_ipmi_se_evt_sensor_num = -1;
114 static gint hf_ipmi_se_evt_byte3 = -1;
115 static gint hf_ipmi_se_evt_dir = -1;
116 static gint hf_ipmi_se_evt_type = -1;
117 static gint hf_ipmi_se_evt_data1 = -1;
118 static gint hf_ipmi_se_evt_data1_b2 = -1;
119 static gint hf_ipmi_se_evt_data1_b3 = -1;
120 static gint hf_ipmi_se_evt_data1_offs = -1;
121 static gint hf_ipmi_se_evt_data2 = -1;
122 static gint hf_ipmi_se_evt_data3 = -1;
123
124 static gint hf_ipmi_se_cp00_sip = -1;
125 static gint hf_ipmi_se_cp01_alert_startup = -1;
126 static gint hf_ipmi_se_cp01_startup = -1;
127 static gint hf_ipmi_se_cp01_event_msg = -1;
128 static gint hf_ipmi_se_cp01_pef = -1;
129 static gint hf_ipmi_se_cp02_diag_intr = -1;
130 static gint hf_ipmi_se_cp02_oem_action = -1;
131 static gint hf_ipmi_se_cp02_pwr_cycle = -1;
132 static gint hf_ipmi_se_cp02_reset = -1;
133 static gint hf_ipmi_se_cp02_pwr_down = -1;
134 static gint hf_ipmi_se_cp02_alert = -1;
135 static gint hf_ipmi_se_cp03_startup = -1;
136 static gint hf_ipmi_se_cp04_alert_startup = -1;
137 static gint hf_ipmi_se_cp05_num_evfilters = -1;
138 static gint hf_ipmi_se_cp06_filter = -1;
139 static gint hf_ipmi_se_cp06_data = -1;
140 static gint hf_ipmi_se_cp07_filter = -1;
141 static gint hf_ipmi_se_cp07_data = -1;
142 static gint hf_ipmi_se_cp08_policies = -1;
143 static gint hf_ipmi_se_cp09_entry = -1;
144 static gint hf_ipmi_se_cp09_data = -1;
145 static gint hf_ipmi_se_cp10_useval = -1;
146 static gint hf_ipmi_se_cp10_guid = -1;
147 static gint hf_ipmi_se_cp11_num_alertstr = -1;
148 static gint hf_ipmi_se_cp12_byte1 = -1;
149 static gint hf_ipmi_se_cp12_alert_stringsel = -1;
150 static gint hf_ipmi_se_cp12_evfilter = -1;
151 static gint hf_ipmi_se_cp12_alert_stringset = -1;
152 static gint hf_ipmi_se_cp13_stringsel = -1;
153 static gint hf_ipmi_se_cp13_blocksel = -1;
154 static gint hf_ipmi_se_cp13_string = -1;
155 static gint hf_ipmi_se_cp14_num_gct = -1;
156 static gint hf_ipmi_se_cp15_gctsel = -1;
157 static gint hf_ipmi_se_cp15_force = -1;
158 static gint hf_ipmi_se_cp15_delayed = -1;
159 static gint hf_ipmi_se_cp15_channel = -1;
160 static gint hf_ipmi_se_cp15_group = -1;
161 static gint hf_ipmi_se_cp15_member_check = -1;
162 static gint hf_ipmi_se_cp15_member_id = -1;
163 static gint hf_ipmi_se_cp15_retries = -1;
164 static gint hf_ipmi_se_cp15_operation = -1;
165
166 static gint hf_ipmi_se_00_addr = -1;
167 static gint hf_ipmi_se_00_lun = -1;
168
169 static gint hf_ipmi_se_01_addr = -1;
170 static gint hf_ipmi_se_01_lun = -1;
171
172 static gint hf_ipmi_se_10_pef_version = -1;
173 static gint hf_ipmi_se_10_action_oem_filter = -1;
174 static gint hf_ipmi_se_10_action_diag_intr = -1;
175 static gint hf_ipmi_se_10_action_oem_action = -1;
176 static gint hf_ipmi_se_10_action_pwr_cycle = -1;
177 static gint hf_ipmi_se_10_action_reset = -1;
178 static gint hf_ipmi_se_10_action_pwr_down = -1;
179 static gint hf_ipmi_se_10_action_alert = -1;
180 static gint hf_ipmi_se_10_entries = -1;
181
182 static gint hf_ipmi_se_11_rq_timeout = -1;
183 static gint hf_ipmi_se_11_rs_timeout = -1;
184
185 static gint hf_ipmi_se_12_byte1 = -1;
186 static gint hf_ipmi_se_12_param = -1;
187 static gint hf_ipmi_se_12_data = -1;
188
189 static gint hf_ipmi_se_13_byte1 = -1;
190 static gint hf_ipmi_se_13_getrev = -1;
191 static gint hf_ipmi_se_13_param = -1;
192 static gint hf_ipmi_se_13_set = -1;
193 static gint hf_ipmi_se_13_block = -1;
194 static gint hf_ipmi_se_13_rev_present = -1;
195 static gint hf_ipmi_se_13_rev_compat = -1;
196 static gint hf_ipmi_se_13_data = -1;
197
198 static gint hf_ipmi_se_14_processed_by = -1;
199 static gint hf_ipmi_se_14_rid = -1;
200
201 static gint hf_ipmi_se_15_tstamp = -1;
202 static gint hf_ipmi_se_15_lastrec = -1;
203 static gint hf_ipmi_se_15_proc_sw = -1;
204 static gint hf_ipmi_se_15_proc_bmc = -1;
205
206 static gint hf_ipmi_se_16_chan = -1;
207 static gint hf_ipmi_se_16_op = -1;
208 static gint hf_ipmi_se_16_dst = -1;
209 static gint hf_ipmi_se_16_send_string = -1;
210 static gint hf_ipmi_se_16_string_sel = -1;
211 static gint hf_ipmi_se_16_gen = -1;
212 static gint hf_ipmi_se_16_status = -1;
213
214 static gint hf_ipmi_se_17_seq = -1;
215 static gint hf_ipmi_se_17_tstamp = -1;
216 static gint hf_ipmi_se_17_evsrc = -1;
217 static gint hf_ipmi_se_17_sensor_dev = -1;
218 static gint hf_ipmi_se_17_sensor_num = -1;
219 static gint hf_ipmi_se_17_evdata1 = -1;
220 static gint hf_ipmi_se_17_evdata2 = -1;
221 static gint hf_ipmi_se_17_evdata3 = -1;
222
223 static gint hf_ipmi_se_20_rq_op = -1;
224 static gint hf_ipmi_se_20_rs_num = -1;
225 static gint hf_ipmi_se_20_rs_sdr = -1;
226 static gint hf_ipmi_se_20_rs_population = -1;
227 static gint hf_ipmi_se_20_rs_lun3 = -1;
228 static gint hf_ipmi_se_20_rs_lun2 = -1;
229 static gint hf_ipmi_se_20_rs_lun1 = -1;
230 static gint hf_ipmi_se_20_rs_lun0 = -1;
231 static gint hf_ipmi_se_20_rs_change = -1;
232
233 static gint hf_ipmi_se_21_rid = -1;
234 static gint hf_ipmi_se_21_record = -1;
235 static gint hf_ipmi_se_21_offset = -1;
236 static gint hf_ipmi_se_21_len = -1;
237 static gint hf_ipmi_se_21_next = -1;
238 static gint hf_ipmi_se_21_recdata = -1;
239
240 static gint hf_ipmi_se_22_resid = -1;
241
242 static gint hf_ipmi_se_23_rq_sensor = -1;
243 static gint hf_ipmi_se_23_rq_reading = -1;
244 static gint hf_ipmi_se_23_rs_next_reading = -1;
245
246 static gint hf_ipmi_se_24_sensor = -1;
247 static gint hf_ipmi_se_24_mask = -1;
248 static gint hf_ipmi_se_24_hyst_pos = -1;
249 static gint hf_ipmi_se_24_hyst_neg = -1;
250
251 static gint hf_ipmi_se_25_sensor = -1;
252 static gint hf_ipmi_se_25_mask = -1;
253 static gint hf_ipmi_se_25_hyst_pos = -1;
254 static gint hf_ipmi_se_25_hyst_neg = -1;
255
256 static gint hf_ipmi_se_26_sensor = -1;
257 static gint hf_ipmi_se_XX_m_unr = -1;
258 static gint hf_ipmi_se_XX_m_uc = -1;
259 static gint hf_ipmi_se_XX_m_unc = -1;
260 static gint hf_ipmi_se_XX_m_lnr = -1;
261 static gint hf_ipmi_se_XX_m_lc = -1;
262 static gint hf_ipmi_se_XX_m_lnc = -1;
263 static gint hf_ipmi_se_XX_thr_lnc = -1;
264 static gint hf_ipmi_se_XX_thr_lc = -1;
265 static gint hf_ipmi_se_XX_thr_lnr = -1;
266 static gint hf_ipmi_se_XX_thr_unc = -1;
267 static gint hf_ipmi_se_XX_thr_uc = -1;
268 static gint hf_ipmi_se_XX_thr_unr = -1;
269
270 static gint hf_ipmi_se_27_sensor = -1;
271
272 static gint hf_ipmi_se_XX_b1_7 = -1;
273 static gint hf_ipmi_se_XX_b1_6 = -1;
274 static gint hf_ipmi_se_XX_b1_5 = -1;
275 static gint hf_ipmi_se_XX_b1_4 = -1;
276 static gint hf_ipmi_se_XX_b1_3 = -1;
277 static gint hf_ipmi_se_XX_b1_2 = -1;
278 static gint hf_ipmi_se_XX_b1_1 = -1;
279 static gint hf_ipmi_se_XX_b1_0 = -1;
280 static gint hf_ipmi_se_XX_b2_6 = -1;
281 static gint hf_ipmi_se_XX_b2_5 = -1;
282 static gint hf_ipmi_se_XX_b2_4 = -1;
283 static gint hf_ipmi_se_XX_b2_3 = -1;
284 static gint hf_ipmi_se_XX_b2_2 = -1;
285 static gint hf_ipmi_se_XX_b2_1 = -1;
286 static gint hf_ipmi_se_XX_b2_0 = -1;
287 static gint hf_ipmi_se_XX_b3_7 = -1;
288 static gint hf_ipmi_se_XX_b3_6 = -1;
289 static gint hf_ipmi_se_XX_b3_5 = -1;
290 static gint hf_ipmi_se_XX_b3_4 = -1;
291 static gint hf_ipmi_se_XX_b3_3 = -1;
292 static gint hf_ipmi_se_XX_b3_2 = -1;
293 static gint hf_ipmi_se_XX_b3_1 = -1;
294 static gint hf_ipmi_se_XX_b3_0 = -1;
295 static gint hf_ipmi_se_XX_b4_6 = -1;
296 static gint hf_ipmi_se_XX_b4_5 = -1;
297 static gint hf_ipmi_se_XX_b4_4 = -1;
298 static gint hf_ipmi_se_XX_b4_3 = -1;
299 static gint hf_ipmi_se_XX_b4_2 = -1;
300 static gint hf_ipmi_se_XX_b4_1 = -1;
301 static gint hf_ipmi_se_XX_b4_0 = -1;
302
303 static gint hf_ipmi_se_28_sensor = -1;
304 static gint hf_ipmi_se_28_fl_evm = -1;
305 static gint hf_ipmi_se_28_fl_scan = -1;                 
306 static gint hf_ipmi_se_28_fl_action = -1;
307
308 static gint hf_ipmi_se_29_sensor = -1;
309 static gint hf_ipmi_se_29_fl_evm = -1;
310 static gint hf_ipmi_se_29_fl_scan = -1;
311
312 static gint hf_ipmi_se_2a_sensor = -1;
313 static gint hf_ipmi_se_2a_fl_sel = -1;
314
315 static gint hf_ipmi_se_2b_sensor = -1;
316 static gint hf_ipmi_se_2b_fl_evm = -1;
317 static gint hf_ipmi_se_2b_fl_scan = -1;
318 static gint hf_ipmi_se_2b_fl_unavail = -1;
319
320 static gint hf_ipmi_se_2d_sensor = -1;
321 static gint hf_ipmi_se_2d_reading = -1;
322 static gint hf_ipmi_se_2d_b1_7 = -1;
323 static gint hf_ipmi_se_2d_b1_6 = -1;
324 static gint hf_ipmi_se_2d_b1_5 = -1;
325 static gint hf_ipmi_se_2d_b1_4 = -1;
326 static gint hf_ipmi_se_2d_b1_3 = -1;
327 static gint hf_ipmi_se_2d_b1_2 = -1;
328 static gint hf_ipmi_se_2d_b1_1 = -1;
329 static gint hf_ipmi_se_2d_b1_0 = -1;
330 static gint hf_ipmi_se_2d_b2_6 = -1;
331 static gint hf_ipmi_se_2d_b2_5 = -1;
332 static gint hf_ipmi_se_2d_b2_4 = -1;
333 static gint hf_ipmi_se_2d_b2_3 = -1;
334 static gint hf_ipmi_se_2d_b2_2 = -1;
335 static gint hf_ipmi_se_2d_b2_1 = -1;
336 static gint hf_ipmi_se_2d_b2_0 = -1;
337
338 static gint hf_ipmi_se_2e_sensor = -1;
339 static gint hf_ipmi_se_2e_stype = -1;
340 static gint hf_ipmi_se_2e_evtype = -1;
341
342 static gint hf_ipmi_se_2f_sensor = -1;
343 static gint hf_ipmi_se_2f_stype = -1;
344 static gint hf_ipmi_se_2f_evtype = -1;
345
346 /* Platform Event parsing. Common for Platform Event and Alert Immediate.
347  */
348 static const value_string evt_evm_rev_vals[] = {
349         { 0x03, "IPMI 1.0" },
350         { 0x04, "IPMI 1.5+" },
351         { 0, NULL },
352 };
353
354 static const struct true_false_string evt_evdir_tfs = {
355         "Deassertion event",
356         "Assertion event"
357 };
358
359 static const value_string et_empty[] = {
360         { 0, NULL }
361 };
362
363 static const value_string etb2_thr[] = {
364         { 0x00, "Unspecified" },
365         { 0x01, "Trigger reading" },
366         { 0x02, "OEM code" },
367         { 0x03, "Sensor-specific" },
368         { 0, NULL }
369 };
370
371 static const value_string etb3_thr[] = {
372         { 0x00, "Unspecified" },
373         { 0x01, "Trigger threshold" },
374         { 0x02, "OEM code" },
375         { 0x03, "Sensor-specific" },
376         { 0, NULL }
377 };
378
379 static const value_string etb2_dscr[] = {
380         { 0x00, "Unspecified" },
381         { 0x01, "Previous state and/or severity" },
382         { 0x02, "OEM code" },
383         { 0x03, "Sensor-specific" },
384         { 0, NULL }
385 };
386
387 static const value_string etb3_dscr[] = {
388         { 0x00, "Unspecified" },
389         { 0x02, "OEM code" },
390         { 0x03, "Sensor-specific" },
391         { 0, NULL }
392 };
393
394 static const value_string etb2_oem[] = {
395         { 0x00, "Unspecified" },
396         { 0x01, "Previous state and/or severity" },
397         { 0x02, "OEM code" },
398         { 0, NULL }
399 };
400
401 static const value_string etb3_oem[] = {
402         { 0x00, "Unspecified" },
403         { 0x02, "OEM code" },
404         { 0, NULL }
405 };
406
407 static const value_string etoff_01[] = {
408         { 0x00, "Lower Non-Critical: going low" },
409         { 0x01, "Lower Non-Critical: going high" },
410         { 0x02, "Lower Critical: going low" },
411         { 0x03, "Lower Critical: going high" },
412         { 0x04, "Lower Non-Recoverable: going low" },
413         { 0x05, "Lower Non-Recoverable: going high" },
414         { 0x06, "Upper Non-Critical: going low" },
415         { 0x07, "Upper Non-Critical: going high" },
416         { 0x08, "Upper Critical: going low" },
417         { 0x09, "Upper Critical: going high" },
418         { 0x0a, "Upper Non-Recoverable: going low" },
419         { 0x0b, "Upper Non-Recoverable: going high" },
420         { 0, NULL }
421 };
422
423 static const value_string etoff_02[] = {
424         { 0x00, "Transition to Idle" },
425         { 0x01, "Transition to Active" },
426         { 0x02, "Transition to Busy" },
427         { 0, NULL }
428 };
429
430 static const value_string etoff_03[] = {
431         { 0x00, "State Deasserted" },
432         { 0x01, "State Asserted" },
433         { 0, NULL }
434 };
435
436 static const value_string etoff_04[] = {
437         { 0x00, "Predictive Failure Deasserted" },
438         { 0x01, "Predictive Failure Asserted" },
439         { 0, NULL }
440 };
441
442 static const value_string etoff_05[] = {
443         { 0x00, "Limit Not Exceeded" },
444         { 0x01, "Limit Exceeded" },
445         { 0, NULL }
446 };
447
448 static const value_string etoff_06[] = {
449         { 0x00, "Performance Met" },
450         { 0x01, "Performance Lags" },
451         { 0, NULL }
452 };
453
454 static const value_string etoff_07[] = {
455         { 0x00, "Transition to OK" },
456         { 0x01, "Transition to Non-Critical from OK" },
457         { 0x02, "Transition to Critical from less severe" },
458         { 0x03, "Transition to Non-Recoverable from less severe" },
459         { 0x04, "Transition to Non-Critical from more severe" },
460         { 0x05, "Transition to Critical from Non-Recoverable" },
461         { 0x06, "Transition to Non-Recoverable" },
462         { 0x07, "Monitor" },
463         { 0x08, "Informational" },
464         { 0, NULL }
465 };
466
467 static const value_string etoff_08[] = {
468         { 0x00, "Device Removed/Absent" },
469         { 0x01, "Device Inserted/Present" },
470         { 0, NULL }
471 };
472
473 static const value_string etoff_09[] = {
474         { 0x00, "Device Disabled" },
475         { 0x01, "Device Enabled" },
476         { 0, NULL }
477 };
478
479 static const value_string etoff_0a[] = {
480         { 0x00, "Transition to Running" },
481         { 0x01, "Transition to In Test" },
482         { 0x02, "Transition to Power Off" },
483         { 0x03, "Transition to On Line" },
484         { 0x04, "Transition to Off Line" },
485         { 0x05, "Transition to Off Duty" },
486         { 0x06, "Transition to Degraded" },
487         { 0x07, "Transition to Power Save" },
488         { 0x08, "Install Error" },
489         { 0, NULL }
490 };
491
492 static const value_string etoff_0b[] = {
493         { 0x00, "Fully Redundant" },
494         { 0x01, "Redundancy Lost" },
495         { 0x02, "Redundancy Degraded" },
496         { 0x03, "Non-Redundant: Sufficient Resources from Redundant" },
497         { 0x04, "Non-Redundant: Sufficient Resources from Insufficient Resources" },
498         { 0x05, "Non-Redundant: Insufficient Resources" },
499         { 0x06, "Redundancy Degraded from Fully Redundant" },
500         { 0x07, "Redundancy Degraded from Non-Redundant" },
501         { 0, NULL }
502 };
503
504 static const value_string etoff_0c[] = {
505         { 0x00, "D0 Power State" },
506         { 0x01, "D1 Power State" },
507         { 0x02, "D2 Power State" },
508         { 0x03, "D3 Power State" },
509         { 0, NULL }
510 };
511
512 static gboolean
513 eti_thr_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
514                 guint32 b, guint32 offs _U_, guint32 d)
515 {
516         if (b == 0x1) {
517                 proto_tree_add_text(tree, tvb, 0, 1, "Trigger reading: %d%s",
518                                 d, d == 0xff ? " (unspecified)" : "");
519                 return TRUE;
520         }
521         return FALSE;
522 }
523
524 static gboolean
525 eti_thr_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
526                 guint32 b, guint32 offs _U_, guint32 d)
527 {
528         if (b == 0x1) {
529                 proto_tree_add_text(tree, tvb, 0, 1, "Trigger threshold: %d%s",
530                                 d, d == 0xff ? " (unspecified)" : "");
531                 return TRUE;
532         }
533         return FALSE;
534 }
535
536 static gboolean
537 eti_2_pst_sev(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si,
538                 guint32 b, guint32 offs _U_, guint32 d)
539 {
540         proto_item *ti;
541         proto_tree *s_tree;
542         guint32 tmp;
543         const char *desc;
544
545         if (b == 0x1) {
546                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Previous state/severity");
547                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2);
548                 tmp = d >> 4;
549                 desc = (tmp == 0x0f) ? "Unspecified" : val_to_str(tmp, etoff_07, "Unknown");
550                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sSeverity: %s (0x%02x)",
551                                 ipmi_dcd8(d, 0xf0), desc, tmp);
552                 tmp = d & 0xf;
553                 desc = (tmp == 0x0f) ? "Unspecified" : val_to_str(tmp, si->offsets, "Unknown");
554                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sPrevious state: %s (0x%02x)",
555                                 ipmi_dcd8(d, 0x0f), desc, tmp);
556                 return TRUE;
557         }
558         return FALSE;
559 }
560
561 static const struct evtype_info *
562 get_evtype_info(unsigned int evtype)
563 {
564         static const struct {
565                 unsigned int id;
566                 struct evtype_info eti;
567         } eti_tab[] = {
568                 { 0x01, { etb2_thr,  etb3_thr,  etoff_01, eti_thr_2,  eti_thr_3,  "Threshold" }},
569                 { 0x02, { etb2_dscr, etb3_dscr, etoff_02, eti_2_pst_sev, NULL,    "Discreet" }},
570                 { 0x03, { etb2_dscr, etb3_dscr, etoff_03, eti_2_pst_sev, NULL,    "Discreet" }},
571                 { 0x04, { etb2_dscr, etb3_dscr, etoff_04, eti_2_pst_sev, NULL,    "Discreet" }},
572                 { 0x05, { etb2_dscr, etb3_dscr, etoff_05, eti_2_pst_sev, NULL,    "Discreet" }},
573                 { 0x06, { etb2_dscr, etb3_dscr, etoff_06, eti_2_pst_sev, NULL,    "Discreet" }},
574                 { 0x07, { etb2_dscr, etb3_dscr, etoff_07, eti_2_pst_sev, NULL,    "Discreet" }},
575                 { 0x08, { etb2_dscr, etb3_dscr, etoff_08, eti_2_pst_sev, NULL,    "Discreet" }},
576                 { 0x09, { etb2_dscr, etb3_dscr, etoff_09, eti_2_pst_sev, NULL,    "Discreet" }},
577                 { 0x0a, { etb2_dscr, etb3_dscr, etoff_0a, eti_2_pst_sev, NULL,    "Discreet" }},
578                 { 0x0b, { etb2_dscr, etb3_dscr, etoff_0b, eti_2_pst_sev, NULL,    "Discreet" }},
579                 { 0x0c, { etb2_dscr, etb3_dscr, etoff_0c, eti_2_pst_sev, NULL,    "Discreet" }},
580                 { 0x6f, { etb2_dscr, etb3_dscr, NULL,     eti_2_pst_sev, NULL,    "Sensor-specific" }}
581         };
582         static const struct evtype_info eti_oem = {
583                 etb2_oem, etb3_oem, et_empty, eti_2_pst_sev, NULL, "OEM-specific"
584         };
585         static const struct evtype_info eti_rsrv = {
586                 et_empty, et_empty, et_empty, NULL, NULL, "Reserved"
587         };
588         unsigned int i;
589
590         /* Look for explicitly specified event/reading type */
591         for (i = 0; i < array_length(eti_tab); i++) {
592                 if (eti_tab[i].id == evtype) {
593                         return &eti_tab[i].eti;
594                 }
595         }
596
597         /* Falls in OEM range? */
598         if (evtype >= 0x70 && evtype <= 0x7f) {
599                 return &eti_oem;
600         }
601
602         return &eti_rsrv;
603 }
604
605 static const value_string ssoff_05[] = {
606         { 0x00, "General Chassis Intrusion" },
607         { 0x01, "Drive Bay Intrusion" },
608         { 0x02, "I/O Card Area Intrusion" },
609         { 0x03, "Processor Area Intrusion" },
610         { 0x04, "LAN Leash Lost" },
611         { 0x05, "Unauthorized dock" },
612         { 0x06, "FAN Area Intrusion" },
613         { 0, NULL }
614 };
615
616 static const value_string ssoff_06[] = {
617         { 0x00, "Secure Mode (Front Panel Lockout) Violation Attempt" },
618         { 0x01, "Pre-boot Password Violation: user password" },
619         { 0x02, "Pre-boot Password Violation: setup password" },
620         { 0x03, "Pre-boot Password Violation: network boot password" },
621         { 0x04, "Other pre-boot password violation" },
622         { 0x05, "Out-of-band password violation" },
623         { 0, NULL }
624 };
625
626 static const value_string ssoff_07[] = {
627         { 0x00, "IERR" },
628         { 0x01, "Thermal Trip" },
629         { 0x02, "FRB1/BIST Failure" },
630         { 0x03, "FRB2/Hang in POST Failure" },
631         { 0x04, "FRB3/Processor Startup/Initialization Failure" },
632         { 0x05, "Configuration Error" },
633         { 0x06, "SM BIOS Uncorrectable CPU-complex error" },
634         { 0x07, "Processor Presence Detected" },
635         { 0x08, "Processor Disabled" },
636         { 0x09, "Terminator Presence Detected" },
637         { 0x0a, "Processor Automatically Throttled" },
638         { 0, NULL }
639 };
640
641 static const value_string ssoff_08[] = {
642         { 0x00, "Presence Detected" },
643         { 0x01, "Power Supply Failure Detected" },
644         { 0x02, "Predictive Failure" },
645         { 0x03, "Power Supply input lost (AC/DC)" },
646         { 0x04, "Power Supply input lost or out-of-range" },
647         { 0x05, "Power Supply out-of-range, but present" },
648         { 0x06, "Configuration error" },
649         { 0, NULL }
650 };
651
652 static const value_string ssoff_09[] = {
653         { 0x00, "Power Off / Power Down" },
654         { 0x01, "Power Cycle" },
655         { 0x02, "240VA Power Down" },
656         { 0x03, "Interlock Power Down" },
657         { 0x04, "AC Lost" },
658         { 0x05, "Soft Power Control Failure" },
659         { 0x06, "Power Unit Failure Detected" },
660         { 0x07, "Predictive Failure" },
661         { 0, NULL }
662 };
663
664 static const value_string ssoff_0c[] = {
665         { 0x00, "Correctable ECC/other correctable memory error" },
666         { 0x01, "Uncorrectable ECC/other uncorrectable memory error" },
667         { 0x02, "Parity" },
668         { 0x03, "Memory Scrub Failed" },
669         { 0x04, "Memory Device Disabled" },
670         { 0x05, "Correctable ECC/other correctable memory error: logging limit reached" },
671         { 0x06, "Presence Detected" },
672         { 0x07, "Configuration Error" },
673         { 0x08, "Spare" },
674         { 0x09, "Memory Automatically Throttled" },
675         { 0x0a, "Critical Overtemperature" },
676         { 0, NULL }
677 };
678
679 static const value_string ssoff_0d[] = {
680         { 0x00, "Drive Presence" },
681         { 0x01, "Drive Fault" },
682         { 0x02, "Predictive Failure" },
683         { 0x03, "Hot Spare" },
684         { 0x04, "Consistency Check / Parity Check in progress" },
685         { 0x05, "In Critical Array" },
686         { 0x06, "In Failed Array" },
687         { 0x07, "Rebuild/Remap in progress" },
688         { 0x08, "Rebuild/Remap aborted" },
689         { 0, NULL }
690 };
691
692 static const value_string ssoff_0f[] = {
693         { 0x00, "System Firmware Error (POST Error)" },
694         { 0x01, "System Firmware Hang" },
695         { 0x02, "System Firmware Progress" },
696         { 0, NULL }
697 };
698
699 static const value_string ssoff_10[] = {
700         { 0x00, "Correctable Memory Error Logging Disabled" },
701         { 0x01, "Event type Logging Disabled" },
702         { 0x02, "Log Area Reset/Cleared" },
703         { 0x03, "All Event Logging Disabled" },
704         { 0x04, "SEL Full" },
705         { 0x05, "SEL Almost Full" },
706         { 0, NULL }
707 };
708
709 static const value_string ssoff_11[] = {
710         { 0x00, "BIOS Watchdog Reset" },
711         { 0x01, "OS Watchdog Reset" },
712         { 0x02, "OS Watchdog Shutdown" },
713         { 0x03, "OS Watchdog Power Down" },
714         { 0x04, "OS Watchdog Power Cycle" },
715         { 0x05, "OS Watchdog NMI/Diagnostic Interrupt" },
716         { 0x06, "OS Watchdog Expired, status only" },
717         { 0x07, "OS Watchdog pre-timeout interrupt, non-NMI" },
718         { 0, NULL }
719 };
720
721 static const value_string ssoff_12[] = {
722         { 0x00, "System Reconfigured" },
723         { 0x01, "OEM System Boot Event" },
724         { 0x02, "Undetermined system hardware failure" },
725         { 0x03, "Entry added to Auxillary Log" },
726         { 0x04, "PEF Action" },
727         { 0x05, "Timestamp Clock Synch" },
728         { 0, NULL }
729 };
730
731 static const value_string ssoff_13[] = {
732         { 0x00, "Front Panel NMI/Diagnostic Interrupt" },
733         { 0x01, "Bus Timeout" },
734         { 0x02, "I/O Channel Check NMI" },
735         { 0x03, "Software NMI" },
736         { 0x04, "PCI PERR" },
737         { 0x05, "PCI SERR" },
738         { 0x06, "EISA Fail Safe Timeout" },
739         { 0x07, "Bus Correctable Error" },
740         { 0x08, "Bus Uncorrectable Error" },
741         { 0x09, "Fatal NMI" },
742         { 0x0a, "Bus Fatal Error" },
743         { 0x0b, "Bus Degraded" },
744         { 0, NULL }
745 };
746
747 static const value_string ssoff_14[] = {
748         { 0x00, "Power Button Pressed" },
749         { 0x01, "Sleep Button Pressed" },
750         { 0x02, "Reset Button Pressed" },
751         { 0x03, "FRU Latch open" },
752         { 0x04, "FRU Service Request Button Pressed" },
753         { 0, NULL }
754 };
755
756 static const value_string ssoff_19[] = {
757         { 0x00, "Soft Power Control Failure" },
758         { 0, NULL }
759 };
760
761 static const value_string ssoff_1b[] = {
762         { 0x00, "Cable/Interconnect is connected" },
763         { 0x01, "Configuration error - Incorrect cable connected / Incorrect interconnection" },
764         { 0, NULL }
765 };
766
767 static const value_string ssoff_1d[] = {
768         { 0x00, "Initiated by Power Up" },
769         { 0x01, "Initiated by hard reset" },
770         { 0x02, "Initiated by warm reset" },
771         { 0x03, "User requested PXE boot" },
772         { 0x04, "Automatic boot to diagnostic" },
773         { 0x05, "OS / run-time software initiated hard reset" },
774         { 0x06, "OS / run-time software initiated warm reset" },
775         { 0x07, "System Restart" },
776         { 0, NULL }
777 };
778
779 static const value_string ssoff_1e[] = {
780         { 0x00, "No bootable media" },
781         { 0x01, "No bootable diskette left in drive" },
782         { 0x02, "PXE Server not found" },
783         { 0x03, "Invalid boot sector" },
784         { 0x04, "Timeout waiting for user selection of boot source" },
785         { 0, NULL }
786 };
787
788 static const value_string ssoff_1f[] = {
789         { 0x00, "A: boot completed" },
790         { 0x01, "C: boot completed" },
791         { 0x02, "PXE boot completed" },
792         { 0x03, "Diagnostic boot completed" },
793         { 0x04, "CD-ROM boot completed" },
794         { 0x05, "ROM boot completed" },
795         { 0x06, "Boot completed - boot device not specified" },
796         { 0, NULL }
797 };
798
799 static const value_string ssoff_20[] = {
800         { 0x00, "Critical stop during OS load/initialization" },
801         { 0x01, "Run-time critical stop" },
802         { 0x02, "OS Graceful Stop" },
803         { 0x03, "OS Graceful Shutdown" },
804         { 0x04, "Soft Shutdown initiated by PEF" },
805         { 0x05, "Agent Not Responding" },
806         { 0, NULL }
807 };
808
809 static const value_string ssoff_21[] = {
810         { 0x00, "Fault Status asserted" },
811         { 0x01, "Identify Status asserted" },
812         { 0x02, "Slot/Connector Device installed/attached" },
813         { 0x03, "Slot/Connector Ready for Device Installation" },
814         { 0x04, "Slot/Connector Ready for Device Removal" },
815         { 0x05, "Slot Power is Off" },
816         { 0x06, "Slot/Connector Device Removal Request" },
817         { 0x07, "Interlock Asserted" },
818         { 0x08, "Slot is Disabled" },
819         { 0x09, "Slot holds spare device" },
820         { 0, NULL }
821 };
822
823 static const value_string ssoff_22[] = {
824         { 0x00, "S0/G0 'working'" },
825         { 0x01, "S1 'sleeping with system h/w & processor context maintained'" },
826         { 0x02, "S2 'sleeping, processor context lost'" },
827         { 0x03, "S3 'sleeping, processor & h/w, memory retained'" },
828         { 0x04, "S4 'non-volatile sleep / suspend-to-disk'" },
829         { 0x05, "S5/G2 'soft-off'" },
830         { 0x06, "S4/S5 'soft-off', particular S4/S5 state cannot be determined" },
831         { 0x07, "G3 / Mechanical Off" },
832         { 0x08, "Sleeping in S1, S2 or S3 states" },
833         { 0x09, "G1 sleeping" },
834         { 0x0a, "S5 entered by override" },
835         { 0x0b, "Legacy ON state" },
836         { 0x0c, "Legacy OFF state" },
837         { 0x0e, "Unknown" },
838         { 0, NULL }
839 };
840
841 static const value_string ssoff_23[] = {
842         { 0x00, "Timer expired, status only" },
843         { 0x01, "Hard Reset" },
844         { 0x02, "Power Down" },
845         { 0x03, "Power Cycle" },
846         { 0x08, "Timer Interrupt" },
847         { 0, NULL }
848 };
849
850 static const value_string ssoff_24[] = {
851         { 0x00, "Platform Generated Page" },
852         { 0x01, "Platform Generated LAN Event" },
853         { 0x02, "Platform Event Trap generated" },
854         { 0x03, "Platform generated SNMP trap" },
855         { 0, NULL }
856 };
857
858 static const value_string ssoff_25[] = {
859         { 0x00, "Entity Present" },
860         { 0x01, "Entity Absent" },
861         { 0x02, "Entity Disabled" },
862         { 0, NULL }
863 };
864
865 static const value_string ssoff_27[] = {
866         { 0x00, "LAN Heartbeat Lost" },
867         { 0x01, "LAN Heartbeat" },
868         { 0, NULL }
869 };
870
871 static const value_string ssoff_28[] = {
872         { 0x00, "Sensor access degraded or unavailable" },
873         { 0x01, "Controller access degraded or unavailable" },
874         { 0x02, "Management controller off-line" },
875         { 0x03, "Management controller unavailable" },
876         { 0x04, "Sensor failure" },
877         { 0x05, "FRU failure" },
878         { 0, NULL }
879 };
880
881 static const value_string ssoff_29[] = {
882         { 0x00, "Battery low" },
883         { 0x01, "Battery failed" },
884         { 0x02, "Battery presence detected" },
885         { 0, NULL }
886 };
887
888 static const value_string ssoff_2a[] = {
889         { 0x00, "Session Activated" },
890         { 0x01, "Session Deactivated" },
891         { 0, NULL }
892 };
893
894 static const value_string ssoff_2b[] = {
895         { 0x00, "Hardware change detected with associated Entity" },
896         { 0x01, "Firmware or software change detected with associated Entity" },
897         { 0x02, "Hardware incompatibility detected with associated Entity" },
898         { 0x03, "Firmware or software incompatibility detected with associated Entity" },
899         { 0x04, "Entity is of an invalid or unsupported hardware version" },
900         { 0x05, "Entity contains an invalid or unsupported firmware or software version" },
901         { 0x06, "Hardware Change detected with associated Entity was successful" },
902         { 0x07, "Software or Firmware Change detected with associated Entity was successful" },
903         { 0, NULL }
904 };
905
906 static const value_string ssoff_2c[] = {
907         { 0x00, "M0 - FRU Not Installed" },
908         { 0x01, "M1 - FRU Inactive" },
909         { 0x02, "M2 - FRU Activation Requested" },
910         { 0x03, "M3 - FRU Activation In Progress" },
911         { 0x04, "M4 - FRU Active" },
912         { 0x05, "M5 - FRU Deactivation Requested" },
913         { 0x06, "M6 - FRU Deactivation In Progress" },
914         { 0x07, "M7 - FRU Communication Lost" },
915         { 0, NULL }
916 };
917
918 static const value_string ssoff_f0[] = {
919         { 0x00, "M0 - FRU Not Installed" },
920         { 0x01, "M1 - FRU Inactive" },
921         { 0x02, "M2 - FRU Activation Requested" },
922         { 0x03, "M3 - FRU Activation In Progress" },
923         { 0x04, "M4 - FRU Active" },
924         { 0x05, "M5 - FRU Deactivation Requested" },
925         { 0x06, "M6 - FRU Deactivation In Progress" },
926         { 0x07, "M7 - FRU Communication Lost" },
927         { 0, NULL }
928 };
929
930 static const value_string ssoff_f1[] = {
931         { 0x00, "IPMB-A disabled, IPMB-B disabled" },
932         { 0x01, "IPMB-A enabled, IPMB-B disabled" },
933         { 0x02, "IPMB-A disabled, IPMB-B enabled" },
934         { 0x03, "IPMB-A enabled, IPMB-B enabled" },
935         { 0, NULL }
936 };
937
938 static const value_string ssoff_f2[] = {
939         { 0x00, "Module handle closed" },
940         { 0x01, "Module handle open" },
941         { 0x02, "Quiesced" },
942         { 0x03, "Backend Power Failure" },
943         { 0x04, "Backend Power Shut Down" },
944         { 0, NULL }
945 };
946
947 static const value_string ssoff_f3[] = {
948         { 0x00, "Global status change" },
949         { 0x01, "Channel status change" },
950         { 0, NULL }
951 };
952
953 static const value_string ssoff_f4[] = {
954         { 0x00, "Minor Reset" },
955         { 0x01, "Major Reset" },
956         { 0x02, "Alarm Cutoff" },
957         { 0, NULL }
958 };
959
960 static gboolean
961 ssi_05_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
962                 guint32 b, guint32 offs, guint32 d)
963 {
964         if (b == 0x3 && offs == 0x04) {
965                 /* LAN Leash Lost */
966                 proto_tree_add_text(tree, tvb, 0, 1, "Network controller #: %d", d);
967                 return TRUE;
968         }
969         return FALSE;
970 }
971
972 static gboolean
973 ssi_08_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
974                 guint32 b, guint32 offs, guint32 d)
975 {
976         static const value_string err_vals[] = {
977                 { 0x00, "Vendor mismatch" },
978                 { 0x01, "Revision mismatch" },
979                 { 0x02, "Processor missing" },
980                 { 0, NULL }
981         };
982         proto_item *ti;
983         proto_tree *s_tree;
984         guint32 tmp;
985
986         if (b == 0x3 && offs == 0x06) {
987                 /* Configuration error */
988                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Error type");
989                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte3);
990                 tmp = d & 0x0f;
991                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sError type: %s (0x%02x)",
992                                 ipmi_dcd8(d, 0x0f), val_to_str(tmp, err_vals, "Reserved"), tmp);
993                 return TRUE;
994         }
995         return FALSE;
996 }
997
998 static gboolean
999 ssi_0c_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1000                 guint32 b, guint32 offs _U_, guint32 d)
1001 {
1002         if (b == 0x3) {
1003                 proto_tree_add_text(tree, tvb, 0, 1, "Memory module/device ID: %d", d);
1004                 return TRUE;
1005         }
1006         return FALSE;
1007 }
1008
1009 static gboolean
1010 ssi_0f_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1011                 guint32 b, guint32 offs, guint32 d)
1012 {
1013         static const value_string err_vals[] = {
1014                 { 0x00, "Unspecified" },
1015                 { 0x01, "No system memory is physically installed" },
1016                 { 0x02, "No usable system memory" },
1017                 { 0x03, "Unrecoverable hard-disk/ATAPI/IDE device failure" },
1018                 { 0x04, "Unrecoverable system board failure" },
1019                 { 0x05, "Unrecoverable diskette subsystem failure" },
1020                 { 0x06, "Unrecoverable hard-disk controller failure" },
1021                 { 0x07, "Unrecoverable PS/2 or USB keyboard failure" },
1022                 { 0x08, "Removable boot media not found" },
1023                 { 0x09, "Unrecoverable video controller failure" },
1024                 { 0x0a, "No video device detected" },
1025                 { 0x0b, "Firmware (BIOS) ROM corruption detected" },
1026                 { 0x0c, "CPU voltage mismatch" },
1027                 { 0x0d, "CPU speed matching failure" },
1028                 { 0, NULL }
1029         };
1030         static const value_string progress_vals[] = {
1031                 { 0x00, "Unspecified" },
1032                 { 0x01, "Memory initialization" },
1033                 { 0x02, "Hard-disk initialization" },
1034                 { 0x03, "Secondary processor(s) initialization" },
1035                 { 0x04, "User authentication" },
1036                 { 0x05, "User-initiated system setup" },
1037                 { 0x06, "USB resource configuration" },
1038                 { 0x07, "PCI resource configuration" },
1039                 { 0x08, "Option ROM initialization" },
1040                 { 0x09, "Video initialization" },
1041                 { 0x0a, "Cache initialization" },
1042                 { 0x0b, "SM Bus initialization" },
1043                 { 0x0c, "Keyboard controller initialization" },
1044                 { 0x0d, "Embedded controller / management controller initialization" },
1045                 { 0x0e, "Docking station attachment" },
1046                 { 0x0f, "Enabling docking station" },
1047                 { 0x10, "Docking station ejection" },
1048                 { 0x11, "Disabling docking station" },
1049                 { 0x12, "Calling operating system wake-up vector" },
1050                 { 0x13, "Starting operating system boot process" },
1051                 { 0x14, "Baseboard or motherboard initialization" },
1052                 { 0x16, "Floppy initialization" },
1053                 { 0x17, "Keyboard test" },
1054                 { 0x18, "Pointing device test" },
1055                 { 0x19, "Primary processor initialization" },
1056                 { 0, NULL }
1057         };
1058
1059         if (b == 0x3 && offs == 0x00) {
1060                 proto_tree_add_text(tree, tvb, 0, 1, "Extension code: %s (0x%02x)",
1061                                 val_to_str(d, err_vals, "Reserved"), d);
1062                 return TRUE;
1063         }
1064         if (b == 0x3 && (offs == 0x01 || offs == 0x02)) {
1065                 proto_tree_add_text(tree, tvb, 0, 1, "Extension code: %s (0x%02x)",
1066                                 val_to_str(d, progress_vals, "Reserved"), d);
1067                 return TRUE;
1068         }
1069         return FALSE;
1070 }
1071
1072 static const struct evtype_info *ssi_10_saveptr;
1073
1074 static gboolean
1075 ssi_10_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1076                 guint32 b, guint32 offs, guint32 d)
1077 {
1078         if (b == 0x3 && offs == 0x00) {
1079                 proto_tree_add_text(tree, tvb, 0, 1, "Memory module/device ID: %d", d);
1080                 return TRUE;
1081         }
1082         if (b == 0x3 && offs == 0x01) {
1083                 ssi_10_saveptr = get_evtype_info(d);
1084                 proto_tree_add_text(tree, tvb, 0, 1, "Event/reading type: %s (0x%02x)",
1085                                 ssi_10_saveptr->desc, d);
1086                 return TRUE;
1087         }
1088         return FALSE;
1089 }
1090
1091 static gboolean
1092 ssi_10_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1093                 guint32 b, guint32 offs, guint32 d)
1094 {
1095         proto_item *ti;
1096         proto_tree *s_tree;
1097         const value_string *off_vals;
1098
1099         if (b == 0x3 && offs == 0x01) {
1100                 if (!ssi_10_saveptr) {
1101                         return FALSE; /* something went wrong */
1102                 }
1103                 off_vals = ssi_10_saveptr->offsets ? ssi_10_saveptr->offsets : et_empty;
1104                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Logging details/Offset");
1105                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte3);
1106                 proto_tree_add_text(tree, tvb, 0, 1, "%sLogging disable for all events of given type: %s",
1107                                 ipmi_dcd8(d, 0x20), (d & 0x20) ? "True" : "False");
1108                 proto_tree_add_text(tree, tvb, 0, 1, "%s%s event",
1109                                 ipmi_dcd8(d, 0x10), (d & 0x10) ? "Deassertion" : "Assertion");
1110                 d &= 0x0f;
1111                 proto_tree_add_text(tree, tvb, 0, 1, "%sEvent Offset: %s (0x%02x)",
1112                                 ipmi_dcd8(d, 0x0f), val_to_str(d, off_vals, "Unknown"), d);
1113                 return TRUE;
1114         }
1115         if (b == 0x3 && offs == 0x05) {
1116                 proto_tree_add_text(tree, tvb, 0, 1, "SEL filled: %d%%", d);
1117                 return TRUE;
1118         }
1119         return FALSE;
1120 }
1121
1122 static gboolean
1123 ssi_12_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1124                 guint32 b, guint32 offs, guint32 d)
1125 {
1126         static const value_string act_vals[] = {
1127                 { 0x00, "Entry added" },
1128                 { 0x01, "Entry added because event did not map to standard IPMI event" },
1129                 { 0x02, "Entry added along with one or more corresponding SEL entries" },
1130                 { 0x03, "Log cleared" },
1131                 { 0x04, "Log disabled" },
1132                 { 0x05, "Log enabled" },
1133                 { 0, NULL }
1134         };
1135         static const value_string type_vals[] = {
1136                 { 0x00, "MCA Log" },
1137                 { 0x01, "OEM 1" },
1138                 { 0x02, "OEM 2" },
1139                 { 0, NULL }
1140         };
1141         static const value_string clock_vals[] = {
1142                 { 0x00, "SEL Timestamp Clock updated" },
1143                 { 0x01, "SDR Timestamp Clock updated" },
1144                 { 0, NULL }
1145         };
1146         proto_item *ti;
1147         proto_tree *s_tree;
1148         guint32 tmp;
1149
1150         if (b == 0x3 && offs == 0x03) {
1151                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Log action/type");
1152                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2);
1153                 tmp = d >> 4;
1154                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sLog entry action: %s (0x%02x)",
1155                                 ipmi_dcd8(d, 0xf0), val_to_str(tmp, act_vals, "Reserved"), tmp);
1156                 tmp = d & 0x0f;
1157                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sLog type: %s (0x%02x)",
1158                                 ipmi_dcd8(d, 0x0f), val_to_str(tmp, type_vals, "Reserved"), tmp);
1159                 return TRUE;
1160         }
1161         if (b == 0x3 && offs == 0x04) {
1162                 ti = proto_tree_add_text(tree, tvb, 0, 1, "PEF Actions to be taken");
1163                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2);
1164                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sDiagnostic interrupt (NMI): %s",
1165                                 ipmi_dcd8(d, 0x20), (d & 0x20) ? "True" : "False");
1166                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sOEM Action: %s",
1167                                 ipmi_dcd8(d, 0x10), (d & 0x10) ? "True" : "False");
1168                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sPower Cycle: %s",
1169                                 ipmi_dcd8(d, 0x08), (d & 0x08) ? "True" : "False");
1170                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sReset: %s",
1171                                 ipmi_dcd8(d, 0x04), (d & 0x04) ? "True" : "False");
1172                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sPower Off: %s",
1173                                 ipmi_dcd8(d, 0x02), (d & 0x02) ? "True" : "False");
1174                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sAlert: %s",
1175                                 ipmi_dcd8(d, 0x01), (d & 0x01) ? "True" : "False");
1176                 return TRUE;
1177         }
1178         if (b == 0x3 && offs == 0x05) {
1179                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Details");
1180                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2);
1181                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sEvent is %s of pair",
1182                                 ipmi_dcd8(d, 0x80), (d & 0x80) ? "second" : "first");
1183                 tmp = d & 0x0f;
1184                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sTimestamp clock type: %s (0x%02x)",
1185                                 ipmi_dcd8(d, 0x0f), val_to_str(tmp, clock_vals, "Reserved"), tmp);
1186         }
1187         return FALSE;
1188 }
1189
1190 static gboolean
1191 ssi_19_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1192                 guint32 b, guint32 offs, guint32 d)
1193 {
1194         if (b == 0x3 && offs == 0x00) {
1195                 proto_tree_add_text(tree, tvb, 0, 1, "Requested power state: %s (0x%02x)",
1196                                 val_to_str(d, ssoff_22, "Reserved"), d);
1197                 return TRUE;
1198         }
1199         return FALSE;
1200 }
1201
1202 static gboolean
1203 ssi_19_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1204                 guint32 b, guint32 offs, guint32 d)
1205 {
1206         if (b == 0x3 && offs == 0x00) {
1207                 proto_tree_add_text(tree, tvb, 0, 1, "Power state at time of request: %s (0x%02x)",
1208                                 val_to_str(d, ssoff_22, "Reserved"), d);
1209                 return TRUE;
1210         }
1211         return FALSE;
1212 }
1213
1214 static gboolean
1215 ssi_1d_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1216                 guint32 b, guint32 offs, guint32 d)
1217 {
1218         /* Copied from ipmi_chassis.c */
1219         static const value_string cause_vals[] = {
1220                 { 0x00, "Unknown" },
1221                 { 0x01, "Chassis Control command" },
1222                 { 0x02, "Reset via pushbutton" },
1223                 { 0x03, "Power-up via pushbutton" },
1224                 { 0x04, "Watchdog expiration" },
1225                 { 0x05, "OEM" },
1226                 { 0x06, "Automatic power-up on AC being applied due to 'always restore' power restore policy" },
1227                 { 0x07, "Automatic power-up on AC being applied due to 'restore previous power state' power restore policy" },
1228                 { 0x08, "Reset via PEF" },
1229                 { 0x09, "Power-cycle via PEF" },
1230                 { 0x0a, "Soft reset" },
1231                 { 0x0b, "Power-up via RTC wakeup" },
1232                 { 0, NULL }
1233         };
1234         proto_item *ti;
1235         proto_tree *s_tree;
1236         guint32 tmp;
1237
1238         if (b == 0x3 && offs == 0x07) {
1239                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Restart cause");
1240                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2);
1241                 tmp = d & 0x0f;
1242                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sRestart cause: %s (0x%02x)",
1243                                 ipmi_dcd8(d, 0x0f), val_to_str(tmp, cause_vals, "Reserved"), tmp);
1244                 return TRUE;
1245         }
1246         return FALSE;
1247 }
1248
1249 static gboolean
1250 ssi_1d_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1251                 guint32 b, guint32 offs, guint32 d)
1252 {
1253         gchar s[ITEM_LABEL_LENGTH];
1254
1255         ipmi_fmt_channel(s, d);
1256         if (b == 0x3 && offs == 0x07) {
1257                 proto_tree_add_text(tree, tvb, 0, 1, "Channel: %s", s);
1258                 return TRUE;
1259         }
1260         return FALSE;
1261 }
1262
1263 static gboolean
1264 ssi_21_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1265                 guint32 b, guint32 offs _U_, guint32 d)
1266 {
1267         static const value_string type_vals[] = {
1268                 { 0x00, "PCI" },
1269                 { 0x01, "Drive Array" },
1270                 { 0x02, "External Peripheral Connector" },
1271                 { 0x03, "Docking" },
1272                 { 0x04, "Other standard internal expansion slot" },
1273                 { 0x05, "Slot associated with entity specified by Entity ID for sensor" },
1274                 { 0x06, "AdvancedTCA" },
1275                 { 0x07, "DIMM/Memory device" },
1276                 { 0x08, "FAN" },
1277                 { 0x09, "PCI Express" },
1278                 { 0x0a, "SCSI (parallel)" },
1279                 { 0x0b, "SATA/SAS" },
1280                 { 0, NULL }
1281         };
1282
1283         if (b == 0x3) {
1284                 proto_tree_add_text(tree, tvb, 0, 1, "Slot/connector type: %s (0x%02x)",
1285                                 val_to_str(d, type_vals, "Reserved"), d);
1286                 return TRUE;
1287         }
1288         return FALSE;
1289 }
1290
1291 static gboolean
1292 ssi_21_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1293                 guint32 b, guint32 offs _U_, guint32 d)
1294 {
1295         if (b == 0x3) {
1296                 proto_tree_add_text(tree, tvb, 0, 1, "Slot/connector #: %d", d);
1297                 return TRUE;
1298         }
1299         return FALSE;
1300 }
1301
1302 static gboolean
1303 ssi_23_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1304                 guint32 b, guint32 offs _U_, guint32 d)
1305 {
1306         static const value_string intr_vals[] = {
1307                 { 0x00, "None" },
1308                 { 0x01, "SMI" },
1309                 { 0x02, "NMI" },
1310                 { 0x03, "Messaging interrupt" },
1311                 { 0x0f, "Unspecified" },
1312                 { 0, NULL }
1313         };
1314         static const value_string use_vals[] = {
1315                 { 0x01, "BIOS FRB2" },
1316                 { 0x02, "BIOS/POST" },
1317                 { 0x03, "OS Load" },
1318                 { 0x04, "SMS/OS" },
1319                 { 0x05, "OEM" },
1320                 { 0x0f, "Unspecified" },
1321                 { 0, NULL }
1322         };
1323         proto_item *ti;
1324         proto_tree *s_tree;
1325         guint32 tmp;
1326
1327         if (b == 0x3) {
1328                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Timer use/interrupt");
1329                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2);
1330                 tmp = d >> 4;
1331                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sInterrupt type: %s (0x%02x)",
1332                                 ipmi_dcd8(d, 0xf0), val_to_str(tmp, intr_vals, "Reserved"), tmp);
1333                 tmp = d & 0x0f;
1334                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sTimer use at expiration: %s (0x%02x)",
1335                                 ipmi_dcd8(d, 0x0f), val_to_str(tmp, use_vals, "Reserved"), tmp);
1336
1337                 return TRUE;
1338         }
1339         return FALSE;
1340 }
1341
1342 static int ssi28_is_logical_fru;
1343
1344 static gboolean
1345 ssi_28_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1346                 guint32 b, guint32 offs _U_, guint32 d)
1347 {
1348         proto_item *ti;
1349         proto_tree *s_tree;
1350         guint32 tmp;
1351
1352         if (b == 0x3 && (offs == 0x00 || offs == 0x04)) {
1353                 proto_tree_add_text(tree, tvb, 0, 1, "Sensor number: %d", d);
1354                 return TRUE;
1355         }
1356         if (b == 0x3 && offs == 0x05) {
1357                 ti = proto_tree_add_text(tree, tvb, 0, 1, "FRU details");
1358                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2);
1359                 ssi28_is_logical_fru = (d & 0x80) ? 1 : 0;
1360                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sLogical FRU device: %s",
1361                                 ipmi_dcd8(d, 0x80), ssi28_is_logical_fru ? "True" : "False");
1362                 tmp = (d & 0x18) >> 3;
1363                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sLUN for Master Read-Write command: 0x%02x",
1364                                 ipmi_dcd8(d, 0x18), tmp);
1365                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sPrivate Bus ID: 0x%02x",
1366                                 ipmi_dcd8(d, 0x07), d & 0x07);
1367                 return TRUE;
1368         }
1369         return FALSE;
1370 }
1371
1372 static gboolean
1373 ssi_28_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1374                 guint32 b, guint32 offs _U_, guint32 d)
1375 {
1376         if (b == 0x3 && offs == 0x05) {
1377                 if (ssi28_is_logical_fru == -1) {
1378                         return FALSE; /* something went wrong */
1379                 }
1380                 if (ssi28_is_logical_fru) {
1381                         proto_tree_add_text(tree, tvb, 0, 1, "FRU Device ID within controller: 0x%02x", d);
1382                 } else {
1383                         proto_tree_add_text(tree, tvb, 0, 1, "I2C Slave Address: 0x%02x", d);
1384                 }
1385                 return TRUE;
1386         }
1387         return FALSE;
1388 }
1389
1390 static gboolean
1391 ssi_2a_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1392                 guint32 b, guint32 offs _U_, guint32 d)
1393 {
1394         proto_item *ti;
1395         proto_tree *s_tree;
1396
1397         if (b == 0x3) {
1398                 d &= 0x3f;
1399                 ti = proto_tree_add_text(tree, tvb, 0, 1, "User ID: %d", d);
1400                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2);
1401                 if (d) {
1402                         proto_tree_add_text(s_tree, tvb, 0, 1, "%sUser ID: %d",
1403                                         ipmi_dcd8(d, 0x3f), d);
1404                 } else {
1405                         proto_tree_add_text(s_tree, tvb, 0, 1, "%sUser ID: unspecified (%d)",
1406                                         ipmi_dcd8(d, 0x3f), d);
1407                 }
1408         }
1409         return FALSE;
1410 }
1411
1412 static gboolean
1413 ssi_2a_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1414                 guint32 b, guint32 offs _U_, guint32 d)
1415 {
1416         static const value_string deact_vals[] = {
1417                 { 0x00, "Unspecified cause" },
1418                 { 0x01, "Close Session command" },
1419                 { 0x02, "Timeout" },
1420                 { 0x03, "Configuration change" },
1421                 { 0, NULL }
1422         };
1423         proto_item *ti;
1424         proto_tree *s_tree;
1425         gchar s[ITEM_LABEL_LENGTH];
1426         guint32 tmp;
1427
1428         if (b == 0x3) {
1429                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Deactivation cause/Channel #");
1430                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte3);
1431                 tmp = (d >> 4) & 0x3;
1432                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sSession deactivated by: %s (0x%02x)",
1433                                 ipmi_dcd8(d, 0x30), val_to_str(tmp, deact_vals, "Reserved"), tmp);
1434                 ipmi_fmt_channel(s, d & 0xf);
1435                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sChannel: %s",
1436                                 ipmi_dcd8(d, 0x0f), s);
1437                 return TRUE;
1438         }
1439         return FALSE;
1440 }
1441
1442 static gboolean
1443 ssi_2b_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1444                 guint32 b, guint32 offs _U_, guint32 d)
1445 {
1446         static const value_string vctype_vals[] = {
1447                 { 0x00, "Unspecified" },
1448                 { 0x01, "Management controller device ID" },
1449                 { 0x02, "Management controller firmware revision" },
1450                 { 0x03, "Management controller device revision" },
1451                 { 0x04, "Management controller manufacturer ID" },
1452                 { 0x05, "Management controller IPMI version" },
1453                 { 0x06, "Management controller auxillary firmware ID" },
1454                 { 0x07, "Management controller firmware boot block" },
1455                 { 0x08, "Other management controller firmware" },
1456                 { 0x09, "System firmware (EFI/BIOS) change" },
1457                 { 0x0a, "SMBIOS change" },
1458                 { 0x0b, "Operating system change" },
1459                 { 0x0c, "Operating system loader change" },
1460                 { 0x0d, "Service or diagnostic partition change" },
1461                 { 0x0e, "Management software agent change" },
1462                 { 0x0f, "Management software application change" },
1463                 { 0x10, "Management software middleware change" },
1464                 { 0x11, "Programmable hardware change" },
1465                 { 0x12, "Board/FRU module change" },
1466                 { 0x13, "Board/FRU component change" },
1467                 { 0x14, "Board/FRU replaced with equivalent version" },
1468                 { 0x15, "Board/FRU replaced with newer version" },
1469                 { 0x16, "Board/FRU replaced with older version" },
1470                 { 0x17, "Board/FRU configuration change" },
1471                 { 0, NULL }
1472         };
1473
1474         if (b == 0x3) {
1475                 proto_tree_add_text(tree, tvb, 0, 1, "Version change type: %s",
1476                                 val_to_str(d, vctype_vals, "Reserved"));
1477                 return TRUE;
1478         }
1479         return FALSE;
1480 }
1481
1482 static gboolean
1483 ssi_2c_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si,
1484                 guint32 b, guint32 offs _U_, guint32 d)
1485 {
1486         static const value_string cause_vals[] = {
1487                 { 0x00, "Normal State Change" },
1488                 { 0x01, "Change commanded by software external to FRU" },
1489                 { 0x02, "State Change due to operator changing a handle latch" },
1490                 { 0x03, "State Change due to operator pressing the hot swap push button" },
1491                 { 0x04, "State Change due to FRU programmatic action" },
1492                 { 0x05, "Communication lost" },
1493                 { 0x06, "Communication lost due to local failure" },
1494                 { 0x07, "State Change due to unexpected extraction" },
1495                 { 0x08, "State Change due to operator intervention/update" },
1496                 { 0x09, "Unable to compute IPMB address" },
1497                 { 0x0a, "Unexpected Deactivation" },
1498                 { 0x0f, "State Change, Cause Unknown" },
1499                 { 0, NULL }
1500         };
1501         proto_item *ti;
1502         proto_tree *s_tree;
1503         guint32 tmp;
1504
1505         if (b == 0x3) {
1506                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Previous state/Cause");
1507                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2);
1508                 tmp = d >> 4;
1509                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sCause: %s (0x%02x)",
1510                                 ipmi_dcd8(d, 0xf0), val_to_str(tmp, cause_vals, "Reserved"), tmp);
1511                 tmp = d & 0xf;
1512                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sPrevious state: %s (0x%02x)",
1513                                 ipmi_dcd8(d, 0x0f), val_to_str(tmp, si->offsets, "Reserved"), tmp);
1514                 return TRUE;
1515         }
1516         return FALSE;
1517 }
1518
1519 static gboolean
1520 ssi_f0_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si,
1521                 guint32 b, guint32 offs _U_, guint32 d)
1522 {
1523         static const value_string cause_vals[] = {
1524                 { 0x00, "Normal State Change" },
1525                 { 0x01, "Change Commanded by Shelf Manager with Set FRU Activation" },
1526                 { 0x02, "State Change due to operator changing a Handle Switch" },
1527                 { 0x03, "State Change due to FRU programmatic action" },
1528                 { 0x04, "Communication Lost or Regained" },
1529                 { 0x05, "Communication Lost or Regained - locally detected" },
1530                 { 0x06, "Surprise State Change due to extraction" },
1531                 { 0x07, "State Change due to provided information" },
1532                 { 0x08, "Invalid Hardware Address Detected" },
1533                 { 0x09, "Unexpected Deactivation" },
1534                 { 0x0f, "State Change, Cause Unknown" },
1535                 { 0, NULL }
1536         };
1537         proto_item *ti;
1538         proto_tree *s_tree;
1539         guint32 tmp;
1540
1541         if (b == 0x2) {
1542                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Previous state/Cause");
1543                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2);
1544                 tmp = d >> 4;
1545                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sCause: %s (0x%02x)",
1546                                 ipmi_dcd8(d, 0xf0), val_to_str(tmp, cause_vals, "Reserved"), tmp);
1547                 tmp = d & 0xf;
1548                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sPrevious state: %s (0x%02x)",
1549                                 ipmi_dcd8(d, 0x0f), val_to_str(tmp, si->offsets, "Reserved"), tmp);
1550                 return TRUE;
1551         }
1552         return FALSE;
1553 }
1554
1555 static gboolean
1556 ssi_f0_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1557                 guint32 b, guint32 offs _U_, guint32 d)
1558 {
1559         if (b == 0x2) {
1560                 proto_tree_add_text(tree, tvb, 0, 1, "FRU Id: %d", d);
1561                 return TRUE;
1562         }
1563         return FALSE;
1564 }
1565
1566 static gboolean
1567 ssi_f1_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1568                 guint32 b, guint32 offs _U_, guint32 d)
1569 {
1570         proto_item *ti;
1571         proto_tree *s_tree;
1572         gchar s[ITEM_LABEL_LENGTH];
1573
1574         if (b == 0x02) {
1575                 ipmi_fmt_channel(s, d >> 4);
1576                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Channel: %s", s);
1577                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2);
1578                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sChannel: %s",
1579                                 ipmi_dcd8(d, 0xf0), s);
1580                 return TRUE;
1581         }
1582         return FALSE;
1583 }
1584
1585 static gboolean
1586 ssi_f1_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1587                 guint32 b, guint32 offs _U_, guint32 d)
1588 {
1589         static const char *override_state[2] = {
1590                 "Override state, bus isolated",
1591                 "Local control state"
1592         };
1593         static const value_string status_vals[] = {
1594                 { 0x00, "No failure" },
1595                 { 0x01, "Unable to drive clock HI" },
1596                 { 0x02, "Unable to drive data HI" },
1597                 { 0x03, "Unable to drive clock LO" },
1598                 { 0x04, "Unable to drive data LO" },
1599                 { 0x05, "Clock low timeout" },
1600                 { 0x06, "Under test" },
1601                 { 0x07, "Undiagnosed communications failure" },
1602                 { 0, NULL }
1603         };
1604         proto_item *ti;
1605         proto_tree *s_tree;
1606         guint32 tmp;
1607
1608         if (b == 0x02) {
1609                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Override state / Local status");
1610                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte3);
1611                 tmp = d & 0x80;
1612                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sIPMB-B Override state: %s",
1613                                 ipmi_dcd8(d, 0x80), override_state[!!tmp]);
1614                 tmp = (d & 0x70) >> 4;
1615                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sIPMB-B Local status: %s (0x%02x)",
1616                                 ipmi_dcd8(d, 0x70), val_to_str(tmp, status_vals, "Reserved"), tmp);
1617                 tmp = d & 0x08;
1618                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sIPMB-A Override state: %s",
1619                                 ipmi_dcd8(d, 0x08), override_state[!!tmp]);
1620                 tmp = d & 0x07;
1621                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sIPMB-A Local status: %s (0x%02x)",
1622                                 ipmi_dcd8(d, 0x07), val_to_str(tmp, status_vals, "Reserved"), tmp);
1623                 return TRUE;
1624         }
1625         return FALSE;
1626 }
1627
1628 static gboolean
1629 ssi_f3_2(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1630                 guint32 b, guint32 offs, guint32 d)
1631 {
1632         proto_tree *s_tree;
1633         proto_item *ti;
1634         guint32 tmp;
1635
1636         if (b == 0x02 && offs == 0x00) {
1637                 /* Global status change */
1638                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Global Status: 0x%02x", d);
1639                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2);
1640                 tmp = d & 0x08;
1641                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sRedundant PM: %s",
1642                                 ipmi_dcd8(d, 0x08),
1643                                 tmp ? "providing Payload Current" :
1644                                 "not providing Payload Current (or this is Primary PM)");
1645                 tmp = d & 0x04;
1646                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sPayload Power: %s",
1647                                 ipmi_dcd8(d, 0x04), tmp ? "is good" : "is not good");
1648                 tmp = d & 0x02;
1649                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sManagement Power: %s",
1650                                 ipmi_dcd8(d, 0x02), tmp ? "is good" : "is not good");
1651                 tmp = d & 0x01;
1652                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sRole: %s",
1653                                 ipmi_dcd8(d, 0x01), tmp ? "Primary" : "Redundant");
1654                 return TRUE;
1655         } else if (b == 0x02 && offs == 0x01) {
1656                 /* Channel status change */
1657                 ti = proto_tree_add_text(tree, tvb, 0, 1, "Channel Status: 0x%02x", d);
1658                 s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte2);
1659                 tmp = d & 0x40;
1660                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sPWR_ON: %s",
1661                                 ipmi_dcd8(d, 0x40), tmp ? "asserted" : "not asserted/not supported");
1662                 tmp = d & 0x20;
1663                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sPayload Power Overcurrent: %s",
1664                                 ipmi_dcd8(d, 0x20), tmp ? "has been detected" : "has not been detected");
1665                 tmp = d & 0x10;
1666                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sPayload Power: %s",
1667                                 ipmi_dcd8(d, 0x10), tmp ? "is enabled" : "is disabled");
1668                 tmp = d & 0x08;
1669                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sENABLE#: %s",
1670                                 ipmi_dcd8(d, 0x08), tmp ? "asserted" : "not asserted");
1671                 tmp = d & 0x04;
1672                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sManagement Power Overcurrent: %s",
1673                                 ipmi_dcd8(d, 0x04), tmp ? "has been detected" : "has not been detected");
1674                 tmp = d & 0x02;
1675                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sManagement Power: %s",
1676                                 ipmi_dcd8(d, 0x02), tmp ? "is enabled" : "is disabled");
1677                 tmp = d & 0x01;
1678                 proto_tree_add_text(s_tree, tvb, 0, 1, "%sPS1#: %s",
1679                                 ipmi_dcd8(d, 0x01), tmp ? "asserted" : "not asserted");
1680                 return TRUE;
1681         }
1682
1683         return FALSE;
1684 }
1685
1686 static gboolean
1687 ssi_f3_3(proto_tree *tree, tvbuff_t *tvb, const struct sensor_info *si _U_,
1688                 guint32 b, guint32 offs, guint32 d)
1689 {
1690         if (b == 0x02 && offs == 0x01) {
1691                 /* Channel status change */
1692                 proto_tree_add_text(tree, tvb, 0, 1, "Power Channel number: %d", d);
1693                 return TRUE;
1694         }
1695
1696         return FALSE;
1697 }
1698
1699 static void
1700 reinit_statics(void)
1701 {
1702         ssi_10_saveptr = NULL;
1703         ssi28_is_logical_fru = -1;
1704 }
1705
1706 static const struct sensor_info *
1707 get_sensor_info(unsigned int stype)
1708 {
1709         static const struct {
1710                 unsigned int id;
1711                 struct sensor_info si;
1712         } si_tab[] = {
1713                 { 0x01, { NULL,     NULL,     NULL,     "Temperature" }},
1714                 { 0x02, { NULL,     NULL,     NULL,     "Voltage" }},
1715                 { 0x03, { NULL,     NULL,     NULL,     "Current" }},
1716                 { 0x04, { NULL,     NULL,     NULL,     "Fan" }},
1717                 { 0x05, { ssoff_05, ssi_05_2, NULL,     "Physical Security (Chassis Intrusion)" }},
1718                 { 0x06, { ssoff_06, NULL,     NULL,     "Platform Security Violation Attempt" }},
1719                 { 0x07, { ssoff_07, NULL,     NULL,     "Processor" }},
1720                 { 0x08, { ssoff_08, NULL,     ssi_08_3, "Power Supply" }},
1721                 { 0x09, { ssoff_09, NULL,     NULL,     "Power Unit" }},
1722                 { 0x0a, { NULL,     NULL,     NULL,     "Cooling Device" }},
1723                 { 0x0b, { NULL,     NULL,     NULL,     "Other Units-based Sensor (per units given in SDR)" }},
1724                 { 0x0c, { ssoff_0c, NULL,     ssi_0c_3, "Memory" }},
1725                 { 0x0d, { ssoff_0d, NULL,     NULL,     "Drive Slot (Bay)" }},
1726                 { 0x0e, { NULL,     NULL,     NULL,     "POST Memory Resize" }},
1727                 { 0x0f, { ssoff_0f, ssi_0f_2, NULL,     "System Firmware Progress (formerly POST Error)" }},
1728                 { 0x10, { ssoff_10, ssi_10_2, ssi_10_3, "Event Logging Disabled" }},
1729                 { 0x11, { ssoff_11, NULL,     NULL,     "Watchdog 1" }},
1730                 { 0x12, { ssoff_12, ssi_12_2, NULL,     "System Event" }},
1731                 { 0x13, { ssoff_13, NULL,     NULL,     "Critical Interrupt" }},
1732                 { 0x14, { ssoff_14, NULL,     NULL,     "Button" }},
1733                 { 0x15, { NULL,     NULL,     NULL,     "Module / Board" }},
1734                 { 0x16, { NULL,     NULL,     NULL,     "Microcontroller / Coprocessor" }},
1735                 { 0x17, { NULL,     NULL,     NULL,     "Add-in Card" }},
1736                 { 0x18, { NULL,     NULL,     NULL,     "Chassis" }},
1737                 { 0x19, { ssoff_19, ssi_19_2, ssi_19_3, "Chip Set" }},
1738                 { 0x1a, { NULL,     NULL,     NULL,     "Other FRU" }},
1739                 { 0x1b, { ssoff_1b, NULL,     NULL,     "Cable / Interconnect" }},
1740                 { 0x1c, { NULL,     NULL,     NULL,     "Terminator" }},
1741                 { 0x1d, { ssoff_1d, ssi_1d_2, ssi_1d_3, "System Boot / Restart Initiated" }},
1742                 { 0x1e, { ssoff_1e, NULL,     NULL,     "Boot Error" }},
1743                 { 0x1f, { ssoff_1f, NULL,     NULL,     "OS Boot" }},
1744                 { 0x20, { ssoff_20, NULL,     NULL,     "OS Critical Stop" }},
1745                 { 0x21, { ssoff_21, ssi_21_2, ssi_21_3, "Slot / Connector" }},
1746                 { 0x22, { ssoff_22, NULL,     NULL,     "System ACPI Power State" }},
1747                 { 0x23, { ssoff_23, ssi_23_2, NULL,     "Watchdog 2" }},
1748                 { 0x24, { ssoff_24, NULL,     NULL,     "Platform Alert" }},
1749                 { 0x25, { ssoff_25, NULL,     NULL,     "Entity Presence" }},
1750                 { 0x26, { NULL,     NULL,     NULL,     "Monitor ASIC / IC" }},
1751                 { 0x27, { ssoff_27, NULL,     NULL,     "LAN" }},
1752                 { 0x28, { ssoff_28, ssi_28_2, ssi_28_3, "Management Subsystem Health" }},
1753                 { 0x29, { ssoff_29, NULL,     NULL,     "Battery" }},
1754                 { 0x2a, { ssoff_2a, ssi_2a_2, ssi_2a_3, "Session Audit" }},
1755                 { 0x2b, { ssoff_2b, ssi_2b_2, NULL,     "Version Change" }},
1756                 { 0x2c, { ssoff_2c, ssi_2c_2, NULL,     "FRU State" }},
1757                 { 0xf0, { ssoff_f0, ssi_f0_2, ssi_f0_3, "Hot Swap (ATCA)" }},
1758                 { 0xf1, { ssoff_f1, ssi_f1_2, ssi_f1_3, "IPMB Physical State (ATCA)" }},
1759                 { 0xf2, { ssoff_f2, NULL,     NULL,     "Module Hot Swap (AMC.0)" }},
1760                 { 0xf3, { ssoff_f3, ssi_f3_2, ssi_f3_3, "Power Channel Notification" }},
1761                 { 0xf4, { ssoff_f4, NULL,     NULL,     "Telco Alarm Input" }}
1762         };
1763         static const struct sensor_info si_oem = {
1764                 NULL, NULL, NULL, "OEM Reserved"
1765         };
1766         static const struct sensor_info si_rsrv = {
1767                 NULL, NULL, NULL, "Reserved"
1768         };
1769         unsigned int i;
1770
1771         /* Look for explicitly defined ones */
1772         for (i = 0; i < array_length(si_tab); i++) {
1773                 if (si_tab[i].id == stype) {
1774                         return &si_tab[i].si;
1775                 }
1776         }
1777
1778         if (stype >= 0xc0 && stype <= 0xff) {
1779                 return &si_oem;
1780         }
1781
1782         return &si_rsrv;
1783 }
1784
1785 static void
1786 parse_platform_event(tvbuff_t *tvb, proto_tree *tree)
1787 {
1788         proto_item *ti;
1789         proto_tree *s_tree;
1790         tvbuff_t *next_tvb;
1791         unsigned int stype, evtype;
1792         const struct sensor_info *si;
1793         const struct evtype_info *eti;
1794         unsigned int d, b2, b3, offs;
1795         const value_string *off_vals;
1796
1797         stype = tvb_get_guint8(tvb, 1);
1798         si = get_sensor_info(stype);
1799         evtype = tvb_get_guint8(tvb, 3) & 0x7f;
1800         eti = get_evtype_info(evtype);
1801
1802         proto_tree_add_item(tree, hf_ipmi_se_evt_rev, tvb, 0, 1, TRUE);
1803         proto_tree_add_uint_format_value(tree, hf_ipmi_se_evt_sensor_type, tvb, 1, 1, stype,
1804                         "%s (0x%02x)", si->desc, stype);
1805         proto_tree_add_item(tree, hf_ipmi_se_evt_sensor_num, tvb, 2, 1, TRUE);
1806         ti = proto_tree_add_item(tree, hf_ipmi_se_evt_byte3, tvb, 3, 1, TRUE);
1807         s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_byte3);
1808         proto_tree_add_item(s_tree, hf_ipmi_se_evt_dir, tvb, 3, 1, TRUE);
1809         proto_tree_add_uint_format(s_tree, hf_ipmi_se_evt_type, tvb, 3, 1, evtype,
1810                         "%sEvent/Reading type: %s (0x%02x)", ipmi_dcd8(evtype, 0x7f),
1811                         eti->desc, evtype);
1812
1813         offs = tvb_get_guint8(tvb, 4);
1814         b2 = offs >> 6;
1815         b3 = (offs >> 4) & 0x3;
1816         off_vals = eti->offsets ? eti->offsets : si->offsets ? si->offsets : et_empty;
1817
1818         ti = proto_tree_add_item(tree, hf_ipmi_se_evt_data1, tvb, 4, 1, TRUE);
1819         s_tree = proto_item_add_subtree(ti, ett_ipmi_se_evt_evd_byte1);
1820         proto_tree_add_uint_format(s_tree, hf_ipmi_se_evt_data1_b2, tvb, 4, 1, b2 << 6,
1821                         "%sByte 2: %s (0x%02x)",
1822                         ipmi_dcd8(offs, 0xc0), val_to_str(b2, eti->byte2, "Reserved"), b2);
1823         proto_tree_add_uint_format(s_tree, hf_ipmi_se_evt_data1_b3, tvb, 4, 1, b3 << 4,
1824                         "%sByte 3: %s (0x%02x)",
1825                         ipmi_dcd8(offs, 0x30), val_to_str(b3, eti->byte3, "Reserved"), b3);
1826         offs &= 0x0f;
1827         proto_tree_add_uint_format(s_tree, hf_ipmi_se_evt_data1_offs, tvb, 4, 1, offs,
1828                         "%sOffset: %s (0x%02x)",
1829                         ipmi_dcd8(offs, 0x0f), val_to_str(offs, off_vals, "Reserved"), offs);
1830
1831         /* This is tricky. First, bytes 2-3 are optional and may be absent.
1832            Second, the necessity to interpret them either in a generic way or in
1833            sensor-specific way depends on the value in byte 1. And at last,
1834            there could be mixture of both ways: the byte 2 can relate to
1835            'previous state', which could be sensor-specific.
1836
1837            Thus, intrp() methods return whether they actually handled the
1838            value. If the 'generic' (related to event/reading type) method fails
1839            to handle the value, we call the 'specific' one. If that fails as
1840            well, we just output it as a hex value.
1841
1842            This is further complicated by the fact that in some events, the
1843            interpretation of the byte 3 depends on the 2nd byte - which could
1844            be specified as having some generic type. Thus, we check it and
1845            fall back to "default" display in such weird cases.
1846         */
1847         reinit_statics();
1848         if (tvb_length(tvb) <= 5) {
1849                 return;
1850         }
1851
1852         next_tvb = tvb_new_subset(tvb, 5, 1, 1);
1853         d = tvb_get_guint8(next_tvb, 0);
1854         if ((eti->intrp2 && eti->intrp2(tree, next_tvb, si, b2, offs, d))
1855                         || (si->intrp2 && si->intrp2(tree, next_tvb, si, b2, offs, d))) {
1856                 /* One of them succeeded. */
1857                 ti = proto_tree_add_item(tree, hf_ipmi_se_evt_data2, next_tvb, 0, 1, TRUE);
1858                 PROTO_ITEM_SET_HIDDEN(ti);
1859         } else {
1860                 /* Just add as hex */
1861                 proto_tree_add_item(tree, hf_ipmi_se_evt_data2, next_tvb, 0, 1, TRUE);
1862         }
1863
1864         /* Now the same for byte 3 */
1865         if (tvb_length(tvb) <= 6) {
1866                 return;
1867         }
1868
1869         next_tvb = tvb_new_subset(tvb, 6, 1, 1);
1870         d = tvb_get_guint8(next_tvb, 0);
1871         if ((eti->intrp3 && eti->intrp3(tree, next_tvb, si, b3, offs, d))
1872                         || (si->intrp3 && si->intrp3(tree, next_tvb, si, b3, offs, d))) {
1873                 /* One of them succeeded. */
1874                 ti = proto_tree_add_item(tree, hf_ipmi_se_evt_data3, next_tvb, 0, 1, TRUE);
1875                 PROTO_ITEM_SET_HIDDEN(ti);
1876         } else {
1877                 /* Just add as hex */
1878                 proto_tree_add_item(tree, hf_ipmi_se_evt_data3, next_tvb, 0, 1, TRUE);
1879         }
1880 }
1881
1882 /* Common for set/get config parameters */
1883 static const value_string cp00_sip_vals[] = {
1884         { 0x00, "Set complete" },
1885         { 0x01, "Set in progress" },
1886         { 0x02, "Commit write" },
1887         { 0x03, "Reserved" },
1888         { 0, NULL }
1889 };
1890
1891 static const struct true_false_string cp10_use_tfs = {
1892         "BMC uses the following value",
1893         "BMC uses the value returned from Get System GUID command"
1894 };
1895
1896 static const struct true_false_string cp15_rq_frc_tfs = {
1897         "Force control operation",
1898         "Request control operation"
1899 };
1900
1901 static const struct true_false_string cp15_imm_delay_tfs = {
1902         "Delayed control",
1903         "Immediate control"
1904 };
1905
1906 static const value_string cp15_op_vals[] = {
1907         { 0x00, "Power down" },
1908         { 0x01, "Power up" },
1909         { 0x02, "Power cycle" },
1910         { 0x03, "Hard reset" },
1911         { 0x04, "Pulse diagnostic interrupt" },
1912         { 0x05, "Initiate a soft-shutdown of OS via ACPI by emulating a fatal overtemperature" },
1913         { 0, NULL }
1914 };
1915
1916 static void
1917 cfgparam_00(tvbuff_t *tvb, proto_tree *tree)
1918 {
1919         proto_tree_add_item(tree, hf_ipmi_se_cp00_sip, tvb, 0, 1, TRUE);
1920 }
1921
1922 static void
1923 cfgparam_01(tvbuff_t *tvb, proto_tree *tree)
1924 {
1925         proto_tree_add_item(tree, hf_ipmi_se_cp01_alert_startup, tvb, 0, 1, TRUE);
1926         proto_tree_add_item(tree, hf_ipmi_se_cp01_startup, tvb, 0, 1, TRUE);
1927         proto_tree_add_item(tree, hf_ipmi_se_cp01_event_msg, tvb, 0, 1, TRUE);
1928         proto_tree_add_item(tree, hf_ipmi_se_cp01_pef, tvb, 0, 1, TRUE);
1929 }
1930
1931 static void
1932 cfgparam_02(tvbuff_t *tvb, proto_tree *tree)
1933 {
1934         proto_tree_add_item(tree, hf_ipmi_se_cp02_diag_intr, tvb, 0, 1, TRUE);
1935         proto_tree_add_item(tree, hf_ipmi_se_cp02_oem_action, tvb, 0, 1, TRUE);
1936         proto_tree_add_item(tree, hf_ipmi_se_cp02_pwr_cycle, tvb, 0, 1, TRUE);
1937         proto_tree_add_item(tree, hf_ipmi_se_cp02_reset, tvb, 0, 1, TRUE);
1938         proto_tree_add_item(tree, hf_ipmi_se_cp02_pwr_down, tvb, 0, 1, TRUE);
1939         proto_tree_add_item(tree, hf_ipmi_se_cp02_alert, tvb, 0, 1, TRUE);
1940 }
1941
1942
1943 static void
1944 cfgparam_03(tvbuff_t *tvb, proto_tree *tree)
1945 {
1946         proto_tree_add_item(tree, hf_ipmi_se_cp03_startup, tvb, 0, 1, TRUE);
1947 }
1948
1949 static void
1950 cfgparam_04(tvbuff_t *tvb, proto_tree *tree)
1951 {
1952         proto_tree_add_item(tree, hf_ipmi_se_cp04_alert_startup, tvb, 0, 1, TRUE);
1953 }
1954
1955 static void
1956 cfgparam_05(tvbuff_t *tvb, proto_tree *tree)
1957 {
1958         proto_tree_add_item(tree, hf_ipmi_se_cp05_num_evfilters, tvb, 0, 1, TRUE);
1959 }
1960
1961 static void
1962 cfgparam_06(tvbuff_t *tvb, proto_tree *tree)
1963 {
1964         static const int *byte1[] = { &hf_ipmi_se_cp06_filter, NULL };
1965
1966         proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_cp06_byte1, byte1, TRUE, 0);
1967         proto_tree_add_item(tree, hf_ipmi_se_cp06_data, tvb, 1, 20, TRUE);
1968 }
1969
1970 static void
1971 cfgparam_07(tvbuff_t *tvb, proto_tree *tree)
1972 {
1973         static const int *byte1[] = { &hf_ipmi_se_cp07_filter, NULL };
1974
1975         proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_cp07_byte1, byte1, TRUE, 0);
1976         proto_tree_add_item(tree, hf_ipmi_se_cp06_data, tvb, 1, 1, TRUE);
1977 }
1978
1979 static void
1980 cfgparam_08(tvbuff_t *tvb, proto_tree *tree)
1981 {
1982         proto_tree_add_item(tree, hf_ipmi_se_cp08_policies, tvb, 0, 1, TRUE);
1983 }
1984
1985 static void
1986 cfgparam_09(tvbuff_t *tvb, proto_tree *tree)
1987 {
1988         static const int *byte1[] = { &hf_ipmi_se_cp09_entry, NULL };
1989
1990         proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_cp09_byte1, byte1, TRUE, 0);
1991         proto_tree_add_item(tree, hf_ipmi_se_cp09_data, tvb, 1, 3, TRUE);
1992 }
1993
1994 static void
1995 cfgparam_10(tvbuff_t *tvb, proto_tree *tree)
1996 {
1997         static const int *byte1[] = { &hf_ipmi_se_cp10_useval, NULL };
1998
1999         proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_cp10_byte1, byte1, TRUE, 0);
2000         ipmi_add_guid(tree, hf_ipmi_se_cp10_guid, tvb, 1);
2001 }
2002
2003 static void
2004 cfgparam_11(tvbuff_t *tvb, proto_tree *tree)
2005 {
2006         proto_tree_add_item(tree, hf_ipmi_se_cp11_num_alertstr, tvb, 0, 1, TRUE);
2007 }
2008
2009 static void
2010 cfgparam_12(tvbuff_t *tvb, proto_tree *tree)
2011 {
2012         static const int *byte2[] = { &hf_ipmi_se_cp12_evfilter, NULL };
2013         static const int *byte3[] = { &hf_ipmi_se_cp12_alert_stringset, NULL };
2014         proto_item *ti;
2015         proto_tree *s_tree;
2016         guint8 tmp;
2017
2018         ti = proto_tree_add_item(tree, hf_ipmi_se_cp12_byte1, tvb, 0, 1, TRUE);
2019         s_tree = proto_item_add_subtree(ti, ett_ipmi_se_cp12_byte1);
2020         tmp = tvb_get_guint8(tvb, 0) & 0x7f;
2021         if (tmp) {
2022                 proto_tree_add_item(s_tree, hf_ipmi_se_cp12_alert_stringsel, tvb, 0, 1, TRUE);
2023         } else {
2024                 proto_tree_add_uint_format(s_tree, hf_ipmi_se_cp12_alert_stringsel, tvb, 0, 1,
2025                                 tmp, "%sSelects volatile string parameters", ipmi_dcd8(tmp, 0x7f));
2026         }
2027
2028         proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_cp12_byte2, byte2, TRUE, 0);
2029         proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, ett_ipmi_se_cp12_byte3, byte3, TRUE, 0);
2030 }
2031
2032 static void
2033 cfgparam_13(tvbuff_t *tvb, proto_tree *tree)
2034 {
2035         static const int *byte1[] = { &hf_ipmi_se_cp13_stringsel, NULL };
2036
2037         proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_cp13_byte1, byte1, TRUE, 0);
2038         proto_tree_add_item(tree, hf_ipmi_se_cp13_blocksel, tvb, 1, 1, TRUE);
2039         proto_tree_add_item(tree, hf_ipmi_se_cp13_string, tvb, 2, tvb_length(tvb) - 2, TRUE);
2040 }
2041
2042 static void
2043 cfgparam_14(tvbuff_t *tvb, proto_tree *tree)
2044 {
2045         proto_tree_add_item(tree, hf_ipmi_se_cp14_num_gct, tvb, 0, 1, TRUE);
2046 }
2047
2048 static void
2049 cp15_add_group_and_member(proto_tree *tree, tvbuff_t *tvb, guint offs, guint num)
2050 {
2051         static const int *byte2[] = { &hf_ipmi_se_cp15_member_check, &hf_ipmi_se_cp15_member_id, NULL };
2052         const char *gdesc;
2053         guint8 tmp;
2054
2055         tmp = tvb_get_guint8(tvb, offs);
2056         if (tmp == 0x00) {
2057                 gdesc = " (unspecified)";
2058         } else if (tmp == 0xff) {
2059                 gdesc = " (all groups)";
2060         } else {
2061                 gdesc = "";
2062         }
2063
2064         proto_tree_add_uint_format(tree, hf_ipmi_se_cp15_group, tvb, offs, 1, tmp,
2065                         "Group ID %d: %d%s", num, tmp, gdesc);
2066         proto_tree_add_bitmask_text(tree, tvb, offs + 1, 1, NULL, NULL, ett_ipmi_se_cp15_member, byte2, TRUE, 0);
2067 }
2068
2069 static void
2070 cfgparam_15(tvbuff_t *tvb, proto_tree *tree)
2071 {
2072         static const int *byte1[] = { &hf_ipmi_se_cp15_gctsel, NULL };
2073         static const int *byte2[] = { &hf_ipmi_se_cp15_force, &hf_ipmi_se_cp15_delayed, &hf_ipmi_se_cp15_channel, NULL };
2074         static const int *byte11[] = { &hf_ipmi_se_cp15_retries, &hf_ipmi_se_cp15_operation, NULL };
2075
2076         proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_cp15_byte1, byte1, TRUE, 0);
2077         proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_cp15_byte2, byte2, TRUE, 0);
2078         cp15_add_group_and_member(tree, tvb, 2, 0);
2079         cp15_add_group_and_member(tree, tvb, 4, 1);
2080         cp15_add_group_and_member(tree, tvb, 6, 2);
2081         cp15_add_group_and_member(tree, tvb, 8, 3);
2082         proto_tree_add_bitmask_text(tree, tvb, 10, 1, NULL, NULL, ett_ipmi_se_cp15_byte11, byte11, TRUE, 0);
2083 }
2084
2085 static struct {
2086         void (*intrp)(tvbuff_t *tvb, proto_tree *tree);
2087         const char *name;
2088 } conf_params[] = {
2089         { cfgparam_00, "Set In Progress" },
2090         { cfgparam_01, "PEF Control" },
2091         { cfgparam_02, "PEF Action global control" },
2092         { cfgparam_03, "PEF Startup Delay" },
2093         { cfgparam_04, "PEF Alert Startup Delay" },
2094         { cfgparam_05, "Number of Event Filters" },
2095         { cfgparam_06, "Event Filter Table" },
2096         { cfgparam_07, "Event Filter Table Data 1" },
2097         { cfgparam_08, "Number of Alert Policy Entries" },
2098         { cfgparam_09, "Alert Policy Table" },
2099         { cfgparam_10, "System GUID" },
2100         { cfgparam_11, "Number of Alert Strings" },
2101         { cfgparam_12, "Alert String Keys" },
2102         { cfgparam_13, "Alert Strings" },
2103         { cfgparam_14, "Number of Group Control Table Entries" },
2104         { cfgparam_15, "Group Control Table" }
2105 };
2106
2107 static const value_string vals_11_pef_timer[] = {
2108         { 0x00, "Disable Postpone Timer" },
2109         { 0xfe, "Temporary PEF disable" },
2110         { 0xff, "Get Present Countdown Value" },
2111         { 0, NULL }
2112 };
2113
2114 static const struct true_false_string tfs_14_processed = {
2115         "BMC",
2116         "software"
2117 };
2118
2119 static const value_string vals_16_op[] = {
2120         { 0x00, "Initiate Alert" },
2121         { 0x01, "Get Alert Immediate status" },
2122         { 0x02, "Clear Alert Immediate status" },
2123         { 0x03, "Reserved" },
2124         { 0, NULL }
2125 };
2126
2127 static const value_string vals_16_status[] = {
2128         { 0x00, "No status" },
2129         { 0x01, "Alert was Normal End" },
2130         { 0x02, "`Call Retry' retries failed" },
2131         { 0x03, "Alert failed due to timeouts waiting for acknowledge on all retries" },
2132         { 0xFF, "Alert by this command is in progress" },
2133         { 0, NULL }
2134 };
2135
2136 static const struct true_false_string tfs_20_op = {
2137         "Get SDR Count", "Get sensor count"
2138 };
2139
2140 static const struct true_false_string tfs_20_pop = {
2141         "Dynamic", "Static"
2142 };
2143
2144 static const value_string vals_28_act[] = {
2145         { 0x00, "Do not change individual enables" },
2146         { 0x01, "Enable selected event messages" },
2147         { 0x02, "Disable selescted event messages" },
2148         { 0x03, "Reserved" },
2149         { 0, NULL }
2150 };
2151
2152 static const struct true_false_string tfs_28_enable = {
2153         "Enable", "Disable"
2154 };
2155
2156 static const struct true_false_string tfs_29_enabled = {
2157         "Enabled", "Disabled"
2158 };
2159
2160 static const struct true_false_string tfs_2a_sel = {
2161         "Selected", "All"
2162 };
2163
2164 static const struct true_false_string tfs_2b_enabled = {
2165         "Enabled", "Disabled"
2166 };
2167
2168 /* Set event receiver.
2169  */
2170 static void
2171 rq00(tvbuff_t *tvb, proto_tree *tree)
2172 {
2173         static const int *byte2[] = { &hf_ipmi_se_00_lun, NULL };
2174         unsigned int addr;
2175
2176         addr = tvb_get_guint8(tvb, 0);
2177         if (addr == 0xff) {
2178                 proto_tree_add_uint_format(tree, hf_ipmi_se_00_addr, tvb, 0, 1,
2179                                 addr, "Disable Message Generation (0xFF)");
2180         } else {
2181                 proto_tree_add_item(tree, hf_ipmi_se_00_addr, tvb, 0, 1, TRUE);
2182         }
2183
2184         proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_00_byte2, byte2, TRUE, 0);
2185 }
2186
2187 /* Get event receiver.
2188  */
2189 static void
2190 rs01(tvbuff_t *tvb, proto_tree *tree)
2191 {
2192         static const int *byte2[] = { &hf_ipmi_se_01_lun, NULL };
2193         unsigned int addr;
2194
2195         addr = tvb_get_guint8(tvb, 0);
2196         if (addr == 0xff) {
2197                 proto_tree_add_uint_format(tree, hf_ipmi_se_01_addr, tvb, 0, 1,
2198                                 addr, "Message Generation Disabled (0xFF)");
2199         } else {
2200                 proto_tree_add_item(tree, hf_ipmi_se_01_addr, tvb, 0, 1, TRUE);
2201         }
2202
2203         proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_01_byte2, byte2, TRUE, 0);
2204 }
2205
2206 /* Platform event.
2207  */
2208 static void
2209 rq02(tvbuff_t *tvb, proto_tree *tree)
2210 {
2211         parse_platform_event(tvb, tree);
2212 }
2213
2214 /* Get PEF capabilities.
2215  */
2216 static void
2217 rs10(tvbuff_t *tvb, proto_tree *tree)
2218 {
2219         static const int *byte2[] = { &hf_ipmi_se_10_action_oem_filter, &hf_ipmi_se_10_action_diag_intr,
2220                 &hf_ipmi_se_10_action_oem_action, &hf_ipmi_se_10_action_pwr_cycle, &hf_ipmi_se_10_action_reset,
2221                 &hf_ipmi_se_10_action_pwr_down, &hf_ipmi_se_10_action_alert, NULL };
2222         guint8 v;
2223
2224         v = tvb_get_guint8(tvb, 0);
2225         proto_tree_add_item(tree, hf_ipmi_se_10_pef_version, tvb, 0, 1, TRUE);
2226         proto_tree_add_bitmask_text(tree, tvb, 1, 1, "Action support: ", "None", ett_ipmi_se_10_action,
2227                         byte2, TRUE, 0);
2228         proto_tree_add_item(tree, hf_ipmi_se_10_entries, tvb, 2, 1, TRUE);
2229 }
2230
2231 /* Arm PEF Postpone Timer.
2232  */
2233 static void
2234 rq11(tvbuff_t *tvb, proto_tree *tree)
2235 {
2236         guint8 val;
2237
2238         val = tvb_get_guint8(tvb, 0);
2239         proto_tree_add_uint_format(tree, hf_ipmi_se_11_rq_timeout, tvb, 0, 1,
2240                         val, "%s", val_to_str(val, vals_11_pef_timer, "Arm Timer for: %d sec"));
2241 }
2242
2243 static void
2244 rs11(tvbuff_t *tvb, proto_tree *tree)
2245 {
2246         guint8 val;
2247
2248         val = tvb_get_guint8(tvb, 0);
2249         proto_tree_add_uint_format(tree, hf_ipmi_se_11_rs_timeout, tvb, 0, 1,
2250                         val, "%s", val_to_str(val, vals_11_pef_timer, "Present Timer Countdown value: %d sec"));
2251 }
2252
2253 /* Set PEF Configuration Parameters.
2254  */
2255 static void
2256 rq12(tvbuff_t *tvb, proto_tree *tree)
2257 {
2258         proto_item *ti;
2259         proto_tree *s_tree;
2260         tvbuff_t *sub;
2261         guint8 pno;
2262         const char *desc;
2263         
2264         pno = tvb_get_guint8(tvb, 0) & 0x7f;
2265         if (pno < array_length(conf_params)) {
2266                 desc = conf_params[pno].name;
2267         } else if (pno >= 96 && pno <= 127) {
2268                 desc = "OEM";
2269         } else {
2270                 desc = "Reserved";
2271         }
2272         ti = proto_tree_add_uint_format(tree, hf_ipmi_se_12_byte1, tvb, 0, 1,
2273                         pno, "Parameter selector: %s (0x%02x)", desc, pno);
2274         s_tree = proto_item_add_subtree(ti, ett_ipmi_se_12_byte1);
2275         proto_tree_add_uint_format(s_tree, hf_ipmi_se_12_param, tvb, 0, 1,
2276                         pno, "%sParameter selector: %s (0x%02x)",
2277                         ipmi_dcd8(pno, 0x7f), desc, pno);
2278
2279         if (pno < array_length(conf_params)) {
2280                 sub = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1);
2281                 conf_params[pno].intrp(sub, tree);
2282         } else {
2283                 proto_tree_add_none_format(tree, hf_ipmi_se_12_data, tvb, 1, tvb_length(tvb) - 1,
2284                                 "Configuration parameter data: %s", desc);
2285         }
2286 }
2287
2288 static const value_string cc12[] = {
2289         { 0x80, "Parameter not supported" },
2290         { 0x81, "Attempt to set the 'set in progress' value (in parameter #0) when not in the 'set complete' state" },
2291         { 0x82, "Attempt to write read-only parameter" },
2292         { 0x83, "Attempt to read write-only parameter" },
2293         { 0, NULL }
2294 };
2295
2296 /* Get PEF Configuration Parameters.
2297  */
2298 static void
2299 rq13(tvbuff_t *tvb, proto_tree *tree)
2300 {
2301         proto_item *ti;
2302         proto_tree *s_tree;
2303         guint32 pno;
2304         const char *desc;
2305
2306         pno = tvb_get_guint8(tvb, 0);
2307
2308         if (!tree) {
2309                 /* Just cache parameter selector */
2310                 ipmi_setsaveddata(0, pno);
2311                 return;
2312         }
2313
2314         pno &= 0x7f;
2315         
2316         if (pno < array_length(conf_params)) {
2317                 desc = conf_params[pno].name;
2318         } else if (pno >= 96 && pno <= 127) {
2319                 desc = "OEM";
2320         } else {
2321                 desc = "Reserved";
2322         }
2323         ti = proto_tree_add_uint_format(tree, hf_ipmi_se_13_byte1, tvb, 0, 1,
2324                         pno, "Parameter selector: %s (0x%02x)", desc, pno);
2325         s_tree = proto_item_add_subtree(ti, ett_ipmi_se_13_byte1);
2326         proto_tree_add_item(s_tree, hf_ipmi_se_13_getrev, tvb, 0, 1, TRUE);
2327         proto_tree_add_uint_format(s_tree, hf_ipmi_se_13_param, tvb, 0, 1,
2328                         pno, "%sParameter selector: %s (0x%02x)",
2329                         ipmi_dcd8(pno, 0x7f), desc, pno);
2330
2331         proto_tree_add_item(tree, hf_ipmi_se_13_set, tvb, 1, 1, TRUE);
2332         proto_tree_add_item(tree, hf_ipmi_se_13_block, tvb, 2, 1, TRUE);
2333 }
2334
2335 static void
2336 rs13(tvbuff_t *tvb, proto_tree *tree)
2337 {
2338         static const int *byte1[] = { &hf_ipmi_se_13_rev_present, &hf_ipmi_se_13_rev_compat, NULL };
2339         proto_item *ti;
2340         tvbuff_t *sub;
2341         guint32 pno;
2342         const char *desc;
2343
2344         proto_tree_add_bitmask_text(tree, tvb, 0, 1, "Parameter revision", NULL,
2345                         ett_ipmi_se_13_rev, byte1, TRUE, 0);
2346
2347         if (!ipmi_getsaveddata(0, &pno)) {
2348                 /* No request found - cannot parse further */
2349                 if (tvb_length(tvb) > 1) {
2350                         proto_tree_add_item(tree, hf_ipmi_se_13_data, tvb, 1, tvb_length(tvb) - 1, TRUE);
2351                 }
2352                 return;
2353         }
2354
2355         if ((pno & 0x80) && tvb_length(tvb) > 1) {
2356                 ti = proto_tree_add_text(tree, tvb, 0, 0, "Requested parameter revision; parameter data returned");
2357                 PROTO_ITEM_SET_GENERATED(ti);
2358         } else if (!(pno & 0x80) && tvb_length(tvb) == 1) {
2359                 ti = proto_tree_add_text(tree, tvb, 0, 0, "Requested parameter data; only parameter version returned");
2360                 PROTO_ITEM_SET_GENERATED(ti);
2361         }
2362
2363         pno &= 0x7f;
2364         if (pno < array_length(conf_params)) {
2365                 desc = conf_params[pno].name;
2366         } else if (pno >= 96 && pno <= 127) {
2367                 desc = "OEM";
2368         } else {
2369                 desc = "Reserved";
2370         }
2371
2372         ti = proto_tree_add_text(tree, tvb, 0, 0, "Parameter: %s", desc);
2373         PROTO_ITEM_SET_GENERATED(ti);
2374
2375         if (tvb_length(tvb) > 1) {
2376                 if (pno < array_length(conf_params)) {
2377                         sub = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1);
2378                         conf_params[pno].intrp(sub, tree);
2379                 } else {
2380                         proto_tree_add_item(tree, hf_ipmi_se_13_data, tvb, 1, tvb_length(tvb) - 1, TRUE);
2381                 }
2382         }
2383 }
2384
2385 static const value_string cc13[] = {
2386         { 0x80, "Parameter not supported" },
2387         { 0, NULL }
2388 };
2389
2390 /* Set Last Processed Event ID Command.
2391  */
2392 static void
2393 rq14(tvbuff_t *tvb, proto_tree *tree)
2394 {
2395         static const gint *byte1[] = { &hf_ipmi_se_14_processed_by, NULL };
2396
2397         proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_14_byte1, byte1, TRUE, 0);
2398         proto_tree_add_item(tree, hf_ipmi_se_14_rid, tvb, 1, 2, TRUE);
2399 }
2400
2401 static const value_string cc14[] = {
2402         { 0x81, "Cannot execute command, SEL erase in progress" },
2403         { 0, NULL }
2404 };
2405
2406 /* Get Last Processed Event ID Command.
2407  */
2408 static void
2409 rs15(tvbuff_t *tvb, proto_tree *tree)
2410 {
2411         guint16 tmp;
2412
2413         ipmi_add_timestamp(tree, hf_ipmi_se_15_tstamp, tvb, 0);
2414         tmp = tvb_get_letohs(tvb, 4);
2415         if (tmp != 0xffff) {
2416                 proto_tree_add_item(tree, hf_ipmi_se_15_lastrec, tvb, 4, 2, TRUE);
2417         } else {
2418                 proto_tree_add_uint_format_value(tree, hf_ipmi_se_15_lastrec, tvb, 4, 2,
2419                                 tmp, "SEL is empty (0x%04x)", tmp);
2420         }
2421         proto_tree_add_item(tree, hf_ipmi_se_15_proc_sw, tvb, 6, 2, TRUE);
2422         tmp = tvb_get_letohs(tvb, 8);
2423         if (tmp != 0x0000) {
2424                 proto_tree_add_item(tree, hf_ipmi_se_15_proc_bmc, tvb, 8, 2, TRUE);
2425         } else {
2426                 proto_tree_add_uint_format_value(tree, hf_ipmi_se_15_proc_bmc, tvb, 8, 2,
2427                                 tmp, "Event processed but cannot be logged (0x%04x)", tmp);
2428         }
2429 }
2430
2431 static const value_string cc15[] = {
2432         { 0x81, "Cannot execute command, SEL erase in progress" },
2433         { 0, NULL }
2434 };
2435
2436 /* Alert Immediate.
2437  */
2438 static void
2439 rq16(tvbuff_t *tvb, proto_tree *tree)
2440 {
2441         static const gint *byte1[] = { &hf_ipmi_se_16_chan, NULL };
2442         static const gint *byte2[] = { &hf_ipmi_se_16_op, &hf_ipmi_se_16_dst, NULL };
2443         static const gint *byte3[] = { &hf_ipmi_se_16_send_string, &hf_ipmi_se_16_string_sel, NULL };
2444         tvbuff_t *sub;
2445
2446         if (!tree) {
2447                 /* Save the operation */
2448                 ipmi_setsaveddata(0, (tvb_get_guint8(tvb, 1) & 0xc0) >> 6);
2449                 return;
2450         }
2451
2452         proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_16_byte1, byte1, TRUE, 0);
2453         proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_16_byte2, byte2, TRUE, 0);
2454         proto_tree_add_bitmask_text(tree, tvb, 2, 1, NULL, NULL, ett_ipmi_se_16_byte3, byte3, TRUE, 0);
2455         if (tvb_length(tvb) > 3) {
2456                 proto_tree_add_item(tree, hf_ipmi_se_16_gen, tvb, 3, 1, TRUE);
2457                 sub = tvb_new_subset(tvb, 4, tvb_length(tvb) - 4, tvb_length(tvb) - 4);
2458                 parse_platform_event(sub, tree);
2459         }
2460 }
2461
2462 static void
2463 rs16(tvbuff_t *tvb, proto_tree *tree)
2464 {
2465         guint32 val;
2466         
2467         if (ipmi_getsaveddata(0, &val) && val == 0x01) {
2468                 /* Operation == Get Alert Immediate Status */
2469                 proto_tree_add_item(tree, hf_ipmi_se_16_status, tvb, 0, 1, TRUE);
2470         }
2471 }
2472
2473 static const value_string cc16[] = {
2474         { 0x81, "Alert Immediate rejected due to alert already in progress" },
2475         { 0x82, "Alert Immediate rejected due to IPMI messaging session active on this channel" },
2476         { 0x83, "Platform Event parameters not supported" },
2477         { 0, NULL }
2478 };
2479
2480 /* PET Acknowledge.
2481  */
2482 static void
2483 rq17(tvbuff_t *tvb, proto_tree *tree)
2484 {
2485         proto_tree_add_item(tree, hf_ipmi_se_17_seq, tvb, 0, 2, TRUE);
2486         ipmi_add_timestamp(tree, hf_ipmi_se_17_tstamp, tvb, 2);
2487         proto_tree_add_item(tree, hf_ipmi_se_17_evsrc, tvb, 6, 1, TRUE);
2488         proto_tree_add_item(tree, hf_ipmi_se_17_sensor_dev, tvb, 7, 1, TRUE);
2489         proto_tree_add_item(tree, hf_ipmi_se_17_sensor_num, tvb, 8, 1, TRUE);
2490         proto_tree_add_item(tree, hf_ipmi_se_17_evdata1, tvb, 9, 1, TRUE);
2491         proto_tree_add_item(tree, hf_ipmi_se_17_evdata2, tvb, 10, 1, TRUE);
2492         proto_tree_add_item(tree, hf_ipmi_se_17_evdata3, tvb, 11, 1, TRUE);
2493 }
2494
2495 /* Get Device SDR Info.
2496  */
2497 static void
2498 rq20(tvbuff_t *tvb, proto_tree *tree)
2499 {
2500         static const int *byte1[] = { &hf_ipmi_se_20_rq_op, NULL };
2501
2502         if (tvb_length(tvb) > 0) {
2503                 proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL,
2504                                 ett_ipmi_se_20_rq_byte1, byte1, TRUE, 0);
2505                 ipmi_setsaveddata(0, tvb_get_guint8(tvb, 0) & 0x01);
2506         }
2507 }
2508
2509 static void
2510 rs20(tvbuff_t *tvb, proto_tree *tree)
2511 {
2512         static const int *byte2[] = { &hf_ipmi_se_20_rs_population, &hf_ipmi_se_20_rs_lun3,
2513                 &hf_ipmi_se_20_rs_lun2, &hf_ipmi_se_20_rs_lun1, &hf_ipmi_se_20_rs_lun0, NULL };
2514         guint32 val;
2515
2516         if (ipmi_getsaveddata(0, &val) && val) {
2517                 proto_tree_add_item(tree, hf_ipmi_se_20_rs_sdr, tvb, 0, 1, TRUE);
2518         } else {
2519                 proto_tree_add_item(tree, hf_ipmi_se_20_rs_num, tvb, 0, 1, TRUE);
2520         }
2521         proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_20_rs_byte2,
2522                         byte2, TRUE, 0);
2523         if (tvb_get_guint8(tvb, 1) & 0x80) {
2524                 /* Dynamic sensor population */
2525                 proto_tree_add_item(tree, hf_ipmi_se_20_rs_change, tvb, 2, 4, TRUE);
2526         }
2527 }
2528
2529
2530 /* Get Device SDR.
2531  */
2532 static void
2533 rq21(tvbuff_t *tvb, proto_tree *tree)
2534 {
2535         guint8 len;
2536
2537         len = tvb_get_guint8(tvb, 5);
2538
2539         proto_tree_add_item(tree, hf_ipmi_se_21_rid, tvb, 0, 2, TRUE);
2540         proto_tree_add_item(tree, hf_ipmi_se_21_record, tvb, 2, 2, TRUE);
2541         proto_tree_add_item(tree, hf_ipmi_se_21_offset, tvb, 4, 1, TRUE);
2542         proto_tree_add_uint_format_value(tree, hf_ipmi_se_21_len, tvb, 5, 1, len,
2543                         "%u%s", len, len == 0xff ? "(entire record)" : "");
2544 }
2545
2546 static void
2547 rs21(tvbuff_t *tvb, proto_tree *tree)
2548 {
2549         proto_tree_add_item(tree, hf_ipmi_se_21_next, tvb, 0, 2, TRUE);
2550         proto_tree_add_item(tree, hf_ipmi_se_21_recdata, tvb, 2, tvb_length(tvb) - 2, TRUE);
2551 }
2552
2553 static const value_string cc21[] = {
2554         { 0x80, "Record changed" },
2555         { 0, NULL }
2556 };
2557
2558 /* Reserve Device SDR Repository.
2559  */
2560 static void
2561 rs22(tvbuff_t *tvb, proto_tree *tree)
2562 {
2563         proto_tree_add_item(tree, hf_ipmi_se_22_resid, tvb, 0, 2, TRUE);
2564 }
2565
2566 /* Get Sensor Reading Factors.
2567  */
2568 static void
2569 rq23(tvbuff_t *tvb, proto_tree *tree)
2570 {
2571         proto_tree_add_item(tree, hf_ipmi_se_23_rq_sensor, tvb, 0, 1, TRUE);
2572         proto_tree_add_item(tree, hf_ipmi_se_23_rq_reading, tvb, 1, 1, TRUE);
2573 }
2574
2575 static inline gint16
2576 sign_extend(gint16 v, int bits)
2577 {
2578         if ((v & (1 << (bits - 1))) == 0) {
2579                 return v;
2580         }
2581
2582         return v | (0xffff << bits);
2583 }
2584
2585 static void
2586 rs23(tvbuff_t *tvb, proto_tree *tree)
2587 {
2588         proto_item *ti;
2589         proto_tree *s_tree, *st2;
2590         guint16 tol, acc, accexp, tmp;
2591         gint16 m, b, bexp, rexp;
2592
2593         proto_tree_add_item(tree, hf_ipmi_se_23_rs_next_reading, tvb, 0, 1, TRUE);
2594
2595         m = tvb_get_guint8(tvb, 1);
2596         tmp = tvb_get_guint8(tvb, 2);
2597         m |= (tmp & 0xc0) << 2;
2598         tol = tmp & 0x3f;
2599         b = tvb_get_guint8(tvb, 3);
2600         tmp = tvb_get_guint8(tvb, 4);
2601         b |= (tmp & 0xc0) << 2;
2602         acc = tmp & 0x3f;
2603         tmp = tvb_get_guint8(tvb, 5);
2604         acc |= (tmp & 0xf0) << 4;
2605         accexp = (tmp & 0x0c) >> 2;
2606         tmp = tvb_get_guint8(tvb, 6);
2607         rexp = (tmp & 0xf0) >> 4;
2608         bexp = tmp & 0x0f;
2609
2610         m = sign_extend(m, 10);
2611         b = sign_extend(b, 10);
2612         bexp = sign_extend(bexp, 4);
2613         rexp = sign_extend(rexp, 4);
2614
2615         ti = proto_tree_add_text(tree, tvb, 1, 6, "Factors: M=%d B=%d K1=%d K2=%d Acc=%u*10^%u Tol=%u",
2616                         m, b, bexp, rexp, acc, accexp, tol);
2617         s_tree = proto_item_add_subtree(ti, ett_ipmi_se_23_readingfactors);
2618
2619         tmp = tvb_get_guint8(tvb, 1);
2620         ti = proto_tree_add_text(s_tree, tvb, 1, 1, "Byte 1");
2621         st2 = proto_item_add_subtree(ti, ett_ipmi_se_23_byte1);
2622         proto_tree_add_text(st2, tvb, 1, 1, "%sM (LS 8bits)", ipmi_dcd8(tmp, 0xff));
2623
2624         tmp = tvb_get_guint8(tvb, 2);
2625         ti = proto_tree_add_text(s_tree, tvb, 2, 1, "Byte 2");
2626         st2 = proto_item_add_subtree(ti, ett_ipmi_se_23_byte2);
2627         proto_tree_add_text(st2, tvb, 2, 1, "%sM (MS 2bits)", ipmi_dcd8(tmp, 0xc0));
2628         proto_tree_add_text(st2, tvb, 2, 1, "%sTolerance", ipmi_dcd8(tmp, 0x3f));
2629
2630         tmp = tvb_get_guint8(tvb, 3);
2631         ti = proto_tree_add_text(s_tree, tvb, 3, 1, "Byte 3");
2632         st2 = proto_item_add_subtree(ti, ett_ipmi_se_23_byte3);
2633         proto_tree_add_text(st2, tvb, 3, 1, "%sB (LS 8bits)", ipmi_dcd8(tmp, 0xff));
2634
2635         tmp = tvb_get_guint8(tvb, 4);
2636         ti = proto_tree_add_text(s_tree, tvb, 4, 1, "Byte 4");
2637         st2 = proto_item_add_subtree(ti, ett_ipmi_se_23_byte4);
2638         proto_tree_add_text(st2, tvb, 4, 1, "%sB (MS 2bits)", ipmi_dcd8(tmp, 0xc0));
2639         proto_tree_add_text(st2, tvb, 4, 1, "%sAccuracy (LS 6bits)", ipmi_dcd8(tmp, 0x3f));
2640
2641         tmp = tvb_get_guint8(tvb, 5);
2642         ti = proto_tree_add_text(s_tree, tvb, 5, 1, "Byte 5");
2643         st2 = proto_item_add_subtree(ti, ett_ipmi_se_23_byte5);
2644         proto_tree_add_text(st2, tvb, 5, 1, "%sAccuracy (MS 4bits)", ipmi_dcd8(tmp, 0xf0));
2645         proto_tree_add_text(st2, tvb, 5, 1, "%sAccuracy exponent", ipmi_dcd8(tmp, 0x0c));
2646
2647         tmp = tvb_get_guint8(tvb, 6);
2648         ti = proto_tree_add_text(s_tree, tvb, 6, 1, "Byte 6");
2649         st2 = proto_item_add_subtree(ti, ett_ipmi_se_23_byte6);
2650         proto_tree_add_text(st2, tvb, 6, 1, "%sR exponent", ipmi_dcd8(tmp, 0xf0));
2651         proto_tree_add_text(st2, tvb, 6, 1, "%sB exponent", ipmi_dcd8(tmp, 0x0f));
2652 }
2653
2654 /* Set Sensor Hysteresis.
2655  */
2656 static void
2657 rq24(tvbuff_t *tvb, proto_tree *tree)
2658 {
2659         proto_tree_add_item(tree, hf_ipmi_se_24_sensor, tvb, 0, 1, TRUE);
2660         proto_tree_add_item(tree, hf_ipmi_se_24_mask, tvb, 1, 1, TRUE);
2661         proto_tree_add_item(tree, hf_ipmi_se_24_hyst_pos, tvb, 2, 1, TRUE);
2662         proto_tree_add_item(tree, hf_ipmi_se_24_hyst_neg, tvb, 3, 1, TRUE);
2663 }
2664
2665 /* Get Sensor Hysteresis.
2666  */
2667 static void
2668 rq25(tvbuff_t *tvb, proto_tree *tree)
2669 {
2670         proto_tree_add_item(tree, hf_ipmi_se_25_sensor, tvb, 0, 1, TRUE);
2671         proto_tree_add_item(tree, hf_ipmi_se_25_mask, tvb, 1, 1, TRUE);
2672 }
2673
2674 static void
2675 rs25(tvbuff_t *tvb, proto_tree *tree)
2676 {
2677         proto_tree_add_item(tree, hf_ipmi_se_25_hyst_pos, tvb, 0, 1, TRUE);
2678         proto_tree_add_item(tree, hf_ipmi_se_25_hyst_neg, tvb, 1, 1, TRUE);
2679 }
2680
2681 /* Common for Get/Set Thresholds */
2682 static void
2683 add_thresholds(tvbuff_t *tvb, int offs, proto_tree *tree, const char *desc)
2684 {
2685         static const int *threshold_mask[] = { &hf_ipmi_se_XX_m_unr, &hf_ipmi_se_XX_m_uc, &hf_ipmi_se_XX_m_unc,
2686                 &hf_ipmi_se_XX_m_lnr, &hf_ipmi_se_XX_m_lc, &hf_ipmi_se_XX_m_lnc, NULL };
2687
2688         proto_tree_add_bitmask_text(tree, tvb, offs, 1, desc, "None",
2689                         ett_ipmi_se_XX_mask, threshold_mask, TRUE, 0);
2690         proto_tree_add_item(tree, hf_ipmi_se_XX_thr_lnc, tvb, offs + 1, 1, TRUE);
2691         proto_tree_add_item(tree, hf_ipmi_se_XX_thr_lc, tvb, offs + 2, 1, TRUE);
2692         proto_tree_add_item(tree, hf_ipmi_se_XX_thr_lnr, tvb, offs + 3, 1, TRUE);
2693         proto_tree_add_item(tree, hf_ipmi_se_XX_thr_unc, tvb, offs + 4, 1, TRUE);
2694         proto_tree_add_item(tree, hf_ipmi_se_XX_thr_uc, tvb, offs + 5, 1, TRUE);
2695         proto_tree_add_item(tree, hf_ipmi_se_XX_thr_unr, tvb, offs + 6, 1, TRUE);
2696 }
2697
2698 /* Set Sensor Thresholds.
2699  */
2700 static void
2701 rq26(tvbuff_t *tvb, proto_tree *tree)
2702 {
2703         proto_tree_add_item(tree, hf_ipmi_se_26_sensor, tvb, 0, 1, TRUE);
2704         add_thresholds(tvb, 1, tree, "Set thresholds: ");
2705 }
2706
2707 /* Get Sensor Thresholds.
2708  */
2709 static void
2710 rq27(tvbuff_t *tvb, proto_tree *tree)
2711 {
2712         proto_tree_add_item(tree, hf_ipmi_se_27_sensor, tvb, 0, 1, TRUE);
2713 }
2714
2715 static void
2716 rs27(tvbuff_t *tvb, proto_tree *tree)
2717 {
2718         add_thresholds(tvb, 0, tree, "Readable thresholds: ");
2719 }
2720
2721 /* Common for Get EE/Set EE/Rearm
2722  */
2723 static void
2724 add_events(tvbuff_t *tvb, int offs, proto_tree *tree, const struct true_false_string *tfs,
2725                 const char *desc)
2726 {
2727         static const int *bsel[4][8] = {
2728                 { &hf_ipmi_se_XX_b1_0, &hf_ipmi_se_XX_b1_1, &hf_ipmi_se_XX_b1_2, &hf_ipmi_se_XX_b1_3,
2729                         &hf_ipmi_se_XX_b1_4, &hf_ipmi_se_XX_b1_5, &hf_ipmi_se_XX_b1_6, &hf_ipmi_se_XX_b1_7 },
2730                 { &hf_ipmi_se_XX_b2_0, &hf_ipmi_se_XX_b2_1, &hf_ipmi_se_XX_b2_2, &hf_ipmi_se_XX_b2_3,
2731                         &hf_ipmi_se_XX_b2_4, &hf_ipmi_se_XX_b2_5, &hf_ipmi_se_XX_b2_6, NULL },
2732                 { &hf_ipmi_se_XX_b3_0, &hf_ipmi_se_XX_b3_1, &hf_ipmi_se_XX_b3_2, &hf_ipmi_se_XX_b3_3,
2733                         &hf_ipmi_se_XX_b3_4, &hf_ipmi_se_XX_b3_5, &hf_ipmi_se_XX_b3_6, &hf_ipmi_se_XX_b3_7 },
2734                 { &hf_ipmi_se_XX_b4_0, &hf_ipmi_se_XX_b4_1, &hf_ipmi_se_XX_b4_2, &hf_ipmi_se_XX_b4_3,
2735                         &hf_ipmi_se_XX_b4_4, &hf_ipmi_se_XX_b4_5, &hf_ipmi_se_XX_b4_6, NULL }
2736         };
2737         static const int *tsel[] = { &ett_ipmi_se_XX_b1, &ett_ipmi_se_XX_b2, &ett_ipmi_se_XX_b3, &ett_ipmi_se_XX_b4 };
2738         proto_item *ti;
2739         proto_tree *s_tree;
2740         int len = tvb_length(tvb);
2741         int i, j, val, msk;
2742
2743         for (i = 0; offs < len; i++, offs++) {
2744                 val = tvb_get_guint8(tvb, offs);
2745                 ti = proto_tree_add_text(tree, tvb, offs, 1, "%s (byte %d)", desc, i);
2746                 s_tree = proto_item_add_subtree(ti, *tsel[i]);
2747                 for (j = 7; j >= 0; j--) {
2748                         if (!bsel[i][j]) {
2749                                 continue;
2750                         }
2751                         msk = 1 << j;
2752                         proto_tree_add_boolean_format_value(s_tree, *bsel[i][j], tvb, offs, 1,
2753                                         val & msk, "%s", (val & msk) ? tfs->true_string : tfs->false_string);
2754                 }
2755         }
2756 }
2757
2758
2759 /* Set Sensor Event Enable.
2760  */
2761 static void
2762 rq28(tvbuff_t *tvb, proto_tree *tree)
2763 {
2764         static const int *byte2[] = { &hf_ipmi_se_28_fl_evm, &hf_ipmi_se_28_fl_scan, &hf_ipmi_se_28_fl_action, NULL };
2765         static const struct true_false_string tfs_lect = { "Select", "Do not select" };
2766
2767         proto_tree_add_item(tree, hf_ipmi_se_28_sensor, tvb, 0, 1, TRUE);
2768         proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_28_byte2, byte2, TRUE, 0);
2769         add_events(tvb, 2, tree, &tfs_lect, "Selected events");
2770 }
2771
2772 /* Get Sensor Event Enable.
2773  */
2774 static void
2775 rq29(tvbuff_t *tvb, proto_tree *tree)
2776 {
2777         proto_tree_add_item(tree, hf_ipmi_se_29_sensor, tvb, 0, 1, TRUE);
2778 }
2779
2780 static void
2781 rs29(tvbuff_t *tvb, proto_tree *tree)
2782 {
2783         static const int *byte1[] = { &hf_ipmi_se_29_fl_evm, &hf_ipmi_se_29_fl_scan, NULL };
2784
2785         proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_29_byte1, byte1, TRUE, 0);
2786         add_events(tvb, 1, tree, &tfs_29_enabled, "Enabled events");
2787 }
2788
2789 /* Re-arm Sensor Events.
2790  */
2791 static void
2792 rq2a(tvbuff_t *tvb, proto_tree *tree)
2793 {
2794         static const int *byte2[] = { &hf_ipmi_se_2a_fl_sel, NULL };
2795         static const struct true_false_string rearm_tfs = { "Re-arm", "Do not re-arm" };
2796
2797         proto_tree_add_item(tree, hf_ipmi_se_2a_sensor, tvb, 0, 1, TRUE);
2798         proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_2a_byte2, byte2, TRUE, 0);
2799         add_events(tvb, 2, tree, &rearm_tfs, "Re-arm Events");
2800 }
2801
2802 /* Get Sensor Event Status.
2803  */
2804 static void
2805 rq2b(tvbuff_t *tvb, proto_tree *tree)
2806 {
2807         proto_tree_add_item(tree, hf_ipmi_se_2b_sensor, tvb, 0, 1, TRUE);
2808 }
2809
2810 static void
2811 rs2b(tvbuff_t *tvb, proto_tree *tree)
2812 {
2813         static const int *byte1[] = { &hf_ipmi_se_2b_fl_evm, &hf_ipmi_se_2b_fl_scan, &hf_ipmi_se_2b_fl_unavail, NULL };
2814         static const struct true_false_string occur_tfs = { "Occurred", "Did not occur" };
2815
2816         proto_tree_add_bitmask_text(tree, tvb, 0, 1, NULL, NULL, ett_ipmi_se_2b_byte1, byte1, TRUE, 0);
2817         add_events(tvb, 1, tree, &occur_tfs, "Event Status");
2818 }
2819
2820 /* Get Sensor Reading.
2821  */
2822 static void
2823 rq2d(tvbuff_t *tvb, proto_tree *tree)
2824 {
2825         proto_tree_add_item(tree, hf_ipmi_se_2d_sensor, tvb, 0, 1, TRUE);
2826 }
2827
2828 static void
2829 rs2d(tvbuff_t *tvb, proto_tree *tree)
2830 {
2831         /* Reuse flags from Event Status message */
2832         static const int *byte2[] = { &hf_ipmi_se_2b_fl_evm, &hf_ipmi_se_2b_fl_scan, &hf_ipmi_se_2b_fl_unavail, NULL };
2833         static const int *bsel[2][8] = {
2834                 { &hf_ipmi_se_2d_b1_0, &hf_ipmi_se_2d_b1_1, &hf_ipmi_se_2d_b1_2, &hf_ipmi_se_2d_b1_3,
2835                         &hf_ipmi_se_2d_b1_4, &hf_ipmi_se_2d_b1_5, &hf_ipmi_se_2d_b1_6, &hf_ipmi_se_2d_b1_7 },
2836                 { &hf_ipmi_se_2d_b2_0, &hf_ipmi_se_2d_b2_1, &hf_ipmi_se_2d_b2_2, &hf_ipmi_se_2d_b2_3,
2837                         &hf_ipmi_se_2d_b2_4, &hf_ipmi_se_2d_b2_5, &hf_ipmi_se_2d_b2_6, NULL }
2838         };
2839         static const int *tsel[2] = { &ett_ipmi_se_2d_b1, &ett_ipmi_se_2d_b2 };
2840         proto_item *ti;
2841         proto_tree *s_tree;
2842         int i, j, len;
2843
2844         proto_tree_add_item(tree, hf_ipmi_se_2d_reading, tvb, 0, 1, TRUE);
2845         proto_tree_add_bitmask_text(tree, tvb, 1, 1, NULL, NULL, ett_ipmi_se_2d_byte2, byte2, TRUE, 0);
2846         len = tvb_length(tvb);
2847         for (i = 0; i < 2 && i < len - 2; i++) {
2848                 ti = proto_tree_add_text(tree, tvb, i + 2, 1, "Threshold comparisons/assertions (byte %d)", i);
2849                 s_tree = proto_item_add_subtree(ti, *tsel[i]);
2850                 for (j = 7; j >= 0; j--) {
2851                         if (bsel[i][j]) {
2852                                 proto_tree_add_item(s_tree, *bsel[i][j], tvb, i + 2, 1, TRUE);
2853                         }
2854                 }
2855         }
2856 }
2857
2858 /* Set Sensor Type.
2859  */
2860 static void
2861 rq2e(tvbuff_t *tvb, proto_tree *tree)
2862 {
2863         guint8 stype, evtype;
2864         const struct sensor_info *si;
2865         const struct evtype_info *eti;
2866         proto_item *ti;
2867         proto_tree *s_tree;
2868
2869         stype = tvb_get_guint8(tvb, 1);
2870         si = get_sensor_info(stype);
2871         evtype = tvb_get_guint8(tvb, 2) & 0x7f;
2872         eti = get_evtype_info(evtype);
2873
2874         proto_tree_add_item(tree, hf_ipmi_se_2e_sensor, tvb, 0, 1, TRUE);
2875         proto_tree_add_uint_format_value(tree, hf_ipmi_se_2e_stype, tvb, 1, 1,
2876                         stype, "%s (0x%02x)", si->desc, stype);
2877
2878         ti = proto_tree_add_text(tree, tvb, 2, 1, "Event/reading type: %s", eti->desc);
2879         s_tree = proto_item_add_subtree(ti, ett_ipmi_se_2e_evtype);
2880         proto_tree_add_uint_format_value(s_tree, hf_ipmi_se_2e_evtype, tvb, 2, 1,
2881                         evtype, "%s (0x%02x)", eti->desc, evtype);
2882 }
2883
2884 /* Get Sensor Type.
2885  */
2886 static void
2887 rq2f(tvbuff_t *tvb, proto_tree *tree)
2888 {
2889         proto_tree_add_item(tree, hf_ipmi_se_2f_sensor, tvb, 0, 1, TRUE);
2890 }
2891
2892 static void
2893 rs2f(tvbuff_t *tvb, proto_tree *tree)
2894 {
2895         guint8 stype, evtype;
2896         const struct sensor_info *si;
2897         const struct evtype_info *eti;
2898         proto_item *ti;
2899         proto_tree *s_tree;
2900
2901         stype = tvb_get_guint8(tvb, 0);
2902         si = get_sensor_info(stype);
2903         evtype = tvb_get_guint8(tvb, 1) & 0x7f;
2904         eti = get_evtype_info(evtype);
2905
2906         proto_tree_add_uint_format_value(tree, hf_ipmi_se_2f_stype, tvb, 0, 1,
2907                         stype, "%s (0x%02x)", si->desc, stype);
2908
2909         ti = proto_tree_add_text(tree, tvb, 2, 1, "Event/reading type: %s", eti->desc);
2910         s_tree = proto_item_add_subtree(ti, ett_ipmi_se_2f_evtype);
2911         proto_tree_add_uint_format_value(s_tree, hf_ipmi_se_2f_evtype, tvb, 1, 1,
2912                         evtype, "%s (0x%02x)", eti->desc, evtype);
2913 }
2914
2915 static const value_string cc30[] = {
2916         { 0x80, "Attempt to change not-settable reading/status bits" },
2917         { 0x81, "Setting Event Data Bytes not supported" },
2918         { 0, NULL }
2919 };
2920
2921 static ipmi_cmd_t cmd_se[] = {
2922   /* Event commands */
2923   { 0x00, rq00, NULL, NULL, NULL, "Set Event Receiver", 0 },
2924   { 0x01, NULL, rs01, NULL, NULL, "Get Event Receiver", 0 },
2925   { 0x02, rq02, NULL, NULL, NULL, "Platform Event", 0 },
2926
2927   /* PEF and Alerting Commands */
2928   { 0x10, NULL, rs10, NULL, NULL, "Get PEF Capabilities", 0 },
2929   { 0x11, rq11, rs11, NULL, NULL, "Arm PEF Postpone Timer", 0 },
2930   { 0x12, rq12, NULL, cc12, NULL, "Set PEF Configuration Parameters", 0 },
2931   { 0x13, rq13, rs13, cc13, NULL, "Get PEF Configuration Parameters", CMD_CALLRQ },
2932   { 0x14, rq14, NULL, cc14, NULL, "Set Last Processed Event ID", 0 },
2933   { 0x15, NULL, rs15, cc15, NULL, "Get Last Processed Event ID", 0 },
2934   { 0x16, rq16, rs16, cc16, NULL, "Alert Immediate", CMD_CALLRQ },
2935   { 0x17, rq17, NULL, NULL, NULL, "PET Acknowledge", 0 },
2936
2937   /* Sensor Device Commands */
2938   { 0x20, rq20, rs20, NULL, NULL, "Get Device SDR Info", CMD_CALLRQ },
2939   { 0x21, rq21, rs21, cc21, NULL, "Get Device SDR", 0 },
2940   { 0x22, NULL, rs22, NULL, NULL, "Reserve Device SDR Repository", 0 },
2941   { 0x23, rq23, rs23, NULL, NULL, "Get Sensor Reading Factors", 0 },
2942   { 0x24, rq24, NULL, NULL, NULL, "Set Sensor Hysteresis", 0 },
2943   { 0x25, rq25, rs25, NULL, NULL, "Get Sensor Hysteresis", 0 },
2944   { 0x26, rq26, NULL, NULL, NULL, "Set Sensor Threshold", 0 },
2945   { 0x27, rq27, rs27, NULL, NULL, "Get Sensor Threshold", 0 },
2946   { 0x28, rq28, NULL, NULL, NULL, "Set Sensor Event Enable", 0 },
2947   { 0x29, rq29, rs29, NULL, NULL, "Get Sensor Event Enable", 0 },
2948   { 0x2a, rq2a, NULL, NULL, NULL, "Re-arm Sensor Events", 0 },
2949   { 0x2b, rq2b, rs2b, NULL, NULL, "Get Sensor Event Status", 0 },
2950   { 0x2d, rq2d, rs2d, NULL, NULL, "Get Sensor Reading", 0 },
2951   { 0x2e, rq2e, NULL, NULL, NULL, "Set Sensor Type", 0 },
2952   { 0x2f, rq2f, rs2f, NULL, NULL, "Get Sensor Type", 0 },
2953   { 0x30, IPMI_TBD,   cc30, NULL, "Set Sensor Reading and Event Status", 0 },
2954 };
2955
2956 void
2957 ipmi_register_se(gint proto_ipmi)
2958 {
2959         static hf_register_info hf[] = {
2960                 { &hf_ipmi_se_evt_rev,
2961                         { "Event Message Revision",
2962                                 "ipmi.evt.evmrev", FT_UINT8, BASE_HEX, evt_evm_rev_vals, 0, "", HFILL }},
2963                 { &hf_ipmi_se_evt_sensor_type,
2964                         { "Sensor Type",
2965                                 "ipmi.evt.sensor_type", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }},
2966                 { &hf_ipmi_se_evt_sensor_num,
2967                         { "Sensor #",
2968                                 "ipmi.evt.sensor_num", FT_UINT8, BASE_DEC, NULL, 0, "", HFILL }},
2969                 { &hf_ipmi_se_evt_byte3,
2970                         { "Event Dir/Type",
2971                                 "ipmi.evt.byte3", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }},
2972                 { &hf_ipmi_se_evt_dir,
2973                         { "Event Direction",
2974                                 "ipmi.evt.evdir", FT_BOOLEAN, 8, TFS(&evt_evdir_tfs), 0x80, "", HFILL }},
2975                 { &hf_ipmi_se_evt_type,
2976                         { "Event Type",
2977                                 "ipmi.evt.evtype", FT_UINT8, BASE_HEX, NULL, 0x7f, "", HFILL }},
2978                 { &hf_ipmi_se_evt_data1,
2979                         { "Event Data 1",
2980                                 "ipmi.evt.data1", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }},
2981                 { &hf_ipmi_se_evt_data1_b2,
2982                         { "Byte 2",
2983                                 "ipmi.evt.data1.b2", FT_UINT8, BASE_HEX, NULL, 0xc0, "", HFILL }},
2984                 { &hf_ipmi_se_evt_data1_b3,
2985                         { "Byte 3",
2986                                 "ipmi.evt.data1.b3", FT_UINT8, BASE_HEX, NULL, 0x30, "", HFILL }},
2987                 { &hf_ipmi_se_evt_data1_offs,
2988                         { "Offset",
2989                                 "ipmi.evt.data1.offs", FT_UINT8, BASE_HEX, NULL, 0x0f, "", HFILL }},
2990                 { &hf_ipmi_se_evt_data2,
2991                         { "Event Data 2",
2992                                 "ipmi.evt.data2", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }},
2993                 { &hf_ipmi_se_evt_data3,
2994                         { "Event Data 3",
2995                                 "ipmi.evt.data3", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }},
2996
2997                 { &hf_ipmi_se_cp00_sip,
2998                         { "Set In Progress",
2999                                 "ipmi.cp00.sip", FT_UINT8, BASE_HEX, cp00_sip_vals, 0x03, "", HFILL }},
3000                 { &hf_ipmi_se_cp01_alert_startup,
3001                         { "PEF Alert Startup Delay disable",
3002                                 "ipmi.cp01.alert_startup", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }},
3003                 { &hf_ipmi_se_cp01_startup,
3004                         { "PEF Startup Delay disable",
3005                                 "ipmi.cp01.startup", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }},
3006                 { &hf_ipmi_se_cp01_event_msg,
3007                         { "Enable Event Messages for PEF actions",
3008                                 "ipmi.cp01.event_msg", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }},
3009                 { &hf_ipmi_se_cp01_pef,
3010                         { "Enable PEF",
3011                                 "ipmi.cp01.pef", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }},
3012                 { &hf_ipmi_se_cp02_diag_intr,
3013                         { "Enable Diagnostic Interrupt",
3014                                 "ipmi.cp02.diag_intr", FT_BOOLEAN, 8, NULL, 0x20, "", HFILL }},
3015                 { &hf_ipmi_se_cp02_oem_action,
3016                         { "Enable OEM action",
3017                                 "ipmi.cp02.oem_action", FT_BOOLEAN, 8, NULL, 0x10, "", HFILL }},
3018                 { &hf_ipmi_se_cp02_pwr_cycle,
3019                         { "Enable Power Cycle action",
3020                                 "ipmi.cp02.pwr_cycle", FT_BOOLEAN, 8, NULL, 0x08, "", HFILL }},
3021                 { &hf_ipmi_se_cp02_reset,
3022                         { "Enable Reset action",
3023                                 "ipmi.cp02.reset", FT_BOOLEAN, 8, NULL, 0x04, "", HFILL }},
3024                 { &hf_ipmi_se_cp02_pwr_down,
3025                         { "Enable Power Down action",
3026                                 "ipmi.cp02.pwr_down", FT_BOOLEAN, 8, NULL, 0x02, "", HFILL }},
3027                 { &hf_ipmi_se_cp02_alert,
3028                         { "Enable Alert action",
3029                                 "ipmi.cp02.alert", FT_BOOLEAN, 8, NULL, 0x01, "", HFILL }},
3030                 { &hf_ipmi_se_cp03_startup,
3031                         { "PEF Startup delay",
3032                                 "ipmi.cp03.startup", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_1based, 0, "", HFILL }},
3033                 { &hf_ipmi_se_cp04_alert_startup,
3034                         { "PEF Alert Startup delay",
3035                                 "ipmi.cp04.alert_startup", FT_UINT8, BASE_CUSTOM, ipmi_fmt_1s_1based, 0, "", HFILL }},
3036                 { &hf_ipmi_se_cp05_num_evfilters,
3037                         { "Number of Event Filters",
3038                                 "ipmi.cp05.num_evfilters", FT_UINT8, BASE_DEC, NULL, 0x7f, "", HFILL }},
3039                 { &hf_ipmi_se_cp06_filter,
3040                         { "Filter number (set selector)",
3041                                 "ipmi.cp06.filter", FT_UINT8, BASE_DEC, NULL, 0x7f, "", HFILL }},
3042                 { &hf_ipmi_se_cp06_data,
3043                         { "Filter data",
3044                                 "ipmi.cp06.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }},
3045                 { &hf_ipmi_se_cp07_filter,
3046                         { "Filter number (set selector)",
3047                                 "ipmi.cp07.filter", FT_UINT8, BASE_DEC, NULL, 0x7f, "", HFILL }},
3048                 { &hf_ipmi_se_cp07_data,
3049                         { "Filter data (byte 1)",
3050                                 "ipmi.cp07.data", FT_UINT8, BASE_HEX, NULL, 0, "", HFILL }},
3051                 { &hf_ipmi_se_cp08_policies,
3052                         { "Number of Alert Policy Entries",
3053                                 "ipmi.cp08.policies", FT_UINT8, BASE_DEC, NULL, 0x7f, "", HFILL }},
3054                 { &hf_ipmi_se_cp09_entry,
3055                         { "Entry number (set selector)",
3056                                 "ipmi.cp09.entry", FT_UINT8, BASE_DEC, NULL, 0x7f, "", HFILL }},
3057                 { &hf_ipmi_se_cp09_data,
3058                         { "Entry data",
3059                                 "ipmi.cp09.data", FT_BYTES, BASE_HEX, NULL, 0, "", HFILL }},
3060                 { &hf_ipmi_se_cp10_useval,
3061                         { "Used to fill the GUID field in PET Trap",
3062                                 "ipmi.cp10.useval", FT_BOOLEAN, 8, TFS(&cp10_use_tfs), 0x01, "", HFILL }},
3063                 { &hf_ipmi_se_cp10_guid,
3064                         { "GUID",
3065                                 "ipmi.cp10.guid", FT_GUID, BASE_HEX, NULL, 0, "", HFILL }},
3066                 { &hf_ipmi_se_cp11_num_alertstr,
3067                         { "Number of Alert Strings",
3068                                 "ipmi.cp11.num_alertstr", FT_UINT8, BASE_DEC, NULL, 0x7f, "", HFILL }},
3069